Module Name:    src
Committed By:   matt
Date:           Thu Mar  6 19:19:40 UTC 2014

Modified Files:
        src/libexec/ld.elf_so: headers.c rtld.h
        src/libexec/ld.elf_so/arch/powerpc: ppc_reloc.c rtld_start64.S

Log Message:
More PPC64 changes.
Nothing to do for lazy bindings.
Record DT_PPC64_GLINK and make _rtld_bind return it.
When resolving a JMP_SLOT, copy the source function descriptor into the PLTGOT


To generate a diff of this commit:
cvs rdiff -u -r1.52 -r1.53 src/libexec/ld.elf_so/headers.c
cvs rdiff -u -r1.116 -r1.117 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.50 -r1.51 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
cvs rdiff -u -r1.1 -r1.2 src/libexec/ld.elf_so/arch/powerpc/rtld_start64.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/headers.c
diff -u src/libexec/ld.elf_so/headers.c:1.52 src/libexec/ld.elf_so/headers.c:1.53
--- src/libexec/ld.elf_so/headers.c:1.52	Sat Aug  3 13:17:05 2013
+++ src/libexec/ld.elf_so/headers.c	Thu Mar  6 19:19:40 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: headers.c,v 1.52 2013/08/03 13:17:05 skrll Exp $	 */
+/*	$NetBSD: headers.c,v 1.53 2014/03/06 19:19:40 matt Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: headers.c,v 1.52 2013/08/03 13:17:05 skrll Exp $");
+__RCSID("$NetBSD: headers.c,v 1.53 2014/03/06 19:19:40 matt Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -298,10 +298,16 @@ _rtld_digest_dynamic(const char *execnam
 			break;
 #endif
 #ifdef __powerpc__
+#ifdef _LP64
+		case DT_PPC64_GLINK:
+			obj->glink = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr);
+			break;
+#else
 		case DT_PPC_GOT:
 			obj->gotptr = (Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
 			break;
 #endif
+#endif
 		case DT_FLAGS_1:
 			obj->z_now =
 			    ((dynp->d_un.d_val & DF_1_BIND_NOW) != 0);

Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.116 src/libexec/ld.elf_so/rtld.h:1.117
--- src/libexec/ld.elf_so/rtld.h:1.116	Thu May  9 15:38:14 2013
+++ src/libexec/ld.elf_so/rtld.h	Thu Mar  6 19:19:40 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.h,v 1.116 2013/05/09 15:38:14 christos Exp $	 */
+/*	$NetBSD: rtld.h,v 1.117 2014/03/06 19:19:40 matt Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -259,8 +259,12 @@ typedef struct Struct_Obj_Entry {
 						  * object we know about. */
 
 #ifdef __powerpc__
+#ifdef _LP64
+	Elf_Addr	glink;		/* global linkage */
+#else
 	Elf_Addr       *gotptr;		/* GOT table (secure-plt only) */
 #endif
+#endif
 
 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
 	/* Thread Local Storage support for this module */

Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.50 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.51
--- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.50	Thu Mar  6 09:34:07 2014
+++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c	Thu Mar  6 19:19:40 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ppc_reloc.c,v 1.50 2014/03/06 09:34:07 matt Exp $	*/
+/*	$NetBSD: ppc_reloc.c,v 1.51 2014/03/06 19:19:40 matt Exp $	*/
 
 /*-
  * Copyright (C) 1998	Tsubai Masanari
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ppc_reloc.c,v 1.50 2014/03/06 09:34:07 matt Exp $");
+__RCSID("$NetBSD: ppc_reloc.c,v 1.51 2014/03/06 19:19:40 matt Exp $");
 #endif /* not lint */
 
 #include <stdarg.h>
