Module Name: src
Committed By: matt
Date: Thu Feb 10 02:28:20 UTC 2011
Modified Files:
src/libexec/ld.elf_so/arch/powerpc: ppc_reloc.c rtld_start.S
Log Message:
Fix problem with bss-plt objects which a reloc index, not offset.
(secure-plt uses an offset (index*sizeof(rela), bss-plt uses an index)
secure-plt will now take the offset and divide by 12 for an index.
To generate a diff of this commit:
cvs rdiff -u -r1.46 -r1.47 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
cvs rdiff -u -r1.14 -r1.15 src/libexec/ld.elf_so/arch/powerpc/rtld_start.S
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.46 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.47
--- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.46 Sun Jan 16 01:22:29 2011
+++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Thu Feb 10 02:28:20 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: ppc_reloc.c,v 1.46 2011/01/16 01:22:29 matt Exp $ */
+/* $NetBSD: ppc_reloc.c,v 1.47 2011/02/10 02:28:20 matt Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: ppc_reloc.c,v 1.46 2011/01/16 01:22:29 matt Exp $");
+__RCSID("$NetBSD: ppc_reloc.c,v 1.47 2011/02/10 02:28:20 matt Exp $");
#endif /* not lint */
#include <stdarg.h>
@@ -82,6 +82,9 @@
if (obj->gotptr != NULL) {
obj->gotptr[1] = (Elf_Addr) _rtld_bind_secureplt_start;
obj->gotptr[2] = (Elf_Addr) obj;
+ dbg(("obj %s secure-plt gotptr=%p start=%p obj=%p",
+ obj->path, obj->gotptr,
+ (void *) obj->gotptr[1], (void *) obj->gotptr[2]));
} else {
Elf_Word *pltcall, *pltresolve;
Elf_Word *jmptab;
@@ -91,6 +94,10 @@
if (N > 8192)
N += N-8192;
+ dbg(("obj %s bss-plt pltgot=%p jmptab=%u start=%p obj=%p",
+ obj->path, obj->pltgot, 18 + N * 2,
+ _rtld_bind_bssplt_start, obj));
+
pltcall = obj->pltgot;
jmptab = pltcall + 18 + N * 2;
@@ -343,7 +350,7 @@
caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
- const Elf_Rela *rela = (const void *)((const char *)obj->pltrela + reloff);
+ const Elf_Rela *rela = obj->pltrela + reloff;
Elf_Addr new_value;
int err;
Index: src/libexec/ld.elf_so/arch/powerpc/rtld_start.S
diff -u src/libexec/ld.elf_so/arch/powerpc/rtld_start.S:1.14 src/libexec/ld.elf_so/arch/powerpc/rtld_start.S:1.15
--- src/libexec/ld.elf_so/arch/powerpc/rtld_start.S:1.14 Sun Jan 16 01:22:29 2011
+++ src/libexec/ld.elf_so/arch/powerpc/rtld_start.S Thu Feb 10 02:28:20 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld_start.S,v 1.14 2011/01/16 01:22:29 matt Exp $ */
+/* $NetBSD: rtld_start.S,v 1.15 2011/02/10 02:28:20 matt Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
@@ -84,14 +84,26 @@
* bss-plt expects %r11 to be index of the rela entry.
* So for bss-plt, we multiply the index by 12 to get the offset.
*/
-ENTRY_NOPROFILE(_rtld_bind_bssplt_start)
- slwi %r11,%r11,2
- add %r0,%r11,%r11
- add %r11,%r11,%r0
ENTRY_NOPROFILE(_rtld_bind_secureplt_start)
stwu %r1,-160(%r1)
+ stw %r0,20(%r1)
+
+ /*
+ * Instead of division which is costly we will use multiplicative
+ * inverse. a / n = ((a * inv(n)) >> 32)
+ * where inv(n) = (0x100000000 + n - 1) / n
+ */
+ mr %r0,%r11
+ lis %r11,0x10000000b/12@h # load multiplicative inverse of 12
+ ori %r11,%r11,0x10000000b/12@l
+ mulhwu %r11,%r11,%r0 # get high half of multiplication
+
+ b 1f
+ENTRY_NOPROFILE(_rtld_bind_bssplt_start)
+ stwu %r1,-160(%r1)
stw %r0,20(%r1)
+1:
mflr %r0
stw %r0,16(%r1) # save lr
mfcr %r0