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 --- |