Deleted Added
full compact
reloc.c (208256) reloc.c (216695)
1/* $NetBSD: mdreloc.c,v 1.23 2003/07/26 15:04:38 mrg Exp $ */
2
3#include <sys/cdefs.h>
1/* $NetBSD: mdreloc.c,v 1.23 2003/07/26 15:04:38 mrg Exp $ */
2
3#include <sys/cdefs.h>
4__FBSDID("$FreeBSD: head/libexec/rtld-elf/arm/reloc.c 208256 2010-05-18 08:55:23Z rdivacky $");
4__FBSDID("$FreeBSD: head/libexec/rtld-elf/arm/reloc.c 216695 2010-12-25 08:51:20Z kib $");
5#include <sys/param.h>
6#include <sys/mman.h>
7
8#include <errno.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>

--- 18 unchanged lines hidden (view full) ---

31 assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */
32
33 rellim = (const Elf_Rel *) ((caddr_t) dstobj->rel + dstobj->relsize);
34 for (rel = dstobj->rel; rel < rellim; rel++) {
35 if (ELF_R_TYPE(rel->r_info) == R_ARM_COPY) {
36 void *dstaddr;
37 const Elf_Sym *dstsym;
38 const char *name;
5#include <sys/param.h>
6#include <sys/mman.h>
7
8#include <errno.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>

--- 18 unchanged lines hidden (view full) ---

31 assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */
32
33 rellim = (const Elf_Rel *) ((caddr_t) dstobj->rel + dstobj->relsize);
34 for (rel = dstobj->rel; rel < rellim; rel++) {
35 if (ELF_R_TYPE(rel->r_info) == R_ARM_COPY) {
36 void *dstaddr;
37 const Elf_Sym *dstsym;
38 const char *name;
39 unsigned long hash;
40 size_t size;
41 const void *srcaddr;
42 const Elf_Sym *srcsym;
39 size_t size;
40 const void *srcaddr;
41 const Elf_Sym *srcsym;
43 Obj_Entry *srcobj;
44 const Ver_Entry *ve;
42 const Obj_Entry *srcobj, *defobj;
43 SymLook req;
44 int res;
45
46 dstaddr = (void *) (dstobj->relocbase + rel->r_offset);
47 dstsym = dstobj->symtab + ELF_R_SYM(rel->r_info);
48 name = dstobj->strtab + dstsym->st_name;
45
46 dstaddr = (void *) (dstobj->relocbase + rel->r_offset);
47 dstsym = dstobj->symtab + ELF_R_SYM(rel->r_info);
48 name = dstobj->strtab + dstsym->st_name;
49 hash = elf_hash(name);
50 size = dstsym->st_size;
49 size = dstsym->st_size;
51 ve = fetch_ventry(dstobj, ELF_R_SYM(rel->r_info));
52
53 for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next)
54 if ((srcsym = symlook_obj(name, hash, srcobj, ve, 0)) != NULL)
50
51 symlook_init(&req, name);
52 req.ventry = fetch_ventry(dstobj,
53 ELF_R_SYM(rel->r_info));
54 for (srcobj = dstobj->next; srcobj != NULL;
55 srcobj = srcobj->next) {
56 res = symlook_obj(&req, srcobj);
57 if (res == 0) {
58 srcsym = req.sym_out;
59 defobj = req.defobj_out;
55 break;
60 break;
56
61 }
62 }
57 if (srcobj == NULL) {
63 if (srcobj == NULL) {
58 _rtld_error("Undefined symbol \"%s\" referenced from COPY"
59 " relocation in %s", name, dstobj->path);
60 return -1;
64 _rtld_error(
65"Undefined symbol \"%s\" referenced from COPY relocation in %s",
66 name, dstobj->path);
67 return (-1);
61 }
62
68 }
69
63 srcaddr = (const void *) (srcobj->relocbase + srcsym->st_value);
70 srcaddr = (const void *)(defobj->relocbase +
71 srcsym->st_value);
64 memcpy(dstaddr, srcaddr, size);
65 }
66 }
67 return 0;
68}
69
70void _rtld_bind_start(void);
71void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);

