Source-Changes-HG archive

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

[src/trunk]: src/libexec/ld.elf_so Rework ifunc support to address a number o...



details:   https://anonhg.NetBSD.org/src/rev/1163318ec4c5
branches:  trunk
changeset: 831521:1163318ec4c5
user:      joerg <joerg%NetBSD.org@localhost>
date:      Tue Apr 03 21:10:27 2018 +0000

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

diffstat:

 libexec/ld.elf_so/arch/arm/Makefile.inc     |   3 +-
 libexec/ld.elf_so/arch/arm/mdreloc.c        |  30 ++------
 libexec/ld.elf_so/arch/i386/Makefile.inc    |   3 +-
 libexec/ld.elf_so/arch/i386/mdreloc.c       |  33 +++------
 libexec/ld.elf_so/arch/powerpc/Makefile.inc |   3 +-
 libexec/ld.elf_so/arch/powerpc/ppc_reloc.c  |  40 +-----------
 libexec/ld.elf_so/arch/sparc/Makefile.inc   |   3 +-
 libexec/ld.elf_so/arch/sparc/mdreloc.c      |  42 +-----------
 libexec/ld.elf_so/arch/sparc64/Makefile.inc |   3 +-
 libexec/ld.elf_so/arch/sparc64/mdreloc.c    |  44 +-----------
 libexec/ld.elf_so/arch/x86_64/Makefile.inc  |   3 +-
 libexec/ld.elf_so/arch/x86_64/mdreloc.c     |  33 +++-------
 libexec/ld.elf_so/reloc.c                   |  94 ++++++++++++++++++++++++++++-
 libexec/ld.elf_so/rtld.c                    |   6 +-
 libexec/ld.elf_so/rtld.h                    |   6 +-
 15 files changed, 155 insertions(+), 191 deletions(-)

diffs (truncated from 634 to 300 lines):

diff -r 60bc17759fde -r 1163318ec4c5 libexec/ld.elf_so/arch/arm/Makefile.inc
--- a/libexec/ld.elf_so/arch/arm/Makefile.inc   Tue Apr 03 18:03:16 2018 +0000
+++ b/libexec/ld.elf_so/arch/arm/Makefile.inc   Tue Apr 03 21:10:27 2018 +0000
@@ -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 @@
 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}\"
diff -r 60bc17759fde -r 1163318ec4c5 libexec/ld.elf_so/arch/arm/mdreloc.c
--- a/libexec/ld.elf_so/arch/arm/mdreloc.c      Tue Apr 03 18:03:16 2018 +0000
+++ b/libexec/ld.elf_so/arch/arm/mdreloc.c      Tue Apr 03 21:10:27 2018 +0000
@@ -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 @@
                            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 @@
        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)
diff -r 60bc17759fde -r 1163318ec4c5 libexec/ld.elf_so/arch/i386/Makefile.inc
--- a/libexec/ld.elf_so/arch/i386/Makefile.inc  Tue Apr 03 18:03:16 2018 +0000
+++ b/libexec/ld.elf_so/arch/i386/Makefile.inc  Tue Apr 03 21:10:27 2018 +0000
@@ -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 @@
 CPPFLAGS+=     -fpic
 
 CPPFLAGS+=     -DELFSIZE=32
+CPPFLAGS+=     -DRTLD_COMMON_CALL_IFUNC_REL
 
 LDFLAGS+=      -Wl,-e,.rtld_start
diff -r 60bc17759fde -r 1163318ec4c5 libexec/ld.elf_so/arch/i386/mdreloc.c
--- a/libexec/ld.elf_so/arch/i386/mdreloc.c     Tue Apr 03 18:03:16 2018 +0000
+++ b/libexec/ld.elf_so/arch/i386/mdreloc.c     Tue Apr 03 21:10:27 2018 +0000
@@ -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 @@
                            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 @@
        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)
diff -r 60bc17759fde -r 1163318ec4c5 libexec/ld.elf_so/arch/powerpc/Makefile.inc
--- a/libexec/ld.elf_so/arch/powerpc/Makefile.inc       Tue Apr 03 18:03:16 2018 +0000
+++ b/libexec/ld.elf_so/arch/powerpc/Makefile.inc       Tue Apr 03 21:10:27 2018 +0000
@@ -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
diff -r 60bc17759fde -r 1163318ec4c5 libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
--- a/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c        Tue Apr 03 18:03:16 2018 +0000
+++ b/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c        Tue Apr 03 21:10:27 2018 +0000
@@ -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 @@
                        /* 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 @@
        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)
 {
diff -r 60bc17759fde -r 1163318ec4c5 libexec/ld.elf_so/arch/sparc/Makefile.inc
--- a/libexec/ld.elf_so/arch/sparc/Makefile.inc Tue Apr 03 18:03:16 2018 +0000
+++ b/libexec/ld.elf_so/arch/sparc/Makefile.inc Tue Apr 03 21:10:27 2018 +0000
@@ -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 @@
 CPPFLAGS+=     -fpic
 
 CPPFLAGS+=     -DELFSIZE=32
+CPPFLAGS+=     -DRTLD_COMMON_CALL_IFUNC_RELA
 
 LDFLAGS+=      -Wl,-e,_rtld_start
diff -r 60bc17759fde -r 1163318ec4c5 libexec/ld.elf_so/arch/sparc/mdreloc.c
--- a/libexec/ld.elf_so/arch/sparc/mdreloc.c    Tue Apr 03 18:03:16 2018 +0000
+++ b/libexec/ld.elf_so/arch/sparc/mdreloc.c    Tue Apr 03 21:10:27 2018 +0000
@@ -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 @@
 
                /* 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 @@
        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;



Home | Main Index | Thread Index | Old Index