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/554c7efe3b54
branches:  trunk
changeset: 827650:554c7efe3b54
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 23f971d35233 -r 554c7efe3b54 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 23f971d35233 -r 554c7efe3b54 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 23f971d35233 -r 554c7efe3b54 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 23f971d35233 -r 554c7efe3b54 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 23f971d35233 -r 554c7efe3b54 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 23f971d35233 -r 554c7efe3b54 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