Module Name:    src
Committed By:   joerg
Date:           Fri Mar  9 20:19:11 UTC 2018

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

Log Message:
Like Sparc, PowerPC can use IRELATIVE relocations in non-PLT sections.


To generate a diff of this commit:
cvs rdiff -u -r1.190 -r1.191 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.131 -r1.132 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.55 -r1.56 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c

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/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.190 src/libexec/ld.elf_so/rtld.c:1.191
--- src/libexec/ld.elf_so/rtld.c:1.190	Sun Feb 11 18:58:44 2018
+++ src/libexec/ld.elf_so/rtld.c	Fri Mar  9 20:19:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.c,v 1.190 2018/02/11 18:58:44 jakllsch Exp $	 */
+/*	$NetBSD: rtld.c,v 1.191 2018/03/09 20:19:11 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.190 2018/02/11 18:58:44 jakllsch Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.191 2018/03/09 20:19:11 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -263,7 +263,7 @@ static bool
 _rtld_call_ifunc_functions(sigset_t *mask, Obj_Entry *obj, u_int cur_objgen)
 {
 	if (obj->ifunc_remaining
-#ifdef __sparc__
+#if defined(__sparc__) || defined(__powerpc__)
 	    || obj->ifunc_remaining_nonplt
 #endif
 	) {

Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.131 src/libexec/ld.elf_so/rtld.h:1.132
--- src/libexec/ld.elf_so/rtld.h:1.131	Sat Aug 12 09:03:27 2017
+++ src/libexec/ld.elf_so/rtld.h	Fri Mar  9 20:19:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.h,v 1.131 2017/08/12 09:03:27 joerg Exp $	 */
+/*	$NetBSD: rtld.h,v 1.132 2018/03/09 20:19:11 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -300,7 +300,7 @@ typedef struct Struct_Obj_Entry {
 	size_t		fini_arraysz;	/* # of entries in it */
 	/* IRELATIVE relocations */
 	size_t		ifunc_remaining;
-#ifdef __sparc__
+#if defined(__sparc__) || defined(__powerpc__)
 	/* On SPARC, the PLT variant is called JMP_IREL and counted above. */
 	size_t		ifunc_remaining_nonplt;
 #endif

Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.55 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.56
--- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.55	Thu Aug 10 19:03:26 2017
+++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c	Fri Mar  9 20:19:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ppc_reloc.c,v 1.55 2017/08/10 19:03:26 joerg Exp $	*/
+/*	$NetBSD: ppc_reloc.c,v 1.56 2018/03/09 20:19:11 joerg Exp $	*/
 
 /*-
  * Copyright (C) 1998	Tsubai Masanari
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ppc_reloc.c,v 1.55 2017/08/10 19:03:26 joerg Exp $");
+__RCSID("$NetBSD: ppc_reloc.c,v 1.56 2018/03/09 20:19:11 joerg Exp $");
 #endif /* not lint */
 
 #include <stdarg.h>
@@ -285,6 +285,14 @@ _rtld_relocate_nonplt_objects(Obj_Entry 
 			    obj->path, (void *)*where, defobj->path));
 			break;
 
+		case R_TYPE(IRELATIVE):
+			/* IFUNC relocations are handled in _rtld_call_ifunc */
+			if (obj->ifunc_remaining_nonplt == 0) {
+				obj->ifunc_remaining_nonplt =
+				    rela - obj->rela + 1;
+			}
+			break;
+
 		default:
 			rdbg(("sym = %lu, type = %lu, offset = %p, "
 			    "addend = %p, contents = %p, symbol = %s",
@@ -314,10 +322,9 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 #else
 	Elf_Addr * const pltresolve = obj->pltgot + 8;
 	const Elf_Rela *rela;
-	int reloff;
 
-	rela = obj->pltrelalim;
-	for (reloff = rela - obj->pltrela; rela-- > obj->pltrela; --reloff) {
+	for (rela = obj->pltrelalim; rela-- > obj->pltrela;) {
+		size_t reloff = rela - obj->pltrela;
 		Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
 
 		assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JUMP_SLOT) ||
@@ -383,6 +390,19 @@ _rtld_call_ifunc(Obj_Entry *obj, sigset_
 				*where = target;
 		}
 	}
+
+	while (obj->ifunc_remaining_nonplt > 0 && _rtld_objgen == cur_objgen) {
+		rela = obj->relalim - --obj->ifunc_remaining_nonplt;
+		if (ELF_R_TYPE(rela->r_info) != R_TYPE(IRELATIVE))
+			continue;
+		where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+		target = (Elf_Addr)(obj->relocbase + rela->r_addend);
+		_rtld_exclusive_exit(mask);
+		target = _rtld_resolve_ifunc2(obj, target);
+		_rtld_exclusive_enter(mask);
+		if (*where != target)
+			*where = target;
+	}
 }
 
 static int

Reply via email to