reloc.c (123481) | reloc.c (133063) |
---|---|
1/*- 2 * Copyright 1996, 1997, 1998, 1999 John D. Polstra. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * | 1/*- 2 * Copyright 1996, 1997, 1998, 1999 John D. Polstra. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * |
25 * $FreeBSD: head/libexec/rtld-elf/amd64/reloc.c 123481 2003-12-12 01:12:41Z peter $ | 25 * $FreeBSD: head/libexec/rtld-elf/amd64/reloc.c 133063 2004-08-03 08:51:00Z dfr $ |
26 */ 27 28/* 29 * Dynamic linker for ELF. 30 * 31 * John Polstra <jdp@polstra.com>. 32 */ 33 34#include <sys/param.h> 35#include <sys/mman.h> | 26 */ 27 28/* 29 * Dynamic linker for ELF. 30 * 31 * John Polstra <jdp@polstra.com>. 32 */ 33 34#include <sys/param.h> 35#include <sys/mman.h> |
36#include <machine/sysarch.h> |
|
36 37#include <dlfcn.h> 38#include <err.h> 39#include <errno.h> 40#include <fcntl.h> 41#include <stdarg.h> 42#include <stdio.h> 43#include <stdlib.h> --- 150 unchanged lines hidden (view full) --- 194 false, cache); 195 if (def == NULL) 196 goto done; 197 198 *where = (Elf_Addr) (defobj->relocbase + def->st_value); 199 } 200 break; 201 | 37 38#include <dlfcn.h> 39#include <err.h> 40#include <errno.h> 41#include <fcntl.h> 42#include <stdarg.h> 43#include <stdio.h> 44#include <stdlib.h> --- 150 unchanged lines hidden (view full) --- 195 false, cache); 196 if (def == NULL) 197 goto done; 198 199 *where = (Elf_Addr) (defobj->relocbase + def->st_value); 200 } 201 break; 202 |
203 case R_X86_64_TPOFF64: 204 { 205 const Elf_Sym *def; 206 const Obj_Entry *defobj; 207 208 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, 209 false, cache); 210 if (def == NULL) 211 goto done; 212 213 /* 214 * We lazily allocate offsets for static TLS as we 215 * see the first relocation that references the 216 * TLS block. This allows us to support (small 217 * amounts of) static TLS in dynamically loaded 218 * modules. If we run out of space, we generate an 219 * error. 220 */ 221 if (!defobj->tls_done) { 222 if (!allocate_tls_offset((Obj_Entry*) defobj)) { 223 _rtld_error("%s: No space available for static " 224 "Thread Local Storage", obj->path); 225 goto done; 226 } 227 } 228 229 *where = (Elf_Addr) (def->st_value - defobj->tlsoffset + 230 rela->r_addend); 231 } 232 break; 233 234 case R_X86_64_TPOFF32: 235 { 236 const Elf_Sym *def; 237 const Obj_Entry *defobj; 238 239 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, 240 false, cache); 241 if (def == NULL) 242 goto done; 243 244 /* 245 * We lazily allocate offsets for static TLS as we 246 * see the first relocation that references the 247 * TLS block. This allows us to support (small 248 * amounts of) static TLS in dynamically loaded 249 * modules. If we run out of space, we generate an 250 * error. 251 */ 252 if (!defobj->tls_done) { 253 if (!allocate_tls_offset((Obj_Entry*) defobj)) { 254 _rtld_error("%s: No space available for static " 255 "Thread Local Storage", obj->path); 256 goto done; 257 } 258 } 259 260 *where32 = (Elf32_Addr) (def->st_value - 261 defobj->tlsoffset + 262 rela->r_addend); 263 } 264 break; 265 266 case R_X86_64_DTPMOD64: 267 { 268 const Elf_Sym *def; 269 const Obj_Entry *defobj; 270 271 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, 272 false, cache); 273 if (def == NULL) 274 goto done; 275 276 *where += (Elf_Addr) defobj->tlsindex; 277 } 278 break; 279 280 case R_X86_64_DTPOFF64: 281 { 282 const Elf_Sym *def; 283 const Obj_Entry *defobj; 284 285 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, 286 false, cache); 287 if (def == NULL) 288 goto done; 289 290 *where += (Elf_Addr) (def->st_value + rela->r_addend); 291 } 292 break; 293 294 case R_X86_64_DTPOFF32: 295 { 296 const Elf_Sym *def; 297 const Obj_Entry *defobj; 298 299 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, 300 false, cache); 301 if (def == NULL) 302 goto done; 303 304 *where32 += (Elf32_Addr) (def->st_value + rela->r_addend); 305 } 306 break; 307 |
|
202 case R_X86_64_RELATIVE: 203 *where = (Elf_Addr)(obj->relocbase + rela->r_addend); 204 break; 205 206 /* missing: R_X86_64_GOTPCREL, R_X86_64_32, R_X86_64_32S, R_X86_64_16, R_X86_64_PC16, R_X86_64_8, R_X86_64_PC8 */ 207 208 default: 209 _rtld_error("%s: Unsupported relocation type %d" --- 50 unchanged lines hidden (view full) --- 260 if (def == NULL) 261 return -1; 262 target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); 263 reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela); 264 } 265 obj->jmpslots_done = true; 266 return 0; 267} | 308 case R_X86_64_RELATIVE: 309 *where = (Elf_Addr)(obj->relocbase + rela->r_addend); 310 break; 311 312 /* missing: R_X86_64_GOTPCREL, R_X86_64_32, R_X86_64_32S, R_X86_64_16, R_X86_64_PC16, R_X86_64_8, R_X86_64_PC8 */ 313 314 default: 315 _rtld_error("%s: Unsupported relocation type %d" --- 50 unchanged lines hidden (view full) --- 366 if (def == NULL) 367 return -1; 368 target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); 369 reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela); 370 } 371 obj->jmpslots_done = true; 372 return 0; 373} |
374 375void 376allocate_initial_tls(Obj_Entry *objs) 377{ 378 /* 379 * Fix the size of the static TLS block by using the maximum 380 * offset allocated so far and adding a bit for dynamic modules to 381 * use. 382 */ 383 tls_static_space = tls_last_offset + RTLD_STATIC_TLS_EXTRA; 384 amd64_set_fsbase(allocate_tls(objs, 0, 385 2*sizeof(Elf_Addr), sizeof(Elf_Addr))); 386} 387 388void *__tls_get_addr(tls_index *ti) 389{ 390 Elf_Addr** segbase; 391 Elf_Addr* dtv; 392 393 __asm __volatile("movq %%fs:0, %0" : "=r" (segbase)); 394 dtv = segbase[1]; 395 396 return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset); 397} |
|