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

Reply via email to