Module Name:    src
Committed By:   joerg
Date:           Mon Nov  6 21:16:04 UTC 2017

Modified Files:
        src/libexec/ld.elf_so: rtld.c
        src/libexec/ld.elf_so/arch/arm: mdreloc.c
        src/libexec/ld.elf_so/arch/i386: mdreloc.c
        src/libexec/ld.elf_so/arch/sparc64: mdreloc.c
        src/libexec/ld.elf_so/arch/x86_64: mdreloc.c
        src/tests/libexec/ld.elf_so: t_ifunc.c

Log Message:
init/fini for the main program is handled by crt0.o, so ifunc handling
is skipped right now as it iterates the same list. Don't repeat that
mistake and explicitly take care of it in the dynamic linker.


To generate a diff of this commit:
cvs rdiff -u -r1.187 -r1.188 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.42 -r1.43 src/libexec/ld.elf_so/arch/arm/mdreloc.c
cvs rdiff -u -r1.39 -r1.40 src/libexec/ld.elf_so/arch/i386/mdreloc.c
cvs rdiff -u -r1.65 -r1.66 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
cvs rdiff -u -r1.45 -r1.46 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c
cvs rdiff -u -r1.4 -r1.5 src/tests/libexec/ld.elf_so/t_ifunc.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.187 src/libexec/ld.elf_so/rtld.c:1.188
--- src/libexec/ld.elf_so/rtld.c:1.187	Sat Aug 12 09:03:27 2017
+++ src/libexec/ld.elf_so/rtld.c	Mon Nov  6 21:16:04 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.c,v 1.187 2017/08/12 09:03:27 joerg Exp $	 */
+/*	$NetBSD: rtld.c,v 1.188 2017/11/06 21:16:04 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.187 2017/08/12 09:03:27 joerg Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.188 2017/11/06 21:16:04 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -259,6 +259,22 @@ _rtld_call_init_function(Obj_Entry *obj,
 #endif /* HAVE_INITFINI_ARRAY */
 }
 
