Module Name:    src
Committed By:   joerg
Date:           Tue Apr  3 21:10:28 UTC 2018

Modified Files:
        src/libexec/ld.elf_so: reloc.c rtld.c rtld.h
        src/libexec/ld.elf_so/arch/arm: Makefile.inc mdreloc.c
        src/libexec/ld.elf_so/arch/i386: Makefile.inc mdreloc.c
        src/libexec/ld.elf_so/arch/powerpc: Makefile.inc ppc_reloc.c
        src/libexec/ld.elf_so/arch/sparc: Makefile.inc mdreloc.c
        src/libexec/ld.elf_so/arch/sparc64: Makefile.inc mdreloc.c
        src/libexec/ld.elf_so/arch/x86_64: Makefile.inc mdreloc.c

Log Message:
Rework ifunc support to address a number of short comings:
- Move to a shared _rtld_call_ifunc for rel and rela architectures
- Architectures using rel format must patch IRELATIVE non-PLT
  relocations like RELATIVE in additition to the later ifunc handling
- Consistently record the delta to the end of the relocation group for
  non-PLT IRELATIVE relocations

Hidden ifunc is now supported on all ifunc platforms, even when using
-fno-plt. The combination of -fno-plt and relro is broken due to
incorrect GNU ld output though.


To generate a diff of this commit:
cvs rdiff -u -r1.111 -r1.112 src/libexec/ld.elf_so/reloc.c
cvs rdiff -u -r1.191 -r1.192 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.132 -r1.133 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.20 -r1.21 src/libexec/ld.elf_so/arch/arm/Makefile.inc
cvs rdiff -u -r1.43 -r1.44 src/libexec/ld.elf_so/arch/arm/mdreloc.c
cvs rdiff -u -r1.14 -r1.15 src/libexec/ld.elf_so/arch/i386/Makefile.inc
cvs rdiff -u -r1.40 -r1.41 src/libexec/ld.elf_so/arch/i386/mdreloc.c
cvs rdiff -u -r1.15 -r1.16 src/libexec/ld.elf_so/arch/powerpc/Makefile.inc
cvs rdiff -u -r1.56 -r1.57 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
cvs rdiff -u -r1.14 -r1.15 src/libexec/ld.elf_so/arch/sparc/Makefile.inc
cvs rdiff -u -r1.54 -r1.55 src/libexec/ld.elf_so/arch/sparc/mdreloc.c
cvs rdiff -u -r1.8 -r1.9 src/libexec/ld.elf_so/arch/sparc64/Makefile.inc
cvs rdiff -u -r1.68 -r1.69 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
cvs rdiff -u -r1.7 -r1.8 src/libexec/ld.elf_so/arch/x86_64/Makefile.inc
cvs rdiff -u -r1.46 -r1.47 src/libexec/ld.elf_so/arch/x86_64/mdreloc.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/reloc.c
diff -u src/libexec/ld.elf_so/reloc.c:1.111 src/libexec/ld.elf_so/reloc.c:1.112
--- src/libexec/ld.elf_so/reloc.c:1.111	Thu Aug 10 19:03:25 2017
+++ src/libexec/ld.elf_so/reloc.c	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: reloc.c,v 1.111 2017/08/10 19:03:25 joerg Exp $	 */
+/*	$NetBSD: reloc.c,v 1.112 2018/04/03 21:10:27 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.111 2017/08/10 19:03:25 joerg Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.112 2018/04/03 21:10:27 joerg Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -276,3 +276,93 @@ _rtld_resolve_ifunc2(const Obj_Entry *ob
 
 	return target;
 }
+
+#ifdef RTLD_COMMON_CALL_IFUNC_RELA
+#  ifdef __sparc__
+#  include <machine/elf_support.h>
+#  endif
+
+void
+_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
+{
+	const Elf_Rela *rela;
+	Elf_Addr *where;
+#ifdef __sparc__
+	Elf_Word *where2;
+#endif
+	Elf_Addr target;
+
+	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
+		rela = obj->pltrelalim - obj->ifunc_remaining--;
+#ifdef __sparc__
+#define PLT_IRELATIVE R_TYPE(JMP_IREL)
+#else
+#define PLT_IRELATIVE R_TYPE(IRELATIVE)
+#endif
+		if (ELF_R_TYPE(rela->r_info) != PLT_IRELATIVE)
+			continue;
+#ifdef __sparc__
+		where2 = (Elf_Word *)(obj->relocbase + rela->r_offset);
+#else
+		where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+#endif
+		target = (Elf_Addr)(obj->relocbase + rela->r_addend);
+		_rtld_exclusive_exit(mask);
+		target = _rtld_resolve_ifunc2(obj, target);
+		_rtld_exclusive_enter(mask);
+#ifdef __sparc__
+		sparc_write_branch(where2 + 1, (void *)target);
+#else
+		if (*where != target)
+			*where = target;
+#endif
+	}
+
+	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;
+	}
+}
+#endif
+
+#ifdef RTLD_COMMON_CALL_IFUNC_REL
+void
+_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
+{
+	const Elf_Rel *rel;
+	Elf_Addr *where, target;
+
+	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
+		rel = obj->pltrellim - obj->ifunc_remaining;
+		--obj->ifunc_remaining;
+		if (ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE)) {
+			where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+			_rtld_exclusive_exit(mask);
+			target = _rtld_resolve_ifunc2(obj, *where);
+			_rtld_exclusive_enter(mask);
+			if (*where != target)
+				*where = target;
+		}
+	}
+
+	while (obj->ifunc_remaining_nonplt > 0 && _rtld_objgen == cur_objgen) {
+		rel = obj->rellim - obj->ifunc_remaining_nonplt--;
+		if (ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE)) {
+			where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+			_rtld_exclusive_exit(mask);
+			target = _rtld_resolve_ifunc2(obj, *where);
+			_rtld_exclusive_enter(mask);
+			if (*where != target)
+				*where = target;
+		}
+	}
+}
+#endif

Index: src/libexec/ld.elf_so/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.191 src/libexec/ld.elf_so/rtld.c:1.192
--- src/libexec/ld.elf_so/rtld.c:1.191	Fri Mar  9 20:19:11 2018
+++ src/libexec/ld.elf_so/rtld.c	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.c,v 1.191 2018/03/09 20:19:11 joerg Exp $	 */
+/*	$NetBSD: rtld.c,v 1.192 2018/04/03 21:10:27 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.191 2018/03/09 20:19:11 joerg Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.192 2018/04/03 21:10:27 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
-#if defined(__sparc__) || defined(__powerpc__)
+#if defined(IFUNC_NONPLT)
 	    || obj->ifunc_remaining_nonplt
 #endif
 	) {

Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.132 src/libexec/ld.elf_so/rtld.h:1.133
--- src/libexec/ld.elf_so/rtld.h:1.132	Fri Mar  9 20:19:11 2018
+++ src/libexec/ld.elf_so/rtld.h	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.h,v 1.132 2018/03/09 20:19:11 joerg Exp $	 */
+/*	$NetBSD: rtld.h,v 1.133 2018/04/03 21:10:27 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -300,7 +300,9 @@ typedef struct Struct_Obj_Entry {
 	size_t		fini_arraysz;	/* # of entries in it */
 	/* IRELATIVE relocations */
 	size_t		ifunc_remaining;