--- 46 unchanged lines hidden (view full) ---

118static __inline void
119store_ptr(void *where, Elf_Addr val)
120{
121
122 memcpy(where, &val, sizeof(val));
123}
124
125static int
72 memcpy(dstaddr, srcaddr, size);
73 }
74 }
75 return 0;
76}
77
78void _rtld_bind_start(void);
79void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);

--- 46 unchanged lines hidden (view full) ---

126static __inline void
127store_ptr(void *where, Elf_Addr val)
128{
129
130 memcpy(where, &val, sizeof(val));
131}
132
133static int
126reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache)
134reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
135 RtldLockState *lockstate)
127{
128 Elf_Addr *where;
129 const Elf_Sym *def;
130 const Obj_Entry *defobj;
131 Elf_Addr tmp;
132 unsigned long symnum;
133
134 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);

--- 9 unchanged lines hidden (view full) ---

144
145 /*
146 * Extract addend and sign-extend if needed.
147 */
148 addend = *where;
149 if (addend & 0x00800000)
150 addend |= 0xff000000;
151
136{
137 Elf_Addr *where;
138 const Elf_Sym *def;
139 const Obj_Entry *defobj;
140 Elf_Addr tmp;
141 unsigned long symnum;
142
143 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);

--- 9 unchanged lines hidden (view full) ---

153
154 /*
155 * Extract addend and sign-extend if needed.
156 */
157 addend = *where;
158 if (addend & 0x00800000)
159 addend |= 0xff000000;
160
152 def = find_symdef(symnum, obj, &defobj, false, cache);
161 def = find_symdef(symnum, obj, &defobj, false, cache,
162 lockstate);
153 if (def == NULL)
154 return -1;
155 tmp = (Elf_Addr)obj->relocbase + def->st_value
156 - (Elf_Addr)where + (addend << 2);
157 if ((tmp & 0xfe000000) != 0xfe000000 &&
158 (tmp & 0xfe000000) != 0) {
159 _rtld_error(
160 "%s: R_ARM_PC24 relocation @ %p to %s failed "

--- 9 unchanged lines hidden (view full) ---

170 obj->strtab + obj->symtab[symnum].st_name,
171 obj->path, (void *)*where, where, defobj->path);
172 break;
173 }
174#endif
175
176 case R_ARM_ABS32: /* word32 B + S + A */
177 case R_ARM_GLOB_DAT: /* word32 B + S */
163 if (def == NULL)
164 return -1;
165 tmp = (Elf_Addr)obj->relocbase + def->st_value
166 - (Elf_Addr)where + (addend << 2);
167 if ((tmp & 0xfe000000) != 0xfe000000 &&
168 (tmp & 0xfe000000) != 0) {
169 _rtld_error(
170 "%s: R_ARM_PC24 relocation @ %p to %s failed "

--- 9 unchanged lines hidden (view full) ---

180 obj->strtab + obj->symtab[symnum].st_name,
181 obj->path, (void *)*where, where, defobj->path);
182 break;
183 }
184#endif
185
186 case R_ARM_ABS32: /* word32 B + S + A */
187 case R_ARM_GLOB_DAT: /* word32 B + S */
178 def = find_symdef(symnum, obj, &defobj, false, cache);
188 def = find_symdef(symnum, obj, &defobj, false, cache,
189 lockstate);
179 if (def == NULL)
180 return -1;
181 if (__predict_true(RELOC_ALIGNED_P(where))) {
182 tmp = *where + (Elf_Addr)defobj->relocbase +
183 def->st_value;
184 *where = tmp;
185 } else {
186 tmp = load_ptr(where) +

--- 48 unchanged lines hidden (view full) ---

235 }
236 return 0;
237}
238
239/*
240 * * Process non-PLT relocations
241 * */
242int
190 if (def == NULL)
191 return -1;
192 if (__predict_true(RELOC_ALIGNED_P(where))) {
193 tmp = *where + (Elf_Addr)defobj->relocbase +
194 def->st_value;
195 *where = tmp;
196 } else {
197 tmp = load_ptr(where) +

--- 48 unchanged lines hidden (view full) ---

246 }
247 return 0;
248}
249
250/*
251 * * Process non-PLT relocations
252 * */
253int
243reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
254reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
244{
245 const Elf_Rel *rellim;
246 const Elf_Rel *rel;
247 SymCache *cache;
248 int r = -1;
249
250 /* The relocation for the dynamic loader has already been done. */
251 if (obj == obj_rtld)
252 return (0);
253 /*
254 * The dynamic loader may be called from a thread, we have
255 * limited amounts of stack available so we cannot use alloca().
256 */
257 cache = calloc(obj->nchains, sizeof(SymCache));
258 /* No need to check for NULL here */
259
260 rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize);
261 for (rel = obj->rel; rel < rellim; rel++) {
255{
256 const Elf_Rel *rellim;
257 const Elf_Rel *rel;
258 SymCache *cache;
259 int r = -1;
260
261 /* The relocation for the dynamic loader has already been done. */
262 if (obj == obj_rtld)
263 return (0);
264 /*
265 * The dynamic loader may be called from a thread, we have
266 * limited amounts of stack available so we cannot use alloca().
267 */
268 cache = calloc(obj->nchains, sizeof(SymCache));
269 /* No need to check for NULL here */
270
271 rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize);
272 for (rel = obj->rel; rel < rellim; rel++) {
262 if (reloc_nonplt_object(obj, rel, cache) < 0)
273 if (reloc_nonplt_object(obj, rel, cache, lockstate) < 0)
263 goto done;
264 }
265 r = 0;
266done:
267 if (cache != NULL)
268 free(cache);
269 return (r);
270}

