]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/do-rel.h
malloc: set NON_MAIN_ARENA flag for reclaimed memalign chunk (BZ #30101)
[thirdparty/glibc.git] / elf / do-rel.h
CommitLineData
421f82e5 1/* Do relocations for ELF dynamic linking.
6d7e8eda 2 Copyright (C) 1995-2023 Free Software Foundation, Inc.
afd4eb37 3 This file is part of the GNU C Library.
421f82e5 4
afd4eb37 5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
421f82e5 9
afd4eb37
UD
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
41bdb6e2 13 Lesser General Public License for more details.
421f82e5 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
421f82e5 18
32612615
AZ
19#include <ldsodefs.h>
20
421f82e5
RM
21/* This file may be included twice, to define both
22 `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */
23
24#ifdef DO_RELA
e453f6cd 25# define elf_dynamic_do_Rel elf_dynamic_do_Rela
1f2a1df3
UD
26# define Rel Rela
27# define elf_machine_rel elf_machine_rela
28# define elf_machine_rel_relative elf_machine_rela_relative
421f82e5
RM
29#endif
30
0e312a82
UD
31#ifndef DO_ELF_MACHINE_REL_RELATIVE
32# define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \
33 elf_machine_rel_relative (l_addr, relative, \
34 (void *) (l_addr + relative->r_offset))
35#endif
36
421f82e5 37/* Perform the relocations in MAP on the running program image as specified
f51d1dfd
RM
38 by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT
39 relocations; they should be set up to call _dl_runtime_resolve, rather
40 than fully resolved now. */
421f82e5 41
490e6c62
FS
42static inline void __attribute__ ((always_inline))
43elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
ca34d7a7 44 ElfW(Addr) reladdr, ElfW(Addr) relsize,
aac13307
UD
45 __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
46 int lazy, int skip_ifunc)
421f82e5 47{
84e02af1
FS
48 const ElfW(Rel) *relative = (const void *) reladdr;
49 const ElfW(Rel) *r = relative + nrelative;
f420344c 50 const ElfW(Rel) *end = (const void *) (reladdr + relsize);
c65c9d8b 51 ElfW(Addr) l_addr = map->l_addr;
84e02af1
FS
52 const ElfW(Sym) *const symtab
53 = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
54
55#ifdef RTLD_BOOTSTRAP
56 for (; relative < r; ++relative)
57 DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative);
58
59 const ElfW (Half) *const version
60 = (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
61 for (; r < end; ++r)
62 {
63 ElfW (Half) ndx = version[ELFW (R_SYM) (r->r_info)] & 0x7fff;
64 const ElfW (Sym) *sym = &symtab[ELFW (R_SYM) (r->r_info)];
65 void *const r_addr_arg = (void *) (l_addr + r->r_offset);
66 const struct r_found_version *rversion = &map->l_versions[ndx];
67
68 elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, skip_ifunc);
69 }
70#else /* !RTLD_BOOTSTRAP */
71# if defined ELF_MACHINE_IRELATIVE
ad0f5cad
UD
72 const ElfW(Rel) *r2 = NULL;
73 const ElfW(Rel) *end2 = NULL;
74# endif
421f82e5 75
84e02af1 76#if !defined DO_RELA || !defined ELF_MACHINE_PLT_REL
43a80540
UD
77 /* We never bind lazily during ld.so bootstrap. Unfortunately gcc is
78 not clever enough to see through all the function calls to realize
79 that. */
a1a9d215 80 if (lazy)
b0cf070b
UD
81 {
82 /* Doing lazy PLT relocations; they need very little info. */
b0cf070b 83 for (; r < end; ++r)
ad0f5cad
UD
84# ifdef ELF_MACHINE_IRELATIVE
85 if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
86 {
87 if (r2 == NULL)
88 r2 = r;
89 end2 = r;
90 }
91 else
92# endif
490e6c62 93 elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc);
ad0f5cad
UD
94
95# ifdef ELF_MACHINE_IRELATIVE
96 if (r2 != NULL)
97 for (; r2 <= end2; ++r2)
98 if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
490e6c62 99 elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc);
ad0f5cad 100# endif
b0cf070b 101 }
a1a9d215 102 else
43a80540 103#endif
c84142e8 104 {
ad427d6e
UD
105 /* This is defined in rtld.c, but nowhere in the static libc.a; make
106 the reference weak so static programs can still link. This
107 declaration cannot be done when compiling rtld.c (i.e. #ifdef
108 RTLD_BOOTSTRAP) because rtld.c contains the common defn for
109 _dl_rtld_map, which is incompatible with a weak decl in the same
110 file. */
d6b5d570
UD
111# ifndef SHARED
112 weak_extern (GL(dl_rtld_map));
113# endif
114 if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
6736e93b 115# if !defined DO_RELA || defined ELF_MACHINE_REL_RELATIVE
95c78350
UD
116 /* Rela platforms get the offset from r_addend and this must
117 be copied in the relocation address. Therefore we can skip
118 the relative relocations only if this is for rel
6736e93b
UD
119 relocations or rela relocations if they are computed as
120 memory_loc += l_addr... */
95c78350
UD
121 if (l_addr != 0)
122# endif
95c78350 123 for (; relative < r; ++relative)
0e312a82 124 DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative);
c84142e8 125
d705269e 126 if (map->l_info[VERSYMIDX (DT_VERSYM)])
c84142e8
UD
127 {
128 const ElfW(Half) *const version =
a42195db 129 (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
c84142e8
UD
130
131 for (; r < end; ++r)
132 {
32612615
AZ
133 ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
134 const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
135 void *const r_addr_arg = (void *) (l_addr + r->r_offset);
136 const struct r_found_version *rversion = &map->l_versions[ndx];
84e02af1 137#if defined ELF_MACHINE_IRELATIVE
ad0f5cad
UD
138 if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
139 {
140 if (r2 == NULL)
141 r2 = r;
142 end2 = r;
143 continue;
144 }
145#endif
146
32612615
AZ
147 elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg,
148 skip_ifunc);
84e02af1 149#if defined SHARED
32612615
AZ
150 if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
151 && GLRO(dl_naudit) > 0)
152 {
153 struct link_map *sym_map
154 = RESOLVE_MAP (map, scope, &sym, rversion,
155 ELF_MACHINE_JMP_SLOT);
156 if (sym != NULL)
157 _dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map);
158 }
159#endif
c84142e8 160 }
ad0f5cad 161
84e02af1 162#if defined ELF_MACHINE_IRELATIVE
ad0f5cad
UD
163 if (r2 != NULL)
164 for (; r2 <= end2; ++r2)
165 if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
166 {
167 ElfW(Half) ndx
168 = version[ELFW(R_SYM) (r2->r_info)] & 0x7fff;
490e6c62 169 elf_machine_rel (map, scope, r2,
ad0f5cad
UD
170 &symtab[ELFW(R_SYM) (r2->r_info)],
171 &map->l_versions[ndx],
172 (void *) (l_addr + r2->r_offset),
173 skip_ifunc);
174 }
175#endif
c84142e8
UD
176 }
177 else
ad0f5cad
UD
178 {
179 for (; r < end; ++r)
32612615
AZ
180 {
181 const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
182 void *const r_addr_arg = (void *) (l_addr + r->r_offset);
ad0f5cad 183# ifdef ELF_MACHINE_IRELATIVE
32612615
AZ
184 if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
185 {
186 if (r2 == NULL)
187 r2 = r;
188 end2 = r;
189 continue;
190 }
ad0f5cad 191# endif
32612615
AZ
192 elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg,
193 skip_ifunc);
84e02af1 194# if defined SHARED
32612615
AZ
195 if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
196 && GLRO(dl_naudit) > 0)
197 {
198 struct link_map *sym_map
199 = RESOLVE_MAP (map, scope, &sym,
200 (struct r_found_version *) NULL,
201 ELF_MACHINE_JMP_SLOT);
202 if (sym != NULL)
203 _dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map);
204 }
205# endif
206 }
ad0f5cad
UD
207
208# ifdef ELF_MACHINE_IRELATIVE
209 if (r2 != NULL)
210 for (; r2 <= end2; ++r2)
211 if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
490e6c62 212 elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
ad0f5cad
UD
213 NULL, (void *) (l_addr + r2->r_offset),
214 skip_ifunc);
215# endif
216 }
c84142e8 217 }
84e02af1 218#endif /* !RTLD_BOOTSTRAP */
421f82e5
RM
219}
220
e453f6cd 221#undef elf_dynamic_do_Rel
266180eb 222#undef Rel
421f82e5 223#undef elf_machine_rel
1f2a1df3 224#undef elf_machine_rel_relative
0e312a82 225#undef DO_ELF_MACHINE_REL_RELATIVE
e453f6cd 226#undef DO_RELA