svn commit: r203539 - projects/ppc64/libexec/rtld-elf/powerpc64
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Sat Feb 6 04:22:55 UTC 2010
Author: nwhitehorn
Date: Sat Feb 6 04:22:54 2010
New Revision: 203539
URL: http://svn.freebsd.org/changeset/base/203539
Log:
Add lazy binding support for 64-bit PowerPC. The last remaining bug here
is that, despite TLS working, enabling TLS in malloc causes segfaults
for some inscrutable reason.
Modified:
projects/ppc64/libexec/rtld-elf/powerpc64/reloc.c
projects/ppc64/libexec/rtld-elf/powerpc64/rtld_machdep.h
projects/ppc64/libexec/rtld-elf/powerpc64/rtld_start.S
Modified: projects/ppc64/libexec/rtld-elf/powerpc64/reloc.c
==============================================================================
--- projects/ppc64/libexec/rtld-elf/powerpc64/reloc.c Sat Feb 6 04:20:06 2010 (r203538)
+++ projects/ppc64/libexec/rtld-elf/powerpc64/reloc.c Sat Feb 6 04:22:54 2010 (r203539)
@@ -323,19 +323,25 @@ static int
reloc_plt_object(Obj_Entry *obj, const Elf_Rela *rela)
{
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+ Elf_Addr *glink;
long reloff;
reloff = rela - obj->pltrela;
+ if (obj->priv == NULL)
+ obj->priv = malloc(obj->pltrelasize);
+ glink = obj->priv + reloff*sizeof(Elf_Addr)*2;
+
if ((reloff < 0) || (reloff >= 0x8000)) {
return (-1);
}
- dbg(" reloc_plt_object: where=%p,reloff=%lx", (void *)where, reloff);
+ dbg(" reloc_plt_object: where=%p,reloff=%lx,glink=%p", (void *)where, reloff, glink);
- memcpy(where, _rtld_powerpc64_pltresolve, sizeof(struct funcdesc));
- ((struct funcdesc *)(where))->toc = reloff;
- ((struct funcdesc *)(where))->env = (uint64_t)obj;
+ memcpy(where, _rtld_bind_start, sizeof(struct funcdesc));
+ ((struct funcdesc *)(where))->env = (Elf_Addr)glink;
+ *(glink++) = (Elf_Addr)obj;
+ *(glink++) = reloff*sizeof(Elf_Rela);
return (0);
}
@@ -351,7 +357,6 @@ reloc_plt(Obj_Entry *obj)
const Elf_Rela *rela;
if (obj->pltrelasize != 0) {
-
relalim = (const Elf_Rela *)((char *)obj->pltrela +
obj->pltrelasize);
for (rela = obj->pltrela; rela < relalim; rela++) {
@@ -449,21 +454,6 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
void
init_pltgot(Obj_Entry *obj)
{
-#if 0
- struct funcdesc *pltcall;
- //int N = obj->pltrelasize / sizeof(Elf_Rela);
-
- pltcall = (struct funcdesc *)obj->pltgot;
-
- if (pltcall == NULL) {
- return;
- }
-
- /*
- * Copy the function description into the PLT0 slot
- */
- memcpy(pltcall, _rtld_powerpc64_pltresolve, sizeof(*pltcall));
-#endif
}
void
Modified: projects/ppc64/libexec/rtld-elf/powerpc64/rtld_machdep.h
==============================================================================
--- projects/ppc64/libexec/rtld-elf/powerpc64/rtld_machdep.h Sat Feb 6 04:20:06 2010 (r203538)
+++ projects/ppc64/libexec/rtld-elf/powerpc64/rtld_machdep.h Sat Feb 6 04:22:54 2010 (r203539)
@@ -54,12 +54,6 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where,
void _rtld_bind_start(void);
/*
- * PLT functions. Not really correct prototypes, but the
- * symbol values are needed.
- */
-void _rtld_powerpc64_pltresolve(void);
-
-/*
* TLS
*/
Modified: projects/ppc64/libexec/rtld-elf/powerpc64/rtld_start.S
==============================================================================
--- projects/ppc64/libexec/rtld-elf/powerpc64/rtld_start.S Sat Feb 6 04:20:06 2010 (r203538)
+++ projects/ppc64/libexec/rtld-elf/powerpc64/rtld_start.S Sat Feb 6 04:22:54 2010 (r203539)
@@ -105,56 +105,57 @@ _ENTRY(_rtld_start)
/*
* _rtld_bind_start()
*
- * Call into the MI binder. This routine is reached via the PLT call cell,
- * and then _rtld_powerpc_pltresolve().
- * On entry, %r13 contains the index of the PLT cell, and %r12 contains
- * a pointer to the ELF object for the file.
- * Save all registers, call into the binder to resolve and fixup the external
+ * Call into the MI binder. This routine is reached via the PLT call cell
+ * On entry, %r11 contains a pointer to the (object, relocation) tuple.
+ *
+ * Save all registers, call into the binder to resolve and fixup the external
* routine, and then transfer to the external routine on return.
*/
.globl _rtld_bind
_ENTRY(_rtld_bind_start)
- stwu %r1,-160(%r1) # stack space for 29 regs + r0/lr/cr
- stw %r0,20(%r1) # save r0
mflr %r0
- stw %r0,16(%r1) # save lr
+ std %r0,16(%r1) # save lr
mfcr %r0
- stw %r0,12(%r1) # save cr
- stmw %r3,24(%r1) # save r3-r31
+ std %r0,8(%r1) # save cr
+
+ stdu %r1,-48-9*8(%r1) # stack space for 8 regs + header
+ std %r3,48+0*8(%r1) # save r3-r31
+ std %r4,48+1*8(%r1)
+ std %r5,48+2*8(%r1)
+ std %r6,48+3*8(%r1)
+ std %r7,48+4*8(%r1)
+ std %r8,48+5*8(%r1)
+ std %r9,48+6*8(%r1)
+ std %r10,48+7*8(%r1)
+ std %r12,48+8*8(%r1)
- mr %r3,%r12 # obj
- mulli %r4,%r11,12 # rela index * sizeof(Elf_Rela)
+ ld %r3,0(%r11)
+ ld %r4,8(%r11)
bl ._rtld_bind # target addr = _rtld_bind(obj, reloff)
nop
+
+ ld %r2,8(%r3)
+ ld %r11,16(%r3)
+ ld %r3,0(%r3)
mtctr %r3 # move absolute target addr into ctr
- lmw %r3,24(%r1) # restore r3-r31
- lwz %r0,12(%r1) # restore cr
+ ld %r3,48+0*8(%r1) # restore r3-r31
+ ld %r4,48+1*8(%r1)
+ ld %r5,48+2*8(%r1)
+ ld %r6,48+3*8(%r1)
+ ld %r7,48+4*8(%r1)
+ ld %r8,48+5*8(%r1)
+ ld %r9,48+6*8(%r1)
+ ld %r10,48+7*8(%r1)
+ ld %r12,48+8*8(%r1)
+
+ addi %r1,%r1,48+9*8 # restore stack
+
+ ld %r0,8(%r1) # restore cr
mtcr %r0
- lwz %r0,16(%r1) # restore lr
+ ld %r0,16(%r1) # restore lr
mtlr %r0
- lwz %r0,20(%r1) # restore r0
- addi %r1,%r1,160 # restore stack
bctr # jump to target
-
-/*
- * _rtld_powerpc64_pltresolve()
- *
- * The first time an external routine is called, the PLT slot will
- * set up %r2 to the offset of the slot, and will jump to this routine.
- * The ELF object is in %r11, and _rtld_bind_start is called
- * to complete the binding.
- */
-_ENTRY(_rtld_powerpc64_pltresolve)
- mr %r13,%r2
- ld %r2,40(%r1)
- addis %r12,%r2,_rtld_bind_start at toc@ha
- addi %r12,%r12,_rtld_bind_start at toc@l
- ld %r2,8(%r12)
- ld %r12,0(%r12)
- mtctr %r12
- bctr
-
More information about the svn-src-projects
mailing list