Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src init/fini for the main program is handled by crt0.o, so ifun...



details:   https://anonhg.NetBSD.org/src/rev/df7e0e35ed90
branches:  trunk
changeset: 357349:df7e0e35ed90
user:      joerg <joerg%NetBSD.org@localhost>
date:      Mon Nov 06 21:16:03 2017 +0000

description:
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.

diffstat:

 libexec/ld.elf_so/arch/arm/mdreloc.c     |   7 +---
 libexec/ld.elf_so/arch/i386/mdreloc.c    |   7 +---
 libexec/ld.elf_so/arch/sparc64/mdreloc.c |   7 +---
 libexec/ld.elf_so/arch/x86_64/mdreloc.c  |   7 +---
 libexec/ld.elf_so/rtld.c                 |  46 ++++++++++++++++++++++---------
 tests/libexec/ld.elf_so/t_ifunc.c        |  29 +++++++++++++++++++-
 6 files changed, 68 insertions(+), 35 deletions(-)

diffs (226 lines):

diff -r eb8d12dd78d9 -r df7e0e35ed90 libexec/ld.elf_so/arch/arm/mdreloc.c
--- a/libexec/ld.elf_so/arch/arm/mdreloc.c      Mon Nov 06 21:11:17 2017 +0000
+++ b/libexec/ld.elf_so/arch/arm/mdreloc.c      Mon Nov 06 21:16:03 2017 +0000
@@ -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 @@
 {
        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);
 
diff -r eb8d12dd78d9 -r df7e0e35ed90 libexec/ld.elf_so/arch/i386/mdreloc.c
--- a/libexec/ld.elf_so/arch/i386/mdreloc.c     Mon Nov 06 21:11:17 2017 +0000
+++ b/libexec/ld.elf_so/arch/i386/mdreloc.c     Mon Nov 06 21:16:03 2017 +0000
@@ -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 @@
 {
        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);
 
diff -r eb8d12dd78d9 -r df7e0e35ed90 libexec/ld.elf_so/arch/sparc64/mdreloc.c
--- a/libexec/ld.elf_so/arch/sparc64/mdreloc.c  Mon Nov 06 21:11:17 2017 +0000
+++ b/libexec/ld.elf_so/arch/sparc64/mdreloc.c  Mon Nov 06 21:16:03 2017 +0000
@@ -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 @@
 {
        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;
diff -r eb8d12dd78d9 -r df7e0e35ed90 libexec/ld.elf_so/arch/x86_64/mdreloc.c
--- a/libexec/ld.elf_so/arch/x86_64/mdreloc.c   Mon Nov 06 21:11:17 2017 +0000
+++ b/libexec/ld.elf_so/arch/x86_64/mdreloc.c   Mon Nov 06 21:16:03 2017 +0000
@@ -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 @@
 {
        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);
 
diff -r eb8d12dd78d9 -r df7e0e35ed90 libexec/ld.elf_so/rtld.c
--- a/libexec/ld.elf_so/rtld.c  Mon Nov 06 21:11:17 2017 +0000
+++ b/libexec/ld.elf_so/rtld.c  Mon Nov 06 21:16:03 2017 +0000
@@ -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 @@
 #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 @@
 
        /* 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) {
diff -r eb8d12dd78d9 -r df7e0e35ed90 tests/libexec/ld.elf_so/t_ifunc.c
--- a/tests/libexec/ld.elf_so/t_ifunc.c Mon Nov 06 21:11:17 2017 +0000
+++ b/tests/libexec/ld.elf_so/t_ifunc.c Mon Nov 06 21:16:03 2017 +0000
@@ -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(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;
 }



Home | Main Index | Thread Index | Old Index