reloc.c (183841) | reloc.c (204687) |
---|---|
1/* $NetBSD: mdreloc.c,v 1.23 2003/07/26 15:04:38 mrg Exp $ */ 2/* $NetBSD: mips_reloc.c,v 1.53 2008/07/24 04:39:25 matt Exp $ */ | 1/* $NetBSD: mips_reloc.c,v 1.58 2010/01/14 11:57:06 skrll Exp $ */ |
3 4/* 5 * Copyright 1997 Michael L. Hitch <mhitch@montana.edu> 6 * Portions copyright 2002 Charles M. Hannum <root@ihack.net> 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions --- 14 unchanged lines hidden (view full) --- 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> | 2 3/* 4 * Copyright 1997 Michael L. Hitch <mhitch@montana.edu> 5 * Portions copyright 2002 Charles M. Hannum <root@ihack.net> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 14 unchanged lines hidden (view full) --- 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/libexec/rtld-elf/mips/reloc.c 183841 2008-10-13 20:24:03Z imp $"); 34#include <sys/param.h> 35#include <sys/mman.h> | 32__FBSDID("$FreeBSD: head/libexec/rtld-elf/mips/reloc.c 204687 2010-03-04 04:53:05Z imp $"); |
36 | 33 |
37#include <errno.h> 38#include <stdio.h> | 34#include <sys/types.h> 35#include <sys/stat.h> 36#include <sys/endian.h> 37 |
39#include <stdlib.h> 40#include <string.h> | 38#include <stdlib.h> 39#include <string.h> |
41#include <unistd.h> | 40 |
42#include "debug.h" 43#include "rtld.h" 44 45void 46init_pltgot(Obj_Entry *obj) | 41#include "debug.h" 42#include "rtld.h" 43 44void 45init_pltgot(Obj_Entry *obj) |
47{ | 46{ |
48 if (obj->pltgot != NULL) { 49 obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start; | 47 if (obj->pltgot != NULL) { 48 obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start; |
49 /* XXX only if obj->pltgot[1] & 0x80000000 ?? */ |
|
50 obj->pltgot[1] |= (Elf_Addr) obj; 51 } 52} 53 | 50 obj->pltgot[1] |= (Elf_Addr) obj; 51 } 52} 53 |
54int | 54int |
55do_copy_relocations(Obj_Entry *dstobj) 56{ 57 /* Do nothing */ | 55do_copy_relocations(Obj_Entry *dstobj) 56{ 57 /* Do nothing */ |
58 return 0; | 58 return 0; |
59} 60 | 59} 60 |
61void _rtld_bind_start(void); | |
62void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr); 63 | 61void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr); 62 |
64int open(); 65int _open(); 66 | |
67/* 68 * It is possible for the compiler to emit relocations for unaligned data. 69 * We handle this situation with these inlines. 70 */ | 63/* 64 * It is possible for the compiler to emit relocations for unaligned data. 65 * We handle this situation with these inlines. 66 */ |
71#define RELOC_ALIGNED_P(x) \ 72 (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0) | 67#if ELFSIZE == 64 68/* 69 * ELF64 MIPS encodes the relocs uniquely. The first 32-bits of info contain 70 * the symbol index. The top 32-bits contain three relocation types encoded 71 * in big-endian integer with first relocation in LSB. This means for little 72 * endian we have to byte swap that interger (r_type). 73 */ 74#define Elf_Sxword Elf64_Sxword 75#define ELF_R_NXTTYPE_64_P(r_type) ((((r_type) >> 8) & 0xff) == R_TYPE(64)) 76#if BYTE_ORDER == LITTLE_ENDIAN 77#undef ELF_R_SYM 78#undef ELF_R_TYPE 79#define ELF_R_SYM(r_info) ((r_info) & 0xffffffff) 80#define ELF_R_TYPE(r_info) bswap32((r_info) >> 32) 81#endif 82#else 83#define ELF_R_NXTTYPE_64_P(r_type) (0) 84#define Elf_Sxword Elf32_Sword 85#endif |
73 | 86 |
74static __inline Elf_Addr 75load_ptr(void *where) | 87static __inline Elf_Sxword 88load_ptr(void *where, size_t len) |
76{ | 89{ |
77 if (__predict_true(RELOC_ALIGNED_P(where))) 78 return *(Elf_Addr *)where; 79 else { 80 Elf_Addr res; | 90 Elf_Sxword val; |
81 | 91 |
82 (void)memcpy(&res, where, sizeof(res)); 83 return res; | 92 if (__predict_true(((uintptr_t)where & (len - 1)) == 0)) { 93#if ELFSIZE == 64 94 if (len == sizeof(Elf_Sxword)) 95 return *(Elf_Sxword *)where; 96#endif 97 return *(Elf_Sword *)where; |
84 } | 98 } |
99 100 val = 0; 101#if BYTE_ORDER == LITTLE_ENDIAN 102 (void)memcpy(&val, where, len); 103#endif 104#if BYTE_ORDER == BIG_ENDIAN 105 (void)memcpy((uint8_t *)((&val)+1) - len, where, len); 106#endif 107 return (len == sizeof(Elf_Sxword)) ? val : (Elf_Sword)val; |
|
85} 86 87static __inline void | 108} 109 110static __inline void |
88store_ptr(void *where, Elf_Addr val) | 111store_ptr(void *where, Elf_Sxword val, size_t len) |
89{ | 112{ |
90 if (__predict_true(RELOC_ALIGNED_P(where))) 91 *(Elf_Addr *)where = val; 92 else 93 (void)memcpy(where, &val, sizeof(val)); | 113 if (__predict_true(((uintptr_t)where & (len - 1)) == 0)) { 114#if ELFSIZE == 64 115 if (len == sizeof(Elf_Sxword)) { 116 *(Elf_Sxword *)where = val; 117 return; 118 } 119#endif 120 *(Elf_Sword *)where = val; 121 return; 122 } 123#if BYTE_ORDER == LITTLE_ENDIAN 124 (void)memcpy(where, &val, len); 125#endif 126#if BYTE_ORDER == BIG_ENDIAN 127 (void)memcpy(where, (const uint8_t *)((&val)+1) - len, len); 128#endif |
94} 95 96void 97_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase) 98{ 99 const Elf_Rel *rel = 0, *rellim; 100 Elf_Addr relsz = 0; 101 const Elf_Sym *symtab = NULL, *sym; 102 Elf_Addr *where; 103 Elf_Addr *got = NULL; 104 Elf_Word local_gotno = 0, symtabno = 0, gotsym = 0; | 129} 130 131void 132_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase) 133{ 134 const Elf_Rel *rel = 0, *rellim; 135 Elf_Addr relsz = 0; 136 const Elf_Sym *symtab = NULL, *sym; 137 Elf_Addr *where; 138 Elf_Addr *got = NULL; 139 Elf_Word local_gotno = 0, symtabno = 0, gotsym = 0; |
105 int i; | 140 size_t i; |
106 107 for (; dynp->d_tag != DT_NULL; dynp++) { 108 switch (dynp->d_tag) { 109 case DT_REL: 110 rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr); 111 break; 112 case DT_RELSZ: 113 relsz = dynp->d_un.d_val; --- 15 unchanged lines hidden (view full) --- 129 break; 130 } 131 } 132 133 i = (got[1] & 0x80000000) ? 2 : 1; 134 /* Relocate the local GOT entries */ 135 got += i; 136 for (; i < local_gotno; i++) { | 141 142 for (; dynp->d_tag != DT_NULL; dynp++) { 143 switch (dynp->d_tag) { 144 case DT_REL: 145 rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr); 146 break; 147 case DT_RELSZ: 148 relsz = dynp->d_un.d_val; --- 15 unchanged lines hidden (view full) --- 164 break; 165 } 166 } 167 168 i = (got[1] & 0x80000000) ? 2 : 1; 169 /* Relocate the local GOT entries */ 170 got += i; 171 for (; i < local_gotno; i++) { |
137 *got++ += relocbase; | 172 *got++ += relocbase; |
138 } 139 140 sym = symtab + gotsym; 141 /* Now do the global GOT entries */ 142 for (i = gotsym; i < symtabno; i++) { 143 *got = sym->st_value + relocbase; 144 ++sym; 145 ++got; 146 } 147 148 rellim = (const Elf_Rel *)((caddr_t)rel + relsz); 149 for (; rel < rellim; rel++) { | 173 } 174 175 sym = symtab + gotsym; 176 /* Now do the global GOT entries */ 177 for (i = gotsym; i < symtabno; i++) { 178 *got = sym->st_value + relocbase; 179 ++sym; 180 ++got; 181 } 182 183 rellim = (const Elf_Rel *)((caddr_t)rel + relsz); 184 for (; rel < rellim; rel++) { |
185 Elf_Word r_symndx, r_type; 186 |
|
150 where = (void *)(relocbase + rel->r_offset); 151 | 187 where = (void *)(relocbase + rel->r_offset); 188 |
152 switch (ELF_R_TYPE(rel->r_info)) { 153 case R_TYPE(NONE): 154 break; | 189 r_symndx = ELF_R_SYM(rel->r_info); 190 r_type = ELF_R_TYPE(rel->r_info); |
155 | 191 |
156 case R_TYPE(REL32): 157 assert(ELF_R_SYM(rel->r_info) < gotsym); 158 sym = symtab + ELF_R_SYM(rel->r_info); | 192 switch (r_type & 0xff) { 193 case R_TYPE(REL32): { 194 const size_t rlen = 195 ELF_R_NXTTYPE_64_P(r_type) 196 ? sizeof(Elf_Sxword) 197 : sizeof(Elf_Sword); 198 Elf_Sxword old = load_ptr(where, rlen); 199 Elf_Sxword val = old; 200#if ELFSIZE == 64 201 assert(r_type == R_TYPE(REL32) 202 || r_type == (R_TYPE(REL32)|(R_TYPE(64) << 8))); 203#endif 204 assert(r_symndx < gotsym); 205 sym = symtab + r_symndx; |
159 assert(ELF_ST_BIND(sym->st_info) == STB_LOCAL); | 206 assert(ELF_ST_BIND(sym->st_info) == STB_LOCAL); |
160 store_ptr(where, load_ptr(where) + relocbase); | 207 val += relocbase; 208 store_ptr(where, val, sizeof(Elf_Sword)); 209 dbg("REL32/L(%p) %p -> %p in <self>", 210 where, (void *)old, (void *)val); 211 store_ptr(where, val, rlen); |
161 break; | 212 break; |
213 } |
|
162 | 214 |
215 case R_TYPE(GPREL32): 216 case R_TYPE(NONE): 217 break; 218 219 |
|
163 default: 164 abort(); 165 break; 166 } 167 } 168} 169 170Elf_Addr --- 13 unchanged lines hidden (view full) --- 184 obj->path, 185 reloff, defobj->strtab + def->st_name, 186 (void *)got[obj->local_gotno + reloff - obj->gotsym], 187 (void *)target); 188 got[obj->local_gotno + reloff - obj->gotsym] = target; 189 return (Elf_Addr)target; 190} 191 | 220 default: 221 abort(); 222 break; 223 } 224 } 225} 226 227Elf_Addr --- 13 unchanged lines hidden (view full) --- 241 obj->path, 242 reloff, defobj->strtab + def->st_name, 243 (void *)got[obj->local_gotno + reloff - obj->gotsym], 244 (void *)target); 245 got[obj->local_gotno + reloff - obj->gotsym] = target; 246 return (Elf_Addr)target; 247} 248 |
192/* 193 * Process non-PLT relocations 194 */ | |
195int 196reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) 197{ 198 const Elf_Rel *rel; 199 const Elf_Rel *rellim; 200 Elf_Addr *got = obj->pltgot; 201 const Elf_Sym *sym, *def; 202 const Obj_Entry *defobj; | 249int 250reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) 251{ 252 const Elf_Rel *rel; 253 const Elf_Rel *rellim; 254 Elf_Addr *got = obj->pltgot; 255 const Elf_Sym *sym, *def; 256 const Obj_Entry *defobj; |
203 int i; | 257 Elf_Word i; 258#ifdef SUPPORT_OLD_BROKEN_LD 259 int broken; 260#endif |
204 205 /* The relocation for the dynamic loader has already been done. */ 206 if (obj == obj_rtld) 207 return (0); 208 | 261 262 /* The relocation for the dynamic loader has already been done. */ 263 if (obj == obj_rtld) 264 return (0); 265 |
266#ifdef SUPPORT_OLD_BROKEN_LD 267 broken = 0; 268 sym = obj->symtab; 269 for (i = 1; i < 12; i++) 270 if (sym[i].st_info == ELF_ST_INFO(STB_LOCAL, STT_NOTYPE)) 271 broken = 1; 272 dbg("%s: broken=%d", obj->path, broken); 273#endif 274 |
|
209 i = (got[1] & 0x80000000) ? 2 : 1; 210 211 /* Relocate the local GOT entries */ 212 got += i; 213 dbg("got:%p for %d entries adding %x", 214 got, obj->local_gotno, (uint32_t)obj->relocbase); 215 for (; i < obj->local_gotno; i++) { | 275 i = (got[1] & 0x80000000) ? 2 : 1; 276 277 /* Relocate the local GOT entries */ 278 got += i; 279 dbg("got:%p for %d entries adding %x", 280 got, obj->local_gotno, (uint32_t)obj->relocbase); 281 for (; i < obj->local_gotno; i++) { |
216 *got += (Elf_Addr)obj->relocbase; 217 got++; | 282 *got += (Elf_Addr)obj->relocbase; 283 got++; |
218 } 219 sym = obj->symtab + obj->gotsym; 220 | 284 } 285 sym = obj->symtab + obj->gotsym; 286 |
221 | |
222 dbg("got:%p for %d entries", 223 got, obj->symtabno); 224 /* Now do the global GOT entries */ 225 for (i = obj->gotsym; i < obj->symtabno; i++) { | 287 dbg("got:%p for %d entries", 288 got, obj->symtabno); 289 /* Now do the global GOT entries */ 290 for (i = obj->gotsym; i < obj->symtabno; i++) { |
291 dbg(" doing got %d sym %p (%s, %lx)", i - obj->gotsym, sym, 292 sym->st_name + obj->strtab, (u_long) *got); 293 294#ifdef SUPPORT_OLD_BROKEN_LD |
|
226 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && | 295 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && |
296 broken && sym->st_shndx == SHN_UNDEF) { 297 /* 298 * XXX DANGER WILL ROBINSON! 299 * You might think this is stupid, as it intentionally 300 * defeats lazy binding -- and you'd be right. 301 * Unfortunately, for lazy binding to work right, we 302 * need to a way to force the GOT slots used for 303 * function pointers to be resolved immediately. This 304 * is supposed to be done automatically by the linker, 305 * by not outputting a PLT slot and setting st_value 306 * to 0 if there are non-PLT references, but older 307 * versions of GNU ld do not do this. 308 */ 309 def = find_symdef(i, obj, &defobj, false, NULL); 310 if (def == NULL) 311 return -1; 312 *got = def->st_value + (Elf_Addr)defobj->relocbase; 313 } else 314#endif 315 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && |
|
227 sym->st_value != 0 && sym->st_shndx == SHN_UNDEF) { 228 /* 229 * If there are non-PLT references to the function, 230 * st_value should be 0, forcing us to resolve the 231 * address immediately. 232 * 233 * XXX DANGER WILL ROBINSON! 234 * The linker is not outputting PLT slots for calls to 235 * functions that are defined in the same shared 236 * library. This is a bug, because it can screw up 237 * link ordering rules if the symbol is defined in 238 * more than one module. For now, if there is a 239 * definition, we fail the test above and force a full 240 * symbol lookup. This means that all intra-module 241 * calls are bound immediately. - mycroft, 2003/09/24 242 */ 243 *got = sym->st_value + (Elf_Addr)obj->relocbase; 244 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) { | 316 sym->st_value != 0 && sym->st_shndx == SHN_UNDEF) { 317 /* 318 * If there are non-PLT references to the function, 319 * st_value should be 0, forcing us to resolve the 320 * address immediately. 321 * 322 * XXX DANGER WILL ROBINSON! 323 * The linker is not outputting PLT slots for calls to 324 * functions that are defined in the same shared 325 * library. This is a bug, because it can screw up 326 * link ordering rules if the symbol is defined in 327 * more than one module. For now, if there is a 328 * definition, we fail the test above and force a full 329 * symbol lookup. This means that all intra-module 330 * calls are bound immediately. - mycroft, 2003/09/24 331 */ 332 *got = sym->st_value + (Elf_Addr)obj->relocbase; 333 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) { |
245 dbg("Warning2, i:%d maps to relocbase address:%x", 246 i, (uint32_t)obj->relocbase); | 334 dbg("Warning2, i:%d maps to relocbase address:%x", 335 i, (uint32_t)obj->relocbase); |
247 } 248 249 } else if (sym->st_info == ELF_ST_INFO(STB_GLOBAL, STT_SECTION)) { 250 /* Symbols with index SHN_ABS are not relocated. */ | 336 } 337 338 } else if (sym->st_info == ELF_ST_INFO(STB_GLOBAL, STT_SECTION)) { 339 /* Symbols with index SHN_ABS are not relocated. */ |
251 if (sym->st_shndx != SHN_ABS) { | 340 if (sym->st_shndx != SHN_ABS) { |
252 *got = sym->st_value + 253 (Elf_Addr)obj->relocbase; 254 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) { | 341 *got = sym->st_value + 342 (Elf_Addr)obj->relocbase; 343 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) { |
255 dbg("Warning3, i:%d maps to relocbase address:%x", 256 i, (uint32_t)obj->relocbase); | 344 dbg("Warning3, i:%d maps to relocbase address:%x", 345 i, (uint32_t)obj->relocbase); |
257 } 258 } 259 } else { 260 /* TODO: add cache here */ 261 def = find_symdef(i, obj, &defobj, false, NULL); 262 if (def == NULL) { | 346 } 347 } 348 } else { 349 /* TODO: add cache here */ 350 def = find_symdef(i, obj, &defobj, false, NULL); 351 if (def == NULL) { |
263 dbg("Warning4, cant find symbole %d", i); | 352 dbg("Warning4, cant find symbole %d", i); |
264 return -1; 265 } 266 *got = def->st_value + (Elf_Addr)defobj->relocbase; 267 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) { | 353 return -1; 354 } 355 *got = def->st_value + (Elf_Addr)defobj->relocbase; 356 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) { |
268 dbg("Warning4, i:%d maps to relocbase address:%x", 269 i, (uint32_t)obj->relocbase); 270 dbg("via first obj symbol %s", 271 obj->strtab + obj->symtab[i].st_name); 272 dbg("found in obj %p:%s", 273 defobj, defobj->path); 274 } | 357 dbg("Warning4, i:%d maps to relocbase address:%x", 358 i, (uint32_t)obj->relocbase); 359 dbg("via first obj symbol %s", 360 obj->strtab + obj->symtab[i].st_name); 361 dbg("found in obj %p:%s", 362 defobj, defobj->path); 363 } |
275 } | 364 } |
365 366 dbg(" --> now %lx", (u_long) *got); |
|
276 ++sym; 277 ++got; 278 } | 367 ++sym; 368 ++got; 369 } |
370 |
|
279 got = obj->pltgot; 280 rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize); 281 for (rel = obj->rel; rel < rellim; rel++) { | 371 got = obj->pltgot; 372 rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize); 373 for (rel = obj->rel; rel < rellim; rel++) { |
374 Elf_Word r_symndx, r_type; |
|
282 void *where; | 375 void *where; |
283 Elf_Addr tmp; 284 unsigned long symnum; | |
285 286 where = obj->relocbase + rel->r_offset; | 376 377 where = obj->relocbase + rel->r_offset; |
287 symnum = ELF_R_SYM(rel->r_info); 288 switch (ELF_R_TYPE(rel->r_info)) { | 378 r_symndx = ELF_R_SYM(rel->r_info); 379 r_type = ELF_R_TYPE(rel->r_info); 380 381 switch (r_type & 0xff) { |
289 case R_TYPE(NONE): 290 break; 291 | 382 case R_TYPE(NONE): 383 break; 384 |
292 case R_TYPE(REL32): | 385 case R_TYPE(REL32): { |
293 /* 32-bit PC-relative reference */ | 386 /* 32-bit PC-relative reference */ |
294 def = obj->symtab + symnum; 295 if (symnum >= obj->gotsym) { 296 tmp = load_ptr(where); 297 tmp += got[obj->local_gotno + symnum - obj->gotsym]; 298 store_ptr(where, tmp); 299 break; | 387 const size_t rlen = 388 ELF_R_NXTTYPE_64_P(r_type) 389 ? sizeof(Elf_Sxword) 390 : sizeof(Elf_Sword); 391 Elf_Sxword old = load_ptr(where, rlen); 392 Elf_Sxword val = old; 393 394 def = obj->symtab + r_symndx; 395 396 if (r_symndx >= obj->gotsym) { 397 val += got[obj->local_gotno + r_symndx - obj->gotsym]; 398 dbg("REL32/G(%p) %p --> %p (%s) in %s", 399 where, (void *)old, (void *)val, 400 obj->strtab + def->st_name, 401 obj->path); |
300 } else { | 402 } else { |
301 tmp = load_ptr(where); | 403 /* 404 * XXX: ABI DIFFERENCE! 405 * 406 * Old NetBSD binutils would generate shared 407 * libs with section-relative relocations being 408 * already adjusted for the start address of 409 * the section. 410 * 411 * New binutils, OTOH, generate shared libs 412 * with the same relocations being based at 413 * zero, so we need to add in the start address 414 * of the section. 415 * 416 * --rkb, Oct 6, 2001 417 */ |
302 303 if (def->st_info == 304 ELF_ST_INFO(STB_LOCAL, STT_SECTION) | 418 419 if (def->st_info == 420 ELF_ST_INFO(STB_LOCAL, STT_SECTION) |
421#ifdef SUPPORT_OLD_BROKEN_LD 422 && !broken 423#endif |
|
305 ) | 424 ) |
306 tmp += (Elf_Addr)def->st_value; | 425 val += (Elf_Addr)def->st_value; |
307 | 426 |
308 tmp += (Elf_Addr)obj->relocbase; 309 store_ptr(where, tmp); | 427 val += (Elf_Addr)obj->relocbase; 428 429 dbg("REL32/L(%p) %p -> %p (%s) in %s", 430 where, (void *)old, (void *)val, 431 obj->strtab + def->st_name, obj->path); |
310 } | 432 } |
433 store_ptr(where, val, rlen); |
|
311 break; | 434 break; |
435 } 436 |
|
312 default: 313 dbg("sym = %lu, type = %lu, offset = %p, " 314 "contents = %p, symbol = %s", | 437 default: 438 dbg("sym = %lu, type = %lu, offset = %p, " 439 "contents = %p, symbol = %s", |
315 symnum, (u_long)ELF_R_TYPE(rel->r_info), 316 (void *)rel->r_offset, (void *)load_ptr(where), 317 obj->strtab + obj->symtab[symnum].st_name); | 440 (u_long)r_symndx, (u_long)ELF_R_TYPE(rel->r_info), 441 (void *)rel->r_offset, 442 (void *)load_ptr(where, sizeof(Elf_Sword)), 443 obj->strtab + obj->symtab[r_symndx].st_name); |
318 _rtld_error("%s: Unsupported relocation type %ld " | 444 _rtld_error("%s: Unsupported relocation type %ld " |
319 "in non-PLT relocations\n", | 445 "in non-PLT relocations", |
320 obj->path, (u_long) ELF_R_TYPE(rel->r_info)); 321 return -1; 322 } 323 } 324 325 return 0; 326} 327 328/* 329 * Process the PLT relocations. 330 */ 331int 332reloc_plt(Obj_Entry *obj) 333{ | 446 obj->path, (u_long) ELF_R_TYPE(rel->r_info)); 447 return -1; 448 } 449 } 450 451 return 0; 452} 453 454/* 455 * Process the PLT relocations. 456 */ 457int 458reloc_plt(Obj_Entry *obj) 459{ |
460#if 0 |
|
334 const Elf_Rel *rellim; 335 const Elf_Rel *rel; 336 337 dbg("reloc_plt obj:%p pltrel:%p sz:%d", obj, obj->pltrel, (int)obj->pltrelsize); 338 dbg("gottable %p num syms:%d", obj->pltgot, obj->symtabno ); 339 dbg("*****************************************************"); 340 rellim = (const Elf_Rel *)((char *)obj->pltrel + 341 obj->pltrelsize); 342 for (rel = obj->pltrel; rel < rellim; rel++) { 343 Elf_Addr *where; 344 where = (Elf_Addr *)(obj->relocbase + rel->r_offset); 345 *where += (Elf_Addr )obj->relocbase; 346 } 347 | 461 const Elf_Rel *rellim; 462 const Elf_Rel *rel; 463 464 dbg("reloc_plt obj:%p pltrel:%p sz:%d", obj, obj->pltrel, (int)obj->pltrelsize); 465 dbg("gottable %p num syms:%d", obj->pltgot, obj->symtabno ); 466 dbg("*****************************************************"); 467 rellim = (const Elf_Rel *)((char *)obj->pltrel + 468 obj->pltrelsize); 469 for (rel = obj->pltrel; rel < rellim; rel++) { 470 Elf_Addr *where; 471 where = (Elf_Addr *)(obj->relocbase + rel->r_offset); 472 *where += (Elf_Addr )obj->relocbase; 473 } 474 |
475#endif 476 /* PLT fixups were done above in the GOT relocation. */ |
|
348 return (0); 349} 350 351/* 352 * LD_BIND_NOW was set - force relocation for all jump slots 353 */ 354int 355reloc_jmpslots(Obj_Entry *obj) --- 28 unchanged lines hidden --- | 477 return (0); 478} 479 480/* 481 * LD_BIND_NOW was set - force relocation for all jump slots 482 */ 483int 484reloc_jmpslots(Obj_Entry *obj) --- 28 unchanged lines hidden --- |