-#if defined(__sparc__) || defined(__powerpc__)
+#if defined(__sparc__) || defined(__powerpc__) || defined(__arm__) || \
+    defined(__i386__) || defined(__x86_64__)
+#define IFUNC_NONPLT
 	/* 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/arm/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/arm/Makefile.inc:1.20 src/libexec/ld.elf_so/arch/arm/Makefile.inc:1.21
--- src/libexec/ld.elf_so/arch/arm/Makefile.inc:1.20	Tue Sep 10 16:35:10 2013
+++ src/libexec/ld.elf_so/arch/arm/Makefile.inc	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.20 2013/09/10 16:35:10 matt Exp $
+#	$NetBSD: Makefile.inc,v 1.21 2018/04/03 21:10:27 joerg Exp $
 
 SRCS+=		rtld_start.S mdreloc.c
 #CPUFLAGS.rtld_start.S+=	-marm
@@ -7,6 +7,7 @@ SRCS+=		rtld_start.S mdreloc.c
 CPPFLAGS+=	-fpic
 
 CPPFLAGS+=	-DELFSIZE=32
+CPPFLAGS+=	-DRTLD_COMMON_CALL_IFUNC_REL
 .if !empty(LDELFSO_MACHINE_ARCH:Mearm*)
 CPPFLAGS+=	-DHAVE_INITFINI_ARRAY
 CPPFLAGS+=	-DELF_NOTE_MARCH_DESC=\"${LDELFSO_MACHINE_ARCH}\"

Index: src/libexec/ld.elf_so/arch/arm/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.43 src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.44
--- src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.43	Mon Nov  6 21:16:04 2017
+++ src/libexec/ld.elf_so/arch/arm/mdreloc.c	Tue Apr  3 21:10:27 2018
@@ -1,8 +1,8 @@
-/*	$NetBSD: mdreloc.c,v 1.43 2017/11/06 21:16:04 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.44 2018/04/03 21:10:27 joerg Exp $	*/
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.43 2017/11/06 21:16:04 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.44 2018/04/03 21:10:27 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -167,6 +167,12 @@ _rtld_relocate_nonplt_objects(Obj_Entry 
 			    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 = obj->rellim - rel;
+			/* FALL-THROUGH */
+
 		case R_TYPE(RELATIVE):	/* word32 B + A */
 			if (__predict_true(RELOC_ALIGNED_P(where))) {
 				tmp = *where + (Elf_Addr)obj->relocbase;
@@ -274,26 +280,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 	return 0;
 }
 
-void
-_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
-{
-	const Elf_Rel *rel;
-	Elf_Addr *where, target;
-
-	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
-		rel = obj->pltrellim - obj->ifunc_remaining;
-		--obj->ifunc_remaining;
-		if (ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE)) {
-			where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
-			_rtld_exclusive_exit(mask);
-			target = _rtld_resolve_ifunc2(obj, *where);
-			_rtld_exclusive_enter(mask);
-			if (*where != target)
-				*where = target;
-		}
-	}
-}
-
 static int
 _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
 	Elf_Addr *tp)

