summaryrefslogtreecommitdiff
path: root/libexec/ld.so
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2008-07-16 20:33:43 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2008-07-16 20:33:43 +0000
commit22b6dda3a25dd576d5b851c02d4b11a72e48edf4 (patch)
treee2322c79e73f26cfeaca31947f9f677e2a52bec6 /libexec/ld.so
parentf4c3215d929c4f4e37ecb0c1bc54f824318df42a (diff)
Fix several of the 'large offset' PLT entries. With help from kurt.
ok kurt@
Diffstat (limited to 'libexec/ld.so')
-rw-r--r--libexec/ld.so/sparc64/rtld_machine.c87
1 files changed, 48 insertions, 39 deletions
diff --git a/libexec/ld.so/sparc64/rtld_machine.c b/libexec/ld.so/sparc64/rtld_machine.c
index c1a3c2fa7cc..4fa524db1d4 100644
--- a/libexec/ld.so/sparc64/rtld_machine.c
+++ b/libexec/ld.so/sparc64/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.42 2008/04/09 21:45:26 kurt Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.43 2008/07/16 20:33:42 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -356,14 +356,17 @@ resolve_failed:
#define SETHI 0x03000000 /* sethi %hi(0), %g1 */
#define JMP 0x81c06000 /* jmpl %g1+%lo(0), %g0 */
#define NOP 0x01000000 /* sethi %hi(0), %g0 */
-#define OR 0x82806000 /* or %g1, 0, %g1 */
-#define XOR 0x82c06000 /* xor %g1, 0, %g1 */
+#define OR 0x82106000 /* or %g1, 0, %g1 */
+#define ORG5 0x8a116000 /* or %g5, 0, %g5 */
+#define XOR 0x82186000 /* xor %g1, 0, %g1 */
#define MOV71 0x8283a000 /* or %o7, 0, %g1 */
#define MOV17 0x9c806000 /* or %g1, 0, %o7 */
#define CALL 0x40000000 /* call 0 */
-#define SLLX 0x8b407000 /* sllx %g1, 0, %g1 */
+#define SLLX 0x83287000 /* sllx %g1, 0, %g1 */
+#define SLLXG5 0x8b297000 /* sllx %g5, 0, %g5 */
+#define SRAX 0x83387000 /* srax %g1, 0, %g1 */
#define SETHIG5 0x0b000000 /* sethi %hi(0), %g5 */
-#define ORG5 0x82804005 /* or %g1, %g5, %g1 */
+#define ORG15 0x82804005 /* or %g1, %g5, %g1 */
/* %hi(v) with variable shift */
@@ -427,9 +430,9 @@ _dl_reloc_plt(Elf_Word *where, Elf_Addr value, Elf_RelA *rela)
*/
where[1] = BAA | ((offset >> 2) &0x3fffff);
__asm __volatile("iflush %0+4" : : "r" (where));
- } else if (value >= 0 && value < (1L<<32)) {
+ } else if (value < (1UL<<32)) {
/*
- * We're withing 32-bits of address zero.
+ * We're within 32-bits of address zero.
*
* The resulting code in the jump slot is:
*
@@ -448,9 +451,9 @@ _dl_reloc_plt(Elf_Word *where, Elf_Addr value, Elf_RelA *rela)
__asm __volatile("iflush %0+8" : : "r" (where));
__asm __volatile("iflush %0+4" : : "r" (where));
- } else if (value <= 0 && value > -(1L<<32)) {
+ } else if (value > -(1UL<<32)) {
/*
- * We're withing 32-bits of address -1.
+ * We're within 32-bits of address -1.
*
* The resulting code in the jump slot is:
*
@@ -473,7 +476,7 @@ _dl_reloc_plt(Elf_Word *where, Elf_Addr value, Elf_RelA *rela)
} else if (offset <= (1L<<32) && offset >= -((1L<<32) - 4)) {
/*
- * We're withing 32-bits -- we can use a direct call insn
+ * We're within 32-bits -- we can use a direct call insn
*
* The resulting code in the jump slot is:
*
@@ -494,51 +497,57 @@ _dl_reloc_plt(Elf_Word *where, Elf_Addr value, Elf_RelA *rela)
__asm __volatile("iflush %0+8" : : "r" (where));
__asm __volatile("iflush %0+4" : : "r" (where));
- } else if (offset >= 0 && offset < (1L<<44)) {
+ } else if (value < (1L<<42)) {
/*
- * We're withing 44 bits. We can generate this pattern:
+ * Target 42bits or smaller.
+ * We can generate this pattern:
*
* The resulting code in the jump slot is:
*
* sethi %hi(. - .PLT0), %g1
- * sethi %h44(addr), %g1
- * or %g1, %m44(addr), %g1
- * sllx %g1, 12, %g1
- * jmp %g1+%l44(addr)
+ * sethi %hi(addr >> 20), %g1
+ * or %g1, %lo(addr >> 10), %g1
+ * sllx %g1, 10, %g1
+ * jmp %g1+%lo(addr)
* nop
* nop
* nop
*
+ * this can handle addresses 0 - 0x3fffffffffc
*/
- where[4] = JMP | LOVAL(offset);
- where[3] = SLLX | 12;
- where[2] = OR | (((offset) >> 12) & 0x00001fff);
- where[1] = SETHI | HIVAL(offset, 22);
+ where[4] = JMP | LOVAL(value);
+ where[3] = SLLX | 10;
+ where[2] = OR | LOVAL(value >> 10);
+ where[1] = SETHI | HIVAL(value, 20);
__asm __volatile("iflush %0+16" : : "r" (where));
__asm __volatile("iflush %0+12" : : "r" (where));
__asm __volatile("iflush %0+8" : : "r" (where));
__asm __volatile("iflush %0+4" : : "r" (where));
- } else if (offset < 0 && offset > -(1L<<44)) {
+ } else if (value > -(1UL<<41)) {
/*
- * We're withing 44 bits. We can generate this pattern:
+ * Large target >= 0xfffffe0000000000UL
+ * We can generate this pattern:
*
* The resulting code in the jump slot is:
*
* sethi %hi(. - .PLT0), %g1
- * sethi %h44(-addr), %g1
- * xor %g1, %m44(-addr), %g1
- * sllx %g1, 12, %g1
- * jmp %g1+%l44(addr)
+ * sethi %hi(addr >> 20), %g1
+ * or %g1, %lo(addr >> 10), %g1
+ * sllx %g1, 32, %g1
+ * srax %g1, 22, %g1
+ * jmp %g1+%lo(addr)
* nop
* nop
* nop
*
*/
- where[4] = JMP | LOVAL(offset);
- where[3] = SLLX | 12;
- where[2] = XOR | (((~offset) >> 12) & 0x00001fff);
- where[1] = SETHI | HIVAL(~offset, 22);
+ where[5] = JMP | LOVAL(value);
+ where[4] = SRAX | 22;
+ where[3] = SLLX | 32;
+ where[2] = OR | LOVAL(value >> 10);
+ where[1] = SETHI | HIVAL(value, 20);
+
__asm __volatile("iflush %0+16" : : "r" (where));
__asm __volatile("iflush %0+12" : : "r" (where));
__asm __volatile("iflush %0+8" : : "r" (where));
@@ -551,21 +560,21 @@ _dl_reloc_plt(Elf_Word *where, Elf_Addr value, Elf_RelA *rela)
* The resulting code in the jump slot is:
*
* sethi %hi(. - .PLT0), %g1
- * sethi %hh(addr), %g1
- * sethi %lm(addr), %g5
- * or %g1, %hm(addr), %g1
- * sllx %g1, 32, %g1
+ * sethi %hi(addr >> 42), %g5
+ * sethi %hi(addr >> 10), %g1
+ * or %g1, %lo(addr >> 32), %g5
+ * sllx %g5, 32, %g5
* or %g1, %g5, %g1
* jmp %g1+%lo(addr)
* nop
*
*/
where[6] = JMP | LOVAL(value);
- where[5] = ORG5;
- where[4] = SLLX | 12;
- where[3] = OR | LOVAL((value) >> 32);
- where[2] = SETHIG5 | HIVAL(value, 10);
- where[1] = SETHI | HIVAL(value, 42);
+ where[5] = ORG15;
+ where[4] = SLLXG5 | 32;
+ where[3] = ORG5 | LOVAL(value >> 32);
+ where[2] = SETHI | HIVAL(value, 10);
+ where[1] = SETHIG5 | HIVAL(value, 42);
__asm __volatile("iflush %0+24" : : "r" (where));
__asm __volatile("iflush %0+20" : : "r" (where));
__asm __volatile("iflush %0+16" : : "r" (where));