reloc.c (112242) | reloc.c (115396) |
---|---|
1/* $NetBSD: mdreloc.c,v 1.5 2001/04/25 12:24:51 kleink Exp $ */ 2 3/*- 4 * Copyright (c) 2000 Eduardo Horvath. 5 * Copyright (c) 1999 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation --- 22 unchanged lines hidden (view full) --- 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 * | 1/* $NetBSD: mdreloc.c,v 1.5 2001/04/25 12:24:51 kleink Exp $ */ 2 3/*- 4 * Copyright (c) 2000 Eduardo Horvath. 5 * Copyright (c) 1999 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation --- 22 unchanged lines hidden (view full) --- 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 * |
39 * $FreeBSD: head/libexec/rtld-elf/sparc64/reloc.c 112242 2003-03-14 21:10:13Z kan $ | 39 * $FreeBSD: head/libexec/rtld-elf/sparc64/reloc.c 115396 2003-05-29 22:58:26Z kan $ |
40 */ 41 42#include <sys/param.h> 43#include <sys/mman.h> 44 45#include <errno.h> 46#include <stdio.h> 47#include <stdlib.h> --- 89 unchanged lines hidden (view full) --- 137static const char *reloc_names[] = { 138 "NONE", "RELOC_8", "RELOC_16", "RELOC_32", "DISP_8", 139 "DISP_16", "DISP_32", "WDISP_30", "WDISP_22", "HI22", 140 "22", "13", "LO10", "GOT10", "GOT13", 141 "GOT22", "PC10", "PC22", "WPLT30", "COPY", 142 "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32", "PLT32", 143 "HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22", "PCPLT32", 144 "10", "11", "64", "OLO10", "HH22", | 40 */ 41 42#include <sys/param.h> 43#include <sys/mman.h> 44 45#include <errno.h> 46#include <stdio.h> 47#include <stdlib.h> --- 89 unchanged lines hidden (view full) --- 137static const char *reloc_names[] = { 138 "NONE", "RELOC_8", "RELOC_16", "RELOC_32", "DISP_8", 139 "DISP_16", "DISP_32", "WDISP_30", "WDISP_22", "HI22", 140 "22", "13", "LO10", "GOT10", "GOT13", 141 "GOT22", "PC10", "PC22", "WPLT30", "COPY", 142 "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32", "PLT32", 143 "HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22", "PCPLT32", 144 "10", "11", "64", "OLO10", "HH22", |
145 "HM10", "LM22", "PC_HH22", "PC_HM10", "PC_LM22", | 145 "HM10", "LM22", "PC_HH22", "PC_HM10", "PC_LM22", |
146 "WDISP16", "WDISP19", "GLOB_JMP", "7", "5", "6", | 146 "WDISP16", "WDISP19", "GLOB_JMP", "7", "5", "6", |
147 "DISP64", "PLT64", "HIX22", "LOX10", "H44", "M44", | 147 "DISP64", "PLT64", "HIX22", "LOX10", "H44", "M44", |
148 "L44", "REGISTER", "UA64", "UA16" 149}; 150#endif 151 152#define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != 0) 153#define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != 0) 154#define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != 0) 155#define RELOC_UNALIGNED(t) ((reloc_target_flags[t] & _RF_U) != 0) --- 5 unchanged lines hidden (view full) --- 161#define _BM(x) (~(-(1ULL << (x)))) 162 0, /* NONE */ 163 _BM(8), _BM(16), _BM(32), /* RELOC_8, _16, _32 */ 164 _BM(8), _BM(16), _BM(32), /* DISP8, DISP16, DISP32 */ 165 _BM(30), _BM(22), /* WDISP30, WDISP22 */ 166 _BM(22), _BM(22), /* HI22, _22 */ 167 _BM(13), _BM(10), /* RELOC_13, _LO10 */ 168 _BM(10), _BM(13), _BM(22), /* GOT10, GOT13, GOT22 */ | 148 "L44", "REGISTER", "UA64", "UA16" 149}; 150#endif 151 152#define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != 0) 153#define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != 0) 154#define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != 0) 155#define RELOC_UNALIGNED(t) ((reloc_target_flags[t] & _RF_U) != 0) --- 5 unchanged lines hidden (view full) --- 161#define _BM(x) (~(-(1ULL << (x)))) 162 0, /* NONE */ 163 _BM(8), _BM(16), _BM(32), /* RELOC_8, _16, _32 */ 164 _BM(8), _BM(16), _BM(32), /* DISP8, DISP16, DISP32 */ 165 _BM(30), _BM(22), /* WDISP30, WDISP22 */ 166 _BM(22), _BM(22), /* HI22, _22 */ 167 _BM(13), _BM(10), /* RELOC_13, _LO10 */ 168 _BM(10), _BM(13), _BM(22), /* GOT10, GOT13, GOT22 */ |
169 _BM(10), _BM(22), /* _PC10, _PC22 */ | 169 _BM(10), _BM(22), /* _PC10, _PC22 */ |
170 _BM(30), 0, /* _WPLT30, _COPY */ 171 _BM(32), _BM(32), _BM(32), /* _GLOB_DAT, JMP_SLOT, _RELATIVE */ 172 _BM(32), _BM(32), /* _UA32, PLT32 */ 173 _BM(22), _BM(10), /* _HIPLT22, LOPLT10 */ 174 _BM(32), _BM(22), _BM(10), /* _PCPLT32, _PCPLT22, _PCPLT10 */ 175 _BM(10), _BM(11), -1, /* _10, _11, _64 */ 176 _BM(10), _BM(22), /* _OLO10, _HH22 */ 177 _BM(10), _BM(22), /* _HM10, _LM22 */ --- 101 unchanged lines hidden (view full) --- 279{ 280 const Obj_Entry *defobj; 281 const Elf_Sym *def; 282 Elf_Addr *where; 283 Elf_Half *where32; 284 Elf_Word type; 285 Elf_Addr value; 286 Elf_Addr mask; | 170 _BM(30), 0, /* _WPLT30, _COPY */ 171 _BM(32), _BM(32), _BM(32), /* _GLOB_DAT, JMP_SLOT, _RELATIVE */ 172 _BM(32), _BM(32), /* _UA32, PLT32 */ 173 _BM(22), _BM(10), /* _HIPLT22, LOPLT10 */ 174 _BM(32), _BM(22), _BM(10), /* _PCPLT32, _PCPLT22, _PCPLT10 */ 175 _BM(10), _BM(11), -1, /* _10, _11, _64 */ 176 _BM(10), _BM(22), /* _OLO10, _HH22 */ 177 _BM(10), _BM(22), /* _HM10, _LM22 */ --- 101 unchanged lines hidden (view full) --- 279{ 280 const Obj_Entry *defobj; 281 const Elf_Sym *def; 282 Elf_Addr *where; 283 Elf_Half *where32; 284 Elf_Word type; 285 Elf_Addr value; 286 Elf_Addr mask; |
287 | 287 |
288 where = (Elf_Addr *)(obj->relocbase + rela->r_offset); 289 where32 = (Elf_Half *)where; 290 defobj = NULL; 291 def = NULL; 292 293 type = ELF_R_TYPE(rela->r_info); 294 if (type == R_SPARC_NONE) 295 return (0); --- 63 unchanged lines hidden (view full) --- 359 value &= mask; 360 361 if (RELOC_UNALIGNED(type)) { 362 /* Handle unaligned relocations. */ 363 Elf_Addr tmp; 364 char *ptr; 365 int size; 366 int i; | 288 where = (Elf_Addr *)(obj->relocbase + rela->r_offset); 289 where32 = (Elf_Half *)where; 290 defobj = NULL; 291 def = NULL; 292 293 type = ELF_R_TYPE(rela->r_info); 294 if (type == R_SPARC_NONE) 295 return (0); --- 63 unchanged lines hidden (view full) --- 359 value &= mask; 360 361 if (RELOC_UNALIGNED(type)) { 362 /* Handle unaligned relocations. */ 363 Elf_Addr tmp; 364 char *ptr; 365 int size; 366 int i; |
367 | 367 |
368 size = RELOC_TARGET_SIZE(type) / 8; 369 ptr = (char *)where; 370 tmp = 0; | 368 size = RELOC_TARGET_SIZE(type) / 8; 369 ptr = (char *)where; 370 tmp = 0; |
371 | 371 |
372 /* Read it in one byte at a time. */ 373 for (i = 0; i < size; i++) 374 tmp = (tmp << 8) | ptr[i]; 375 376 tmp &= ~mask; 377 tmp |= value; 378 379 /* Write it back out. */ --- 114 unchanged lines hidden (view full) --- 494 * 495 * We now need to find out how far we need to jump. We 496 * have a choice of several different relocation techniques 497 * which are increasingly expensive. 498 */ 499 where = (Elf_Half *)wherep; 500 offset = ((Elf_Addr)where) - target; 501 if (offset <= (1L<<20) && offset >= -(1L<<20)) { | 372 /* Read it in one byte at a time. */ 373 for (i = 0; i < size; i++) 374 tmp = (tmp << 8) | ptr[i]; 375 376 tmp &= ~mask; 377 tmp |= value; 378 379 /* Write it back out. */ --- 114 unchanged lines hidden (view full) --- 494 * 495 * We now need to find out how far we need to jump. We 496 * have a choice of several different relocation techniques 497 * which are increasingly expensive. 498 */ 499 where = (Elf_Half *)wherep; 500 offset = ((Elf_Addr)where) - target; 501 if (offset <= (1L<<20) && offset >= -(1L<<20)) { |
502 /* | 502 /* |
503 * We're within 1MB -- we can use a direct branch insn. 504 * 505 * We can generate this pattern: 506 * 507 * sethi %hi(. - .PLT0), %g1 508 * ba,a %xcc, addr 509 * nop 510 * nop 511 * nop 512 * nop 513 * nop 514 * nop 515 * 516 */ 517 where[1] = BAA | ((offset >> 2) &0x3fffff); 518 flush(where, 4); 519 } else if (target >= 0 && target < (1L<<32)) { | 503 * We're within 1MB -- we can use a direct branch insn. 504 * 505 * We can generate this pattern: 506 * 507 * sethi %hi(. - .PLT0), %g1 508 * ba,a %xcc, addr 509 * nop 510 * nop 511 * nop 512 * nop 513 * nop 514 * nop 515 * 516 */ 517 where[1] = BAA | ((offset >> 2) &0x3fffff); 518 flush(where, 4); 519 } else if (target >= 0 && target < (1L<<32)) { |
520 /* | 520 /* |
521 * We're withing 32-bits of address zero. 522 * 523 * The resulting code in the jump slot is: 524 * 525 * sethi %hi(. - .PLT0), %g1 526 * sethi %hi(addr), %g1 527 * jmp %g1+%lo(addr) 528 * nop 529 * nop 530 * nop 531 * nop 532 * nop 533 * 534 */ 535 where[2] = JMP | LOVAL(target); 536 flush(where, 8); 537 where[1] = SETHI | HIVAL(target, 10); 538 flush(where, 4); 539 } else if (target <= 0 && target > -(1L<<32)) { | 521 * We're withing 32-bits of address zero. 522 * 523 * The resulting code in the jump slot is: 524 * 525 * sethi %hi(. - .PLT0), %g1 526 * sethi %hi(addr), %g1 527 * jmp %g1+%lo(addr) 528 * nop 529 * nop 530 * nop 531 * nop 532 * nop 533 * 534 */ 535 where[2] = JMP | LOVAL(target); 536 flush(where, 8); 537 where[1] = SETHI | HIVAL(target, 10); 538 flush(where, 4); 539 } else if (target <= 0 && target > -(1L<<32)) { |
540 /* | 540 /* |
541 * We're withing 32-bits of address -1. 542 * 543 * The resulting code in the jump slot is: 544 * 545 * sethi %hi(. - .PLT0), %g1 546 * sethi %hix(addr), %g1 547 * xor %g1, %lox(addr), %g1 548 * jmp %g1 --- 5 unchanged lines hidden (view full) --- 554 */ 555 where[3] = JMP; 556 flush(where, 12); 557 where[2] = XOR | ((~target) & 0x00001fff); 558 flush(where, 8); 559 where[1] = SETHI | HIVAL(~target, 10); 560 flush(where, 4); 561 } else if (offset <= (1L<<32) && offset >= -((1L<<32) - 4)) { | 541 * We're withing 32-bits of address -1. 542 * 543 * The resulting code in the jump slot is: 544 * 545 * sethi %hi(. - .PLT0), %g1 546 * sethi %hix(addr), %g1 547 * xor %g1, %lox(addr), %g1 548 * jmp %g1 --- 5 unchanged lines hidden (view full) --- 554 */ 555 where[3] = JMP; 556 flush(where, 12); 557 where[2] = XOR | ((~target) & 0x00001fff); 558 flush(where, 8); 559 where[1] = SETHI | HIVAL(~target, 10); 560 flush(where, 4); 561 } else if (offset <= (1L<<32) && offset >= -((1L<<32) - 4)) { |
562 /* | 562 /* |
563 * We're withing 32-bits -- we can use a direct call 564 * insn 565 * 566 * The resulting code in the jump slot is: 567 * 568 * sethi %hi(. - .PLT0), %g1 569 * mov %o7, %g1 570 * call (.+offset) --- 6 unchanged lines hidden (view full) --- 577 */ 578 where[3] = MOV17; 579 flush(where, 12); 580 where[2] = CALL | ((offset >> 4) & 0x3fffffff); 581 flush(where, 8); 582 where[1] = MOV71; 583 flush(where, 4); 584 } else if (offset >= 0 && offset < (1L<<44)) { | 563 * We're withing 32-bits -- we can use a direct call 564 * insn 565 * 566 * The resulting code in the jump slot is: 567 * 568 * sethi %hi(. - .PLT0), %g1 569 * mov %o7, %g1 570 * call (.+offset) --- 6 unchanged lines hidden (view full) --- 577 */ 578 where[3] = MOV17; 579 flush(where, 12); 580 where[2] = CALL | ((offset >> 4) & 0x3fffffff); 581 flush(where, 8); 582 where[1] = MOV71; 583 flush(where, 4); 584 } else if (offset >= 0 && offset < (1L<<44)) { |
585 /* | 585 /* |
586 * We're withing 44 bits. We can generate this pattern: 587 * 588 * The resulting code in the jump slot is: 589 * 590 * sethi %hi(. - .PLT0), %g1 591 * sethi %h44(addr), %g1 592 * or %g1, %m44(addr), %g1 | 586 * We're withing 44 bits. We can generate this pattern: 587 * 588 * The resulting code in the jump slot is: 589 * 590 * sethi %hi(. - .PLT0), %g1 591 * sethi %h44(addr), %g1 592 * or %g1, %m44(addr), %g1 |
593 * sllx %g1, 12, %g1 594 * jmp %g1+%l44(addr) | 593 * sllx %g1, 12, %g1 594 * jmp %g1+%l44(addr) |
595 * nop 596 * nop 597 * nop 598 * 599 */ 600 where[4] = JMP | LOVAL(offset); 601 flush(where, 16); 602 where[3] = SLLX | 12; 603 flush(where, 12); 604 where[2] = OR | (((offset) >> 12) & 0x00001fff); 605 flush(where, 8); 606 where[1] = SETHI | HIVAL(offset, 22); 607 flush(where, 4); 608 } else if (offset < 0 && offset > -(1L<<44)) { | 595 * nop 596 * nop 597 * nop 598 * 599 */ 600 where[4] = JMP | LOVAL(offset); 601 flush(where, 16); 602 where[3] = SLLX | 12; 603 flush(where, 12); 604 where[2] = OR | (((offset) >> 12) & 0x00001fff); 605 flush(where, 8); 606 where[1] = SETHI | HIVAL(offset, 22); 607 flush(where, 4); 608 } else if (offset < 0 && offset > -(1L<<44)) { |
609 /* | 609 /* |
610 * We're withing 44 bits. We can generate this pattern: 611 * 612 * The resulting code in the jump slot is: 613 * 614 * sethi %hi(. - .PLT0), %g1 615 * sethi %h44(-addr), %g1 616 * xor %g1, %m44(-addr), %g1 | 610 * We're withing 44 bits. We can generate this pattern: 611 * 612 * The resulting code in the jump slot is: 613 * 614 * sethi %hi(. - .PLT0), %g1 615 * sethi %h44(-addr), %g1 616 * xor %g1, %m44(-addr), %g1 |
617 * sllx %g1, 12, %g1 618 * jmp %g1+%l44(addr) | 617 * sllx %g1, 12, %g1 618 * jmp %g1+%l44(addr) |
619 * nop 620 * nop 621 * nop 622 * 623 */ 624 where[4] = JMP | LOVAL(offset); 625 flush(where, 16); 626 where[3] = SLLX | 12; 627 flush(where, 12); 628 where[2] = XOR | (((~offset) >> 12) & 0x00001fff); 629 flush(where, 8); 630 where[1] = SETHI | HIVAL(~offset, 22); 631 flush(where, 4); 632 } else { | 619 * nop 620 * nop 621 * nop 622 * 623 */ 624 where[4] = JMP | LOVAL(offset); 625 flush(where, 16); 626 where[3] = SLLX | 12; 627 flush(where, 12); 628 where[2] = XOR | (((~offset) >> 12) & 0x00001fff); 629 flush(where, 8); 630 where[1] = SETHI | HIVAL(~offset, 22); 631 flush(where, 4); 632 } else { |
633 /* | 633 /* |
634 * We need to load all 64-bits 635 * 636 * The resulting code in the jump slot is: 637 * 638 * sethi %hi(. - .PLT0), %g1 639 * sethi %hh(addr), %g1 640 * sethi %lm(addr), %g5 641 * or %g1, %hm(addr), %g1 --- 78 unchanged lines hidden --- | 634 * We need to load all 64-bits 635 * 636 * The resulting code in the jump slot is: 637 * 638 * sethi %hi(. - .PLT0), %g1 639 * sethi %hh(addr), %g1 640 * sethi %lm(addr), %g5 641 * or %g1, %hm(addr), %g1 --- 78 unchanged lines hidden --- |