Index: src/libexec/ld.elf_so/arch/i386/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/i386/Makefile.inc:1.14 src/libexec/ld.elf_so/arch/i386/Makefile.inc:1.15
--- src/libexec/ld.elf_so/arch/i386/Makefile.inc:1.14	Sun Dec 13 09:31:47 2009
+++ src/libexec/ld.elf_so/arch/i386/Makefile.inc	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.14 2009/12/13 09:31:47 mrg Exp $
+#	$NetBSD: Makefile.inc,v 1.15 2018/04/03 21:10:27 joerg Exp $
 
 SRCS+=		rtld_start.S mdreloc.c
 
@@ -6,5 +6,6 @@ SRCS+=		rtld_start.S mdreloc.c
 CPPFLAGS+=	-fpic
 
 CPPFLAGS+=	-DELFSIZE=32
+CPPFLAGS+=	-DRTLD_COMMON_CALL_IFUNC_REL
 
 LDFLAGS+=	-Wl,-e,.rtld_start

Index: src/libexec/ld.elf_so/arch/i386/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.40 src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.41
--- src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.40	Mon Nov  6 21:16:04 2017
+++ src/libexec/ld.elf_so/arch/i386/mdreloc.c	Tue Apr  3 21:10:27 2018
@@ -1,8 +1,8 @@
-/*	$NetBSD: mdreloc.c,v 1.40 2017/11/06 21:16:04 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.41 2018/04/03 21:10:27 joerg Exp $	*/
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.40 2017/11/06 21:16:04 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.41 2018/04/03 21:10:27 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -115,6 +115,15 @@ _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 =
+				    obj->rellim - rel;
+			}
+			/* FALL-THROUGH */
+
 		case R_TYPE(RELATIVE):
 			*where += (Elf_Addr)obj->relocbase;
 			rdbg(("RELATIVE in %s --> %p", obj->path,
@@ -215,26 +224,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 	return 0;
 }
 
-void
-_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
-{
-	const Elf_Rel *rel;
-	Elf_Addr *where, target;
-
-	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
-		rel = obj->pltrellim - obj->ifunc_remaining;
-		--obj->ifunc_remaining;
-		if (ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE)) {
-			where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
-			_rtld_exclusive_exit(mask);
-			target = _rtld_resolve_ifunc2(obj, *where);
-			_rtld_exclusive_enter(mask);
-			if (*where != target)
-				*where = target;
-		}
-	}
-}
-
 static inline int
 _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
 	Elf_Addr *tp)

