Deleted Added
full compact
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 ---