Update.
[glibc.git] / elf / dynamic-link.h
blob1d134ddf2fc6cb18236baa8a1e641443c0d9e798
1 /* Inline functions for dynamic linking.
2 Copyright (C) 1995, 1996, 1997 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 not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, 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 __attribute__ ((unused))
28 elf_get_dynamic_info (ElfW(Dyn) *dyn,
29 ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM
30 + DT_EXTRANUM])
32 unsigned int i;
34 for (i = 0; i < DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM; ++i)
35 info[i] = NULL;
37 if (! dyn)
38 return;
40 while (dyn->d_tag != DT_NULL)
42 if (dyn->d_tag < DT_NUM)
43 info[dyn->d_tag] = dyn;
44 else if (dyn->d_tag >= DT_LOPROC &&
45 dyn->d_tag < DT_LOPROC + DT_PROCNUM)
46 info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
47 else if ((Elf32_Word) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
48 info[DT_VERSIONTAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM] = dyn;
49 else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
50 info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM
51 + DT_VERSIONTAGNUM] = dyn;
52 else
53 assert (! "bad dynamic tag");
54 dyn++;
57 if (info[DT_RELA])
58 assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
59 if (info[DT_REL])
60 assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
61 if (info[DT_PLTREL])
62 assert (info[DT_PLTREL]->d_un.d_val == DT_REL ||
63 info[DT_PLTREL]->d_un.d_val == DT_RELA);
66 #ifdef RESOLVE
68 /* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.
69 These functions are almost identical, so we use cpp magic to avoid
70 duplicating their code. It cannot be done in a more general function
71 because we must be able to completely inline. */
73 #if ! ELF_MACHINE_NO_REL
74 #include "do-rel.h"
75 #define ELF_DYNAMIC_DO_REL(map, lazy) \
76 if ((map)->l_info[DT_REL]) \
77 elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, 0); \
78 if ((map)->l_info[DT_PLTREL] && \
79 (map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL) \
80 elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (lazy));
81 #else
82 #define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do. */
83 #endif
85 #if ! ELF_MACHINE_NO_RELA
86 #define DO_RELA
87 #include "do-rel.h"
88 #define ELF_DYNAMIC_DO_RELA(map, lazy) \
89 if ((map)->l_info[DT_RELA]) \
90 elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, 0); \
91 if ((map)->l_info[DT_PLTREL] && \
92 (map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA) \
93 elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (lazy));
94 #else
95 #define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do. */
96 #endif
98 /* This can't just be an inline function because GCC is too dumb
99 to inline functions containing inlines themselves. */
100 #define ELF_DYNAMIC_RELOCATE(map, lazy) \
101 do { ELF_DYNAMIC_DO_REL ((map), (lazy)); \
102 ELF_DYNAMIC_DO_RELA ((map), (lazy)); } while (0)
104 #endif