.
[glibc.git] / elf / dynamic-link.h
blob0c4e99d2b69ab5798c7dffed64cbdcd8e913d7ce
1 /* Inline functions for dynamic linking.
2 Copyright (C) 1995 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA. */
20 #include <elf.h>
21 #include <dl-machine.h>
22 #include <assert.h>
25 /* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
27 static inline void
28 elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM + DT_PROCNUM])
30 unsigned int i;
32 for (i = 0; i < DT_NUM + DT_PROCNUM; ++i)
33 info[i] = NULL;
35 if (! dyn)
36 return;
38 while (dyn->d_tag != DT_NULL)
40 if (dyn->d_tag < DT_NUM)
41 info[dyn->d_tag] = dyn;
42 else if (dyn->d_tag >= DT_LOPROC &&
43 dyn->d_tag < DT_LOPROC + DT_PROCNUM)
44 info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
45 else
46 assert (! "bad dynamic tag");
47 dyn++;
50 if (info[DT_RELA])
51 assert (info[DT_RELAENT]->d_un.d_val == sizeof (Elf32_Rela));
52 if (info[DT_REL])
53 assert (info[DT_RELENT]->d_un.d_val == sizeof (Elf32_Rel));
54 if (info[DT_PLTREL])
55 assert (info[DT_PLTREL]->d_un.d_val == DT_REL ||
56 info[DT_PLTREL]->d_un.d_val == DT_RELA);
59 /* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.
60 These functions are almost identical, so we use cpp magic to avoid
61 duplicating their code. It cannot be done in a more general function
62 because we must be able to completely inline. */
64 #if ! ELF_MACHINE_NO_REL
65 #include "do-rel.h"
66 #define ELF_DYNAMIC_DO_REL(map, lazy, resolve) \
67 if ((map)->l_info[DT_REL]) \
68 elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, (resolve), 0); \
69 if ((map)->l_info[DT_PLTREL] && \
70 (map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL) \
71 elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (resolve), (lazy));
72 #else
73 #define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do. */
74 #endif
76 #if ! ELF_MACHINE_NO_RELA
77 #define DO_RELA
78 #include "do-rel.h"
79 #define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) \
80 if ((map)->l_info[DT_RELA]) \
81 elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, (resolve), 0); \
82 if ((map)->l_info[DT_PLTREL] && \
83 (map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA) \
84 elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (resolve), (lazy));
85 #else
86 #define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do. */
87 #endif
89 /* This can't just be an inline function because GCC is too dumb
90 to inline functions containing inlines themselves. */
91 #define ELF_DYNAMIC_RELOCATE(map, lazy, resolve) \
92 do { ELF_DYNAMIC_DO_REL ((map), (lazy), (resolve)); \
93 ELF_DYNAMIC_DO_RELA ((map), (lazy), (resolve)); } while (0)