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