@@ -70,8 +70,8 @@ extern const uint64_t _rtld_bind_start[3
 void _rtld_bind_bssplt_start(void);
 void _rtld_bind_secureplt_start(void);
 #endif
+Elf_Addr _rtld_bind(const Obj_Entry *, Elf_Word);
 void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
-caddr_t _rtld_bind(const Obj_Entry *, Elf_Word);
 static int _rtld_relocate_plt_object(const Obj_Entry *,
     const Elf_Rela *, int, Elf_Addr *);
 
@@ -297,9 +297,13 @@ _rtld_relocate_nonplt_objects(Obj_Entry 
 int
 _rtld_relocate_plt_lazy(const Obj_Entry *obj)
 {
-#ifndef _LP64
+#ifdef _LP64
+	/*
+	 * For PowerPC64, the plt stubs handle an empty function descriptor
+	 * so there's nothing to do.
+	 */
+#else
 	Elf_Addr * const pltresolve = obj->pltgot + 8;
-#endif
 	const Elf_Rela *rela;
 	int reloff;
 
@@ -310,12 +314,6 @@ _rtld_relocate_plt_lazy(const Obj_Entry 
 
 		assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
 
-#ifdef _LP64
-		/*
-		 * For now, simply treat then as relative.
-		 */
-		*where += (Elf_Addr)obj->relocbase;
-#else
 		if (obj->gotptr != NULL) {
 			/*
 			 * For now, simply treat then as relative.
@@ -345,8 +343,8 @@ _rtld_relocate_plt_lazy(const Obj_Entry 
 			 */
 			/* __syncicache(where - 3, 12); */
 		}
-#endif
 	}
+#endif /* !_LP64 */
 
 	return 0;
 }
@@ -358,7 +356,6 @@ _rtld_relocate_plt_object(const Obj_Entr
 	Elf_Addr value;
 	const Elf_Sym *def;
 	const Obj_Entry *defobj;
-	int distance;
 	unsigned long info = rela->r_info;
 
 	assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT));
@@ -370,19 +367,22 @@ _rtld_relocate_plt_object(const Obj_Entr
 		return 0;
 
 	value = (Elf_Addr)(defobj->relocbase + def->st_value);
-	distance = value - (Elf_Addr)where;
 	rdbg(("bind now/fixup in %s --> new=%p", 
 	    defobj->strtab + def->st_name, (void *)value));
 
 #ifdef _LP64
 	/*
-	 * For PowerPC64 we simply replace the entry in the PLTGOT with the
-	 * address of the routine.
+	 * For PowerPC64 we simply replace the function descriptor in the
+	 * PLTGOT with the one from source object.
 	 */
 	assert(where >= (Elf_Word *)obj->pltgot);
 	assert(where < (Elf_Word *)obj->pltgot + (obj->pltrelalim - obj->pltrela));
-	*where = value;
+	const Elf_Addr * const fdesc = (Elf_Addr *) value;
+	where[0] = fdesc[0];
+	where[1] = fdesc[1];
+	where[2] = fdesc[2];
 #else
+	ptrdiff_t distance = value - (Elf_Addr)where;
 	if (obj->gotptr != NULL) {
 		/*
 		 * For Secure-PLT we simply replace the entry in GOT with the
@@ -391,7 +391,7 @@ _rtld_relocate_plt_object(const Obj_Entr
 		assert(where >= (Elf_Word *)obj->pltgot);
 		assert(where < (Elf_Word *)obj->pltgot + (obj->pltrelalim - obj->pltrela));
 		*where = value;
-	} else if (abs(distance) < 32*1024*1024) {	/* inside 32MB? */
+	} else if (labs(distance) < 32*1024*1024) {	/* inside 32MB? */
 		/* b	value	# branch directly */
 		*where = 0x48000000 | (distance & 0x03fffffc);
 		__syncicache(where, 4);
@@ -440,7 +440,7 @@ _rtld_relocate_plt_object(const Obj_Entr
 	return 0;
 }
 
-caddr_t
+Elf_Addr
 _rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
 {
 	const Elf_Rela *rela = obj->pltrela + reloff;
@@ -455,7 +455,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
 		_rtld_die();
 	_rtld_shared_exit();
 
-	return (caddr_t)new_value;
+#ifdef _LP64
+	return obj->glink;
+#else
+	return new_value;
+#endif
 }
 
 int

Index: src/libexec/ld.elf_so/arch/powerpc/rtld_start64.S
diff -u src/libexec/ld.elf_so/arch/powerpc/rtld_start64.S:1.1 src/libexec/ld.elf_so/arch/powerpc/rtld_start64.S:1.2
--- src/libexec/ld.elf_so/arch/powerpc/rtld_start64.S:1.1	Thu Mar  6 07:47:19 2014
+++ src/libexec/ld.elf_so/arch/powerpc/rtld_start64.S	Thu Mar  6 19:19:40 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld_start64.S,v 1.1 2014/03/06 07:47:19 matt Exp $	*/
+/*	$NetBSD: rtld_start64.S,v 1.2 2014/03/06 19:19:40 matt Exp $	*/
 
 /*-
  * Copyright (C) 1998	Tsubai Masanari
@@ -107,8 +107,7 @@ ENTRY_NOPROFILE(_rtld_bind_start)
 	CALL(_rtld_bind)		// _rtld_bind(obj, reloff)
 
 	mtctr	%r3
-	ld	%r2,8(%r31)		// load TOC for function
-	ld	%r11,16(%r31)		// load env ptr for function.
+	mr	%r12,%r31		// restore r12
 
 	ld	%r0,8(%r1)		// get saved CR
 	mtcr	%r0			// restore it

Reply via email to