Index: src/libexec/ld.elf_so/arch/powerpc/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/powerpc/Makefile.inc:1.15 src/libexec/ld.elf_so/arch/powerpc/Makefile.inc:1.16
--- src/libexec/ld.elf_so/arch/powerpc/Makefile.inc:1.15	Fri Aug 15 09:40:07 2014
+++ src/libexec/ld.elf_so/arch/powerpc/Makefile.inc	Tue Apr  3 21:10:27 2018
@@ -1,9 +1,10 @@
-#	$NetBSD: Makefile.inc,v 1.15 2014/08/15 09:40:07 matt Exp $
+#	$NetBSD: Makefile.inc,v 1.16 2018/04/03 21:10:27 joerg Exp $
 
 SRCS+=		ppc_reloc.c
 LDFLAGS+=	-Wl,-e,_rtld_start
 
 CPPFLAGS+=	-fPIC
+CPPFLAGS+=	-DRTLD_COMMON_CALL_IFUNC_RELA
 
 .if ${LDELFSO_MACHINE_ARCH} == "powerpc64"
 SRCS+=		rtld_start64.S

Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.56 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.57
--- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.56	Fri Mar  9 20:19:11 2018
+++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ppc_reloc.c,v 1.56 2018/03/09 20:19:11 joerg Exp $	*/
+/*	$NetBSD: ppc_reloc.c,v 1.57 2018/04/03 21:10:27 joerg Exp $	*/
 
 /*-
  * Copyright (C) 1998	Tsubai Masanari
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ppc_reloc.c,v 1.56 2018/03/09 20:19:11 joerg Exp $");
+__RCSID("$NetBSD: ppc_reloc.c,v 1.57 2018/04/03 21:10:27 joerg Exp $");
 #endif /* not lint */
 
 #include <stdarg.h>
@@ -289,7 +289,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry 
 			/* IFUNC relocations are handled in _rtld_call_ifunc */
 			if (obj->ifunc_remaining_nonplt == 0) {
 				obj->ifunc_remaining_nonplt =
-				    rela - obj->rela + 1;
+				    obj->relalim - rela;
 			}
 			break;
 
@@ -371,40 +371,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 	return 0;
 }
 
