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/109f02169328
branches: trunk
changeset: 321753:109f02169328
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 7d88cc1b3987 -r 109f02169328 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 7d88cc1b3987 -r 109f02169328 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 7d88cc1b3987 -r 109f02169328 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 7d88cc1b3987 -r 109f02169328 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 7d88cc1b3987 -r 109f02169328 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 7d88cc1b3987 -r 109f02169328 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 7d88cc1b3987 -r 109f02169328 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 7d88cc1b3987 -r 109f02169328 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