+static bool
+_rtld_call_ifunc_functions(sigset_t *mask, Obj_Entry *obj, u_int cur_objgen)
+{
+	if (obj->ifunc_remaining
+#ifdef __sparc__
+	    || obj->ifunc_remaining_nonplt
+#endif
+	) {
+		_rtld_call_ifunc(obj, mask, cur_objgen);
+		if (_rtld_objgen != cur_objgen) {
+			return true;
+		}
+	}
+	return false;
+}
+
 static void
 _rtld_call_init_functions(sigset_t *mask)
 {
@@ -275,20 +291,22 @@ restart:
 
 	/* First pass: objects with IRELATIVE relocations. */
 	SIMPLEQ_FOREACH(elm, &initlist, link) {
-		Obj_Entry * const obj = elm->obj;
-		if (obj->ifunc_remaining
-#ifdef __sparc__
-		    || obj->ifunc_remaining_nonplt
-#endif
-		) {
-			_rtld_call_ifunc(obj, mask, cur_objgen);
-			if (_rtld_objgen != cur_objgen) {
-				dbg(("restarting init iteration"));
-				_rtld_objlist_clear(&initlist);
-				goto restart;
-			}
+		if (_rtld_call_ifunc_functions(mask, elm->obj, cur_objgen)) {
+			dbg(("restarting init iteration"));
+			_rtld_objlist_clear(&initlist);
+			goto restart;
 		}
 	}
+	/*
+	 * XXX: For historic reasons, init/fini of the main object are called
+	 * from crt0. Don't introduce that mistake for ifunc, so look at
+	 * the head of _rtld_objlist that _rtld_initlist_tsort skipped.
+	 */
+	if (_rtld_call_ifunc_functions(mask, _rtld_objlist, cur_objgen)) {
+		dbg(("restarting init iteration"));
+		_rtld_objlist_clear(&initlist);
+		goto restart;
+	}
 
 	/* Second pass: objects marked with DF_1_INITFIRST. */
 	SIMPLEQ_FOREACH(elm, &initlist, link) {

Index: src/libexec/ld.elf_so/arch/arm/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.42 src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.43
--- src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.42	Thu Aug 10 19:03:26 2017
+++ src/libexec/ld.elf_so/arch/arm/mdreloc.c	Mon Nov  6 21:16:04 2017
@@ -1,8 +1,8 @@
-/*	$NetBSD: mdreloc.c,v 1.42 2017/08/10 19:03:26 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.43 2017/11/06 21:16:04 joerg Exp $	*/
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.42 2017/08/10 19:03:26 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.43 2017/11/06 21:16:04 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -257,9 +257,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 {
 	const Elf_Rel *rel;
 
-	if (!obj->relocbase)
-		return 0;
-
 	for (rel = obj->pltrellim; rel-- > obj->pltrel; ) {
 		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
 

Index: src/libexec/ld.elf_so/arch/i386/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.39 src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.40
--- src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.39	Thu Aug 10 19:03:26 2017
+++ src/libexec/ld.elf_so/arch/i386/mdreloc.c	Mon Nov  6 21:16:04 2017
@@ -1,8 +1,8 @@
-/*	$NetBSD: mdreloc.c,v 1.39 2017/08/10 19:03:26 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.40 2017/11/06 21:16:04 joerg Exp $	*/
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.39 2017/08/10 19:03:26 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.40 2017/11/06 21:16:04 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -198,9 +198,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 {
 	const Elf_Rel *rel;
 
-	if (!obj->relocbase)
-		return 0;
-
 	for (rel = obj->pltrellim; rel-- > obj->pltrel; ) {
 		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
 

Index: src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.65 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.66
--- src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.65	Sat Aug 12 09:03:27 2017
+++ src/libexec/ld.elf_so/arch/sparc64/mdreloc.c	Mon Nov  6 21:16:04 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mdreloc.c,v 1.65 2017/08/12 09:03:27 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.66 2017/11/06 21:16:04 joerg Exp $	*/
 
 /*-
  * Copyright (c) 2000 Eduardo Horvath.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.65 2017/08/12 09:03:27 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.66 2017/11/06 21:16:04 joerg Exp $");
 #endif /* not lint */
 
 #include <errno.h>
@@ -516,9 +516,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 {
 	const Elf_Rela *rela;
 
-	if (!obj->relocbase)
-		return 0;
-
 	for (rela = obj->pltrelalim; rela-- > obj->pltrela; ) {
 		if (ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_IREL))
 			obj->ifunc_remaining = obj->pltrelalim - rela + 1;

Index: src/libexec/ld.elf_so/arch/x86_64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.45 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.46
--- src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.45	Thu Aug 10 19:03:27 2017
+++ src/libexec/ld.elf_so/arch/x86_64/mdreloc.c	Mon Nov  6 21:16:04 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mdreloc.c,v 1.45 2017/08/10 19:03:27 joerg Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.46 2017/11/06 21:16:04 joerg Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -68,7 +68,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.45 2017/08/10 19:03:27 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.46 2017/11/06 21:16:04 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -282,9 +282,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
 {
 	const Elf_Rela *rela;
 
-	if (!obj->relocbase)
-		return 0;
-
 	for (rela = obj->pltrelalim; rela-- > obj->pltrela; ) {
 		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
 

Index: src/tests/libexec/ld.elf_so/t_ifunc.c
diff -u src/tests/libexec/ld.elf_so/t_ifunc.c:1.4 src/tests/libexec/ld.elf_so/t_ifunc.c:1.5
--- src/tests/libexec/ld.elf_so/t_ifunc.c:1.4	Sat Aug 12 09:03:28 2017
+++ src/tests/libexec/ld.elf_so/t_ifunc.c	Mon Nov  6 21:16:03 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ifunc.c,v 1.4 2017/08/12 09:03:28 joerg Exp $	*/
+/*	$NetBSD: t_ifunc.c,v 1.5 2017/11/06 21:16:03 joerg Exp $	*/
 
 /*
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -149,9 +149,36 @@ ATF_TC_BODY(rtld_hidden_ifunc, tc)
 	}
 }
 
+ATF_TC(rtld_main_ifunc);
+ATF_TC_HEAD(rtld_main_ifunc, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "ifunc functions are resolved in the executable");
+}
+
+static unsigned int
+ifunc_helper(void)
+{
+	return 0xdeadbeef;
+}
+
+static __attribute__((used))
+unsigned int (*resolve_ifunc(void))(void)
+{
+	return ifunc_helper;
+}
+__hidden_ifunc(ifunc, resolve_ifunc);
+unsigned int ifunc(void);
+
+ATF_TC_BODY(rtld_main_ifunc, tc)
+{
+	ATF_CHECK(ifunc() == 0xdeadbeef);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 	ATF_TP_ADD_TC(tp, rtld_ifunc);
 	ATF_TP_ADD_TC(tp, rtld_hidden_ifunc);
+	ATF_TP_ADD_TC(tp, rtld_main_ifunc);
 	return 0;
 }

Reply via email to