]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dynamic-link.h
* sysdeps/mach/i386/sysdep.h (SNARF_ARGS, CALL_WITH_SP): Rewritten.
[thirdparty/glibc.git] / elf / dynamic-link.h
CommitLineData
d66e34cd
RM
1/* Inline functions for dynamic linking.
2Copyright (C) 1995 Free Software Foundation, Inc.
3This file is part of the GNU C Library.
4
5The GNU C Library is free software; you can redistribute it and/or
6modify it under the terms of the GNU Library General Public License as
7published by the Free Software Foundation; either version 2 of the
8License, or (at your option) any later version.
9
10The GNU C Library is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13Library General Public License for more details.
14
15You should have received a copy of the GNU Library General Public
16License along with the GNU C Library; see the file COPYING.LIB. If
17not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18Cambridge, MA 02139, USA. */
19
20#include <elf.h>
21
22/* This machine-dependent file defines these inline functions. */
23
24static void elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
25 const Elf32_Rel *reloc,
26 Elf32_Addr sym_loadaddr, const Elf32_Sym *sym);
27static void elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
28 const Elf32_Rela *reloc,
29 Elf32_Addr sym_loadaddr, const Elf32_Sym *sym);
30static Elf32_Addr *elf_machine_got (void);
31static Elf32_Addr elf_machine_load_address (void);
32
33#include <dl-machine.h>
34
35
36#include <assert.h>
37
38/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
39
40static inline void
41elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
42{
43 unsigned int i;
44
45 for (i = 0; i < DT_NUM; ++i)
46 info[i] = NULL;
47
48 while (dyn->d_tag != DT_NULL)
49 {
50 assert (dyn->d_tag < DT_NUM);
51 info[dyn->d_tag] = dyn++;
52 }
53
54 if (info[DT_RELA])
55 assert (info[DT_RELAENT]->d_un.d_val == sizeof (Elf32_Rela));
56 if (info[DT_REL])
57 assert (info[DT_RELENT]->d_un.d_val == sizeof (Elf32_Rel));
58 if (info[DT_PLTREL])
59 assert (info[DT_PLTREL]->d_un.d_val == DT_REL ||
60 info[DT_PLTREL]->d_un.d_val == DT_RELA);
61}
62
63/* Perform the relocations specified by DYNAMIC on the running program
64 image. If LAZY is nonzero, don't relocate PLT entries. *RESOLVE is
65 called to resolve symbol values; it modifies its argument pointer to
66 point to the defining symbol, and returns the base load address of the
67 defining object. */
68
69static inline void
70elf_dynamic_relocate (Elf32_Dyn *dynamic[DT_NUM], Elf32_Addr loadaddr,
71 int lazy, Elf32_Addr (*resolve) (const Elf32_Sym **))
72{
73 const Elf32_Sym *const symtab
74 = (const Elf32_Sym *) dynamic[DT_SYMTAB]->d_un.d_ptr;
75
76 inline Elf32_Addr symvalue (Elf32_Word info, const Elf32_Sym **definer)
77 {
78 if (ELF32_R_SYM (info) == STN_UNDEF)
79 return 0; /* This value will not be consulted. */
80 *definer = &symtab[ELF32_R_SYM (info)];
81 return (*resolve) (definer);
82 }
83
84 /* Perform Elf32_Rel relocations in the section found by RELTAG, SZTAG. */
85 inline void do_rel (Elf32_Word reltag, Elf32_Word sztag)
86 {
87 const Elf32_Rel *r = (const Elf32_Rel *) dynamic[reltag]->d_un.d_ptr;
88 const Elf32_Rel *end = &r[dynamic[sztag]->d_un.d_val / sizeof *r];
89 while (r < end)
90 {
91 const Elf32_Sym *definer;
92 Elf32_Addr loadbase = symvalue (r->r_info, &definer);
93 elf_machine_rel (loadaddr, dynamic, r, loadbase, definer);
94 ++r;
95 }
96 }
97 /* Perform Elf32_Rela relocations in the section found by RELTAG, SZTAG. */
98 inline void do_rela (Elf32_Word reltag, Elf32_Word sztag)
99 {
100 const Elf32_Rela *r = (const Elf32_Rela *) dynamic[reltag]->d_un.d_ptr;
101 const Elf32_Rela *end = &r[dynamic[sztag]->d_un.d_val / sizeof *r];
102 while (r < end)
103 {
104 const Elf32_Sym *definer;
105 Elf32_Addr loadbase = symvalue (r->r_info, &definer);
106 elf_machine_rela (loadaddr, dynamic, r, loadbase, definer);
107 ++r;
108 }
109 }
110
111 if (dynamic[DT_RELA])
112 do_rela (DT_RELA, DT_RELASZ);
113 if (dynamic[DT_REL])
114 do_rel (DT_REL, DT_RELSZ);
115 if (dynamic[DT_JMPREL] && ! lazy)
116 /* Relocate the PLT right now. */
117 (dynamic[DT_PLTREL]->d_un.d_val == DT_REL ? do_rel : do_rela)
118 (DT_JMPREL, DT_PLTRELSZ);
119}