--- 20 unchanged lines hidden (view full) ---

291
292 return (0);
293}
294
295/*
296 * * LD_BIND_NOW was set - force relocation for all jump slots
297 * */
298int
274 goto done;
275 }
276 r = 0;
277done:
278 if (cache != NULL)
279 free(cache);
280 return (r);
281}

--- 20 unchanged lines hidden (view full) ---

302
303 return (0);
304}
305
306/*
307 * * LD_BIND_NOW was set - force relocation for all jump slots
308 * */
309int
299reloc_jmpslots(Obj_Entry *obj)
310reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
300{
301 const Obj_Entry *defobj;
302 const Elf_Rel *rellim;
303 const Elf_Rel *rel;
304 const Elf_Sym *def;
305 Elf_Addr *where;
306 Elf_Addr target;
307
308 rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
309 for (rel = obj->pltrel; rel < rellim; rel++) {
310 assert(ELF_R_TYPE(rel->r_info) == R_ARM_JUMP_SLOT);
311 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
312 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
311{
312 const Obj_Entry *defobj;
313 const Elf_Rel *rellim;
314 const Elf_Rel *rel;
315 const Elf_Sym *def;
316 Elf_Addr *where;
317 Elf_Addr target;
318
319 rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
320 for (rel = obj->pltrel; rel < rellim; rel++) {
321 assert(ELF_R_TYPE(rel->r_info) == R_ARM_JUMP_SLOT);
322 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
323 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
313 true, NULL);
324 true, NULL, lockstate);
314 if (def == NULL) {
315 dbg("reloc_jmpslots: sym not found");
316 return (-1);
317 }
318
319 target = (Elf_Addr)(defobj->relocbase + def->st_value);
320 reloc_jmpslot(where, target, defobj, obj,
321 (const Elf_Rel *) rel);

--- 31 unchanged lines hidden ---
325 if (def == NULL) {
326 dbg("reloc_jmpslots: sym not found");
327 return (-1);
328 }
329
330 target = (Elf_Addr)(defobj->relocbase + def->st_value);
331 reloc_jmpslot(where, target, defobj, obj,
332 (const Elf_Rel *) rel);

--- 31 unchanged lines hidden ---