Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 Feb 2010 04:22:54 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r203539 - projects/ppc64/libexec/rtld-elf/powerpc64
Message-ID:  <201002060422.o164MsFe050540@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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@toc@ha
-	addi	%r12,%r12,_rtld_bind_start@toc@l
-	ld	%r2,8(%r12)
-	ld	%r12,0(%r12)
-        mtctr   %r12
-        bctr
-



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002060422.o164MsFe050540>