-void
-_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
-{
-	const Elf_Rela *rela;
-	Elf_Addr *where, target;
-
-	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
-		rela = obj->pltrelalim - obj->ifunc_remaining;
-		--obj->ifunc_remaining;
-		if (ELF_R_TYPE(rela->r_info) == R_TYPE(IRELATIVE)) {
-			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;
-		}
-	}
-
-	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
 _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, int reloff, Elf_Addr *tp)
 {

Index: src/libexec/ld.elf_so/arch/sparc/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/sparc/Makefile.inc:1.14 src/libexec/ld.elf_so/arch/sparc/Makefile.inc:1.15
--- src/libexec/ld.elf_so/arch/sparc/Makefile.inc:1.14	Sun Dec 13 09:31:47 2009
+++ src/libexec/ld.elf_so/arch/sparc/Makefile.inc	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.14 2009/12/13 09:31:47 mrg Exp $
+#	$NetBSD: Makefile.inc,v 1.15 2018/04/03 21:10:27 joerg Exp $
 
 SRCS+=		rtld_start.S mdreloc.c
 
@@ -6,5 +6,6 @@ SRCS+=		rtld_start.S mdreloc.c
 CPPFLAGS+=	-fpic
 
 CPPFLAGS+=	-DELFSIZE=32
+CPPFLAGS+=	-DRTLD_COMMON_CALL_IFUNC_RELA
 
 LDFLAGS+=	-Wl,-e,_rtld_start

Index: src/libexec/ld.elf_so/arch/sparc/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.54 src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.55
--- src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.54	Thu Mar 29 13:23:39 2018
+++ src/libexec/ld.elf_so/arch/sparc/mdreloc.c	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: mdreloc.c,v 1.54 2018/03/29 13:23:39 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.55 2018/04/03 21:10:27 joerg Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.54 2018/03/29 13:23:39 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.55 2018/04/03 21:10:27 joerg Exp $");
 #endif /* not lint */
 
 #include <machine/elf_support.h>
@@ -224,8 +224,10 @@ _rtld_relocate_nonplt_objects(Obj_Entry 
 
 		/* IFUNC relocations are handled in _rtld_call_ifunc */
 		if (type == R_TYPE(IRELATIVE)) {
-			if (obj->ifunc_remaining_nonplt == 0)
-				obj->ifunc_remaining_nonplt = rela - obj->rela + 1;
+			if (obj->ifunc_remaining_nonplt == 0) {
+				obj->ifunc_remaining_nonplt =
+				    obj->relalim - rela;
+			}
 			continue;
 		}
 
@@ -406,38 +408,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 	return 0;
 }
 
-void
-_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
-{
-	const Elf_Rela *rela;
-	Elf_Addr *where, target;
-
-	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
-		rela = obj->pltrelalim - --obj->ifunc_remaining;
-		if (ELF_R_TYPE(rela->r_info) != R_TYPE(JMP_IREL))
-			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);
-		sparc_write_branch(where + 1, (void *)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;
-	}
-}
-
 caddr_t
 _rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
 {

Index: src/libexec/ld.elf_so/arch/sparc64/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/sparc64/Makefile.inc:1.8 src/libexec/ld.elf_so/arch/sparc64/Makefile.inc:1.9
--- src/libexec/ld.elf_so/arch/sparc64/Makefile.inc:1.8	Sat Jun  4 16:17:17 2005
+++ src/libexec/ld.elf_so/arch/sparc64/Makefile.inc	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.8 2005/06/04 16:17:17 lukem Exp $
+#	$NetBSD: Makefile.inc,v 1.9 2018/04/03 21:10:27 joerg Exp $
 
 SRCS+=		rtld_start.S mdreloc.c
 
@@ -6,5 +6,6 @@ SRCS+=		rtld_start.S mdreloc.c
 CPPFLAGS+=	-fpic
 
 CPPFLAGS+=	-DELFSIZE=64
+CPPFLAGS+=	-DRTLD_COMMON_CALL_IFUNC_RELA
 
 LDFLAGS+=	-Wl,-e,_rtld_start

Index: src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.68 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.69
--- src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.68	Thu Mar 29 13:23:39 2018
+++ src/libexec/ld.elf_so/arch/sparc64/mdreloc.c	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: mdreloc.c,v 1.68 2018/03/29 13:23:39 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.69 2018/04/03 21:10:27 joerg Exp $	*/
 
 /*-
  * Copyright (c) 2000 Eduardo Horvath.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.68 2018/03/29 13:23:39 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.69 2018/04/03 21:10:27 joerg Exp $");
 #endif /* not lint */
 
 #include <machine/elf_support.h>
@@ -323,8 +323,10 @@ _rtld_relocate_nonplt_objects(Obj_Entry 
 
 		/* IFUNC relocations are handled in _rtld_call_ifunc */
 		if (type == R_TYPE(IRELATIVE)) {
-			if (obj->ifunc_remaining_nonplt == 0)
-				obj->ifunc_remaining_nonplt = rela - obj->rela + 1;
+			if (obj->ifunc_remaining_nonplt == 0) {
+				obj->ifunc_remaining_nonplt =
+				    obj->relalim - rela;
+			}
 			continue;
 		}
 
@@ -633,37 +635,3 @@ _rtld_relocate_plt_object(const Obj_Entr
 
 	return 0;
 }
-
-void
-_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
-{
-	const Elf_Rela *rela;
-	Elf_Addr *where;
-	Elf_Word *where2;
-	Elf_Addr target;
-
-	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
-		rela = obj->pltrelalim - --obj->ifunc_remaining;
-		if (ELF_R_TYPE(rela->r_info) != R_TYPE(JMP_IREL))
-			continue;
-		where2 = (Elf_Word *)(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);
-		sparc_write_branch(where2 + 1, (void *)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;
-	}
-}

Index: src/libexec/ld.elf_so/arch/x86_64/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/x86_64/Makefile.inc:1.7 src/libexec/ld.elf_so/arch/x86_64/Makefile.inc:1.8
--- src/libexec/ld.elf_so/arch/x86_64/Makefile.inc:1.7	Sat Jun  4 16:17:17 2005
+++ src/libexec/ld.elf_so/arch/x86_64/Makefile.inc	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.7 2005/06/04 16:17:17 lukem Exp $
+#	$NetBSD: Makefile.inc,v 1.8 2018/04/03 21:10:27 joerg Exp $
 
 SRCS+=		rtld_start.S mdreloc.c
 
@@ -6,5 +6,6 @@ SRCS+=		rtld_start.S mdreloc.c
 CPPFLAGS+=	-fPIC
 
 CPPFLAGS+=	-DELFSIZE=64
+CPPFLAGS+=	-DRTLD_COMMON_CALL_IFUNC_RELA
 
 LDFLAGS+=	-Wl,-e,.rtld_start

Index: src/libexec/ld.elf_so/arch/x86_64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.46 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.47
--- src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.46	Mon Nov  6 21:16:04 2017
+++ src/libexec/ld.elf_so/arch/x86_64/mdreloc.c	Tue Apr  3 21:10:27 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: mdreloc.c,v 1.46 2017/11/06 21:16:04 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.47 2018/04/03 21:10:27 joerg Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -68,7 +68,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.46 2017/11/06 21:16:04 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.47 2018/04/03 21:10:27 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -261,6 +261,14 @@ _rtld_relocate_nonplt_objects(Obj_Entry 
 			rdbg(("COPY"));
 			break;
 
+		case R_TYPE(IRELATIVE):
+			/* IFUNC relocations are handled in _rtld_call_ifunc */
+			if (obj->ifunc_remaining_nonplt == 0) {
+				obj->ifunc_remaining_nonplt =
+				    obj->relalim - rela;
+			}
+			break;
+
 		default:
 			rdbg(("sym = %lu, type = %lu, offset = %p, "
 			    "addend = %p, contents = %p, symbol = %s",
@@ -299,27 +307,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 	return 0;
 }
 
-void
-_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
-{
-	const Elf_Rela *rela;
-	Elf_Addr *where, target;
-
-	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
-		rela = obj->pltrelalim - obj->ifunc_remaining;
-		--obj->ifunc_remaining;
-		if (ELF_R_TYPE(rela->r_info) == R_TYPE(IRELATIVE)) {
-			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 inline int
 _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *tp)
 {

Reply via email to