(rtld_map): New static variable.
[kopensolaris-gnu/glibc.git] / elf / dynamic-link.h
1 /* Inline functions for dynamic linking.
2 Copyright (C) 1995 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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.  */
19
20 #include <elf.h>
21 #include <dl-machine.h>
22 #include <assert.h>
23
24
25 /* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */
26
27 static inline void
28 elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
29 {
30   unsigned int i;
31
32   for (i = 0; i < DT_NUM; ++i)
33     info[i] = NULL;
34
35   if (! dyn)
36     return;
37
38   while (dyn->d_tag != DT_NULL)
39     {
40       assert (dyn->d_tag < DT_NUM);
41       info[dyn->d_tag] = dyn++;
42     }
43
44   if (info[DT_RELA])
45     assert (info[DT_RELAENT]->d_un.d_val == sizeof (Elf32_Rela));
46   if (info[DT_REL])
47     assert (info[DT_RELENT]->d_un.d_val == sizeof (Elf32_Rel));
48   if (info[DT_PLTREL])
49     assert (info[DT_PLTREL]->d_un.d_val == DT_REL ||
50             info[DT_PLTREL]->d_un.d_val == DT_RELA);
51 }
52
53 /* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.
54    These functions are almost identical, so we use cpp magic to avoid
55    duplicating their code.  It cannot be done in a more general function
56    because we must be able to completely inline.  */
57
58 #if ! ELF_MACHINE_NO_REL
59 #include "do-rel.h"
60 #define ELF_DYNAMIC_DO_REL(map, lazy, resolve)                                \
61   if ((map)->l_info[DT_REL])                                                  \
62     elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, (resolve), 0);               \
63   if ((map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL)                         \
64     elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (resolve), (lazy));
65 #else
66 #define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do.  */
67 #endif
68
69 #if ! ELF_MACHINE_NO_RELA
70 #define DO_RELA
71 #include "do-rel.h"
72 #define ELF_DYNAMIC_DO_RELA(map, lazy, resolve)                               \
73   if ((map)->l_info[DT_RELA])                                                 \
74     elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, (resolve), 0);            \
75   if ((map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA)                        \
76     elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (resolve), (lazy));
77 #else
78 #define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do.  */
79 #endif
80
81 /* This can't just be an inline function because GCC is too dumb
82    to inline functions containing inlines themselves.  */
83 #define ELF_DYNAMIC_RELOCATE(map, lazy, resolve) \
84   do { ELF_DYNAMIC_DO_REL ((map), (lazy), (resolve)); \
85        ELF_DYNAMIC_DO_RELA ((map), (lazy), (resolve)); } while (0)