Module Name: src
Committed By: joerg
Date: Tue Apr 3 21:10:28 UTC 2018
Modified Files:
src/libexec/ld.elf_so: reloc.c rtld.c rtld.h
src/libexec/ld.elf_so/arch/arm: Makefile.inc mdreloc.c
src/libexec/ld.elf_so/arch/i386: Makefile.inc mdreloc.c
src/libexec/ld.elf_so/arch/powerpc: Makefile.inc ppc_reloc.c
src/libexec/ld.elf_so/arch/sparc: Makefile.inc mdreloc.c
src/libexec/ld.elf_so/arch/sparc64: Makefile.inc mdreloc.c
src/libexec/ld.elf_so/arch/x86_64: Makefile.inc mdreloc.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.111 -r1.112 src/libexec/ld.elf_so/reloc.c
cvs rdiff -u -r1.191 -r1.192 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.132 -r1.133 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.20 -r1.21 src/libexec/ld.elf_so/arch/arm/Makefile.inc
cvs rdiff -u -r1.43 -r1.44 src/libexec/ld.elf_so/arch/arm/mdreloc.c
cvs rdiff -u -r1.14 -r1.15 src/libexec/ld.elf_so/arch/i386/Makefile.inc
cvs rdiff -u -r1.40 -r1.41 src/libexec/ld.elf_so/arch/i386/mdreloc.c
cvs rdiff -u -r1.15 -r1.16 src/libexec/ld.elf_so/arch/powerpc/Makefile.inc
cvs rdiff -u -r1.56 -r1.57 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
cvs rdiff -u -r1.14 -r1.15 src/libexec/ld.elf_so/arch/sparc/Makefile.inc
cvs rdiff -u -r1.54 -r1.55 src/libexec/ld.elf_so/arch/sparc/mdreloc.c
cvs rdiff -u -r1.8 -r1.9 src/libexec/ld.elf_so/arch/sparc64/Makefile.inc
cvs rdiff -u -r1.68 -r1.69 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
cvs rdiff -u -r1.7 -r1.8 src/libexec/ld.elf_so/arch/x86_64/Makefile.inc
cvs rdiff -u -r1.46 -r1.47 src/libexec/ld.elf_so/arch/x86_64/mdreloc.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/reloc.c
diff -u src/libexec/ld.elf_so/reloc.c:1.111 src/libexec/ld.elf_so/reloc.c:1.112
--- src/libexec/ld.elf_so/reloc.c:1.111 Thu Aug 10 19:03:25 2017
+++ src/libexec/ld.elf_so/reloc.c Tue Apr 3 21:10:27 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: reloc.c,v 1.111 2017/08/10 19:03:25 joerg Exp $ */
+/* $NetBSD: reloc.c,v 1.112 2018/04/03 21:10:27 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.111 2017/08/10 19:03:25 joerg Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.112 2018/04/03 21:10:27 joerg Exp $");
#endif /* not lint */
#include <err.h>
@@ -276,3 +276,93 @@ _rtld_resolve_ifunc2(const Obj_Entry *ob
return target;
}
+
+#ifdef RTLD_COMMON_CALL_IFUNC_RELA
+# ifdef __sparc__
+# include <machine/elf_support.h>
+# endif
+
+void
+_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
+{
+ const Elf_Rela *rela;
+ Elf_Addr *where;
+#ifdef __sparc__
+ Elf_Word *where2;
+#endif
+ Elf_Addr target;
+
+ while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
+ rela = obj->pltrelalim - obj->ifunc_remaining--;
+#ifdef __sparc__
+#define PLT_IRELATIVE R_TYPE(JMP_IREL)
+#else
+#define PLT_IRELATIVE R_TYPE(IRELATIVE)
+#endif
+ if (ELF_R_TYPE(rela->r_info) != PLT_IRELATIVE)
+ continue;
+#ifdef __sparc__
+ where2 = (Elf_Word *)(obj->relocbase + rela->r_offset);
+#else
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+#endif
+ target = (Elf_Addr)(obj->relocbase + rela->r_addend);
+ _rtld_exclusive_exit(mask);
+ target = _rtld_resolve_ifunc2(obj, target);
+ _rtld_exclusive_enter(mask);
+#ifdef __sparc__
+ sparc_write_branch(where2 + 1, (void *)target);
+#else
+ if (*where != target)
+ *where = target;
+#endif
+ }
+
+ 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;
+ }
+}
+#endif
+
+#ifdef RTLD_COMMON_CALL_IFUNC_REL
+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;
+ }
+ }
+
+ while (obj->ifunc_remaining_nonplt > 0 && _rtld_objgen == cur_objgen) {
+ rel = obj->rellim - obj->ifunc_remaining_nonplt--;
+ 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;
+ }
+ }
+}
+#endif
Index: src/libexec/ld.elf_so/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.191 src/libexec/ld.elf_so/rtld.c:1.192
--- src/libexec/ld.elf_so/rtld.c:1.191 Fri Mar 9 20:19:11 2018
+++ src/libexec/ld.elf_so/rtld.c Tue Apr 3 21:10:27 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.191 2018/03/09 20:19:11 joerg Exp $ */
+/* $NetBSD: rtld.c,v 1.192 2018/04/03 21:10:27 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.191 2018/03/09 20:19:11 joerg Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.192 2018/04/03 21:10:27 joerg Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -263,7 +263,7 @@ static bool
_rtld_call_ifunc_functions(sigset_t *mask, Obj_Entry *obj, u_int cur_objgen)
{
if (obj->ifunc_remaining
-#if defined(__sparc__) || defined(__powerpc__)
+#if defined(IFUNC_NONPLT)
|| obj->ifunc_remaining_nonplt
#endif
) {
Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.132 src/libexec/ld.elf_so/rtld.h:1.133
--- src/libexec/ld.elf_so/rtld.h:1.132 Fri Mar 9 20:19:11 2018
+++ src/libexec/ld.elf_so/rtld.h Tue Apr 3 21:10:27 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.h,v 1.132 2018/03/09 20:19:11 joerg Exp $ */
+/* $NetBSD: rtld.h,v 1.133 2018/04/03 21:10:27 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -300,7 +300,9 @@ typedef struct Struct_Obj_Entry {
size_t fini_arraysz; /* # of entries in it */
/* IRELATIVE relocations */
size_t ifunc_remaining;
-#if defined(__sparc__) || defined(__powerpc__)
+#if defined(__sparc__) || defined(__powerpc__) || defined(__arm__) || \
+ defined(__i386__) || defined(__x86_64__)
+#define IFUNC_NONPLT
/* On SPARC, the PLT variant is called JMP_IREL and counted above. */
size_t ifunc_remaining_nonplt;
#endif
Index: src/libexec/ld.elf_so/arch/arm/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/arm/Makefile.inc:1.20 src/libexec/ld.elf_so/arch/arm/Makefile.inc:1.21
--- src/libexec/ld.elf_so/arch/arm/Makefile.inc:1.20 Tue Sep 10 16:35:10 2013
+++ src/libexec/ld.elf_so/arch/arm/Makefile.inc Tue Apr 3 21:10:27 2018
@@ -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 @@ SRCS+= rtld_start.S mdreloc.c
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}\"
Index: src/libexec/ld.elf_so/arch/arm/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.43 src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.44
--- src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.43 Mon Nov 6 21:16:04 2017
+++ src/libexec/ld.elf_so/arch/arm/mdreloc.c Tue Apr 3 21:10:27 2018
@@ -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 @@ _rtld_relocate_nonplt_objects(Obj_Entry
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 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
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)
Index: src/libexec/ld.elf_so/arch/i386/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/i386/Makefile.inc:1.14 src/libexec/ld.elf_so/arch/i386/Makefile.inc:1.15
--- src/libexec/ld.elf_so/arch/i386/Makefile.inc:1.14 Sun Dec 13 09:31:47 2009
+++ src/libexec/ld.elf_so/arch/i386/Makefile.inc Tue Apr 3 21:10:27 2018
@@ -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 @@ SRCS+= rtld_start.S mdreloc.c
CPPFLAGS+= -fpic
CPPFLAGS+= -DELFSIZE=32
+CPPFLAGS+= -DRTLD_COMMON_CALL_IFUNC_REL
LDFLAGS+= -Wl,-e,.rtld_start
Index: src/libexec/ld.elf_so/arch/i386/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.40 src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.41
--- src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.40 Mon Nov 6 21:16:04 2017
+++ src/libexec/ld.elf_so/arch/i386/mdreloc.c Tue Apr 3 21:10:27 2018
@@ -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 @@ _rtld_relocate_nonplt_objects(Obj_Entry
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 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
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)
Index: src/libexec/ld.elf_so/arch/powerpc/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/powerpc/Makefile.inc:1.15 src/libexec/ld.elf_so/arch/powerpc/Makefile.inc:1.16
--- src/libexec/ld.elf_so/arch/powerpc/Makefile.inc:1.15 Fri Aug 15 09:40:07 2014
+++ src/libexec/ld.elf_so/arch/powerpc/Makefile.inc Tue Apr 3 21:10:27 2018
@@ -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
Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.56 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.57
--- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.56 Fri Mar 9 20:19:11 2018
+++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Tue Apr 3 21:10:27 2018
@@ -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 @@ _rtld_relocate_nonplt_objects(Obj_Entry
/* 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 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
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)
{
Index: src/libexec/ld.elf_so/arch/sparc/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/sparc/Makefile.inc:1.14 src/libexec/ld.elf_so/arch/sparc/Makefile.inc:1.15
--- src/libexec/ld.elf_so/arch/sparc/Makefile.inc:1.14 Sun Dec 13 09:31:47 2009
+++ src/libexec/ld.elf_so/arch/sparc/Makefile.inc Tue Apr 3 21:10:27 2018
@@ -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 @@ SRCS+= rtld_start.S mdreloc.c
CPPFLAGS+= -fpic
CPPFLAGS+= -DELFSIZE=32
+CPPFLAGS+= -DRTLD_COMMON_CALL_IFUNC_RELA
LDFLAGS+= -Wl,-e,_rtld_start
Index: src/libexec/ld.elf_so/arch/sparc/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.54 src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.55
--- src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.54 Thu Mar 29 13:23:39 2018
+++ src/libexec/ld.elf_so/arch/sparc/mdreloc.c Tue Apr 3 21:10:27 2018
@@ -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 @@ _rtld_relocate_nonplt_objects(Obj_Entry
/* 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 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
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;
- 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;
- }
-}
-
caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
Index: src/libexec/ld.elf_so/arch/sparc64/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/sparc64/Makefile.inc:1.8 src/libexec/ld.elf_so/arch/sparc64/Makefile.inc:1.9
--- src/libexec/ld.elf_so/arch/sparc64/Makefile.inc:1.8 Sat Jun 4 16:17:17 2005
+++ src/libexec/ld.elf_so/arch/sparc64/Makefile.inc Tue Apr 3 21:10:27 2018
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.8 2005/06/04 16:17:17 lukem Exp $
+# $NetBSD: Makefile.inc,v 1.9 2018/04/03 21:10:27 joerg Exp $
SRCS+= rtld_start.S mdreloc.c
@@ -6,5 +6,6 @@ SRCS+= rtld_start.S mdreloc.c
CPPFLAGS+= -fpic
CPPFLAGS+= -DELFSIZE=64
+CPPFLAGS+= -DRTLD_COMMON_CALL_IFUNC_RELA
LDFLAGS+= -Wl,-e,_rtld_start
Index: src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.68 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.69
--- src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.68 Thu Mar 29 13:23:39 2018
+++ src/libexec/ld.elf_so/arch/sparc64/mdreloc.c Tue Apr 3 21:10:27 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.68 2018/03/29 13:23:39 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.69 2018/04/03 21:10:27 joerg Exp $ */
/*-
* Copyright (c) 2000 Eduardo Horvath.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.68 2018/03/29 13:23:39 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.69 2018/04/03 21:10:27 joerg Exp $");
#endif /* not lint */
#include <machine/elf_support.h>
@@ -323,8 +323,10 @@ _rtld_relocate_nonplt_objects(Obj_Entry
/* 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;
}
@@ -633,37 +635,3 @@ _rtld_relocate_plt_object(const Obj_Entr
return 0;
}
-
-void
-_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
-{
- const Elf_Rela *rela;
- Elf_Addr *where;
- Elf_Word *where2;
- Elf_Addr 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;
- where2 = (Elf_Word *)(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(where2 + 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;
- 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;
- }
-}
Index: src/libexec/ld.elf_so/arch/x86_64/Makefile.inc
diff -u src/libexec/ld.elf_so/arch/x86_64/Makefile.inc:1.7 src/libexec/ld.elf_so/arch/x86_64/Makefile.inc:1.8
--- src/libexec/ld.elf_so/arch/x86_64/Makefile.inc:1.7 Sat Jun 4 16:17:17 2005
+++ src/libexec/ld.elf_so/arch/x86_64/Makefile.inc Tue Apr 3 21:10:27 2018
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.7 2005/06/04 16:17:17 lukem Exp $
+# $NetBSD: Makefile.inc,v 1.8 2018/04/03 21:10:27 joerg Exp $
SRCS+= rtld_start.S mdreloc.c
@@ -6,5 +6,6 @@ SRCS+= rtld_start.S mdreloc.c
CPPFLAGS+= -fPIC
CPPFLAGS+= -DELFSIZE=64
+CPPFLAGS+= -DRTLD_COMMON_CALL_IFUNC_RELA
LDFLAGS+= -Wl,-e,.rtld_start
Index: src/libexec/ld.elf_so/arch/x86_64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.46 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.47
--- src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.46 Mon Nov 6 21:16:04 2017
+++ src/libexec/ld.elf_so/arch/x86_64/mdreloc.c Tue Apr 3 21:10:27 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.46 2017/11/06 21:16:04 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.47 2018/04/03 21:10:27 joerg Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -68,7 +68,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.46 2017/11/06 21:16:04 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.47 2018/04/03 21:10:27 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -261,6 +261,14 @@ _rtld_relocate_nonplt_objects(Obj_Entry
rdbg(("COPY"));
break;
+ case R_TYPE(IRELATIVE):
+ /* IFUNC relocations are handled in _rtld_call_ifunc */
+ if (obj->ifunc_remaining_nonplt == 0) {
+ obj->ifunc_remaining_nonplt =
+ obj->relalim - rela;
+ }
+ break;
+
default:
rdbg(("sym = %lu, type = %lu, offset = %p, "
"addend = %p, contents = %p, symbol = %s",
@@ -299,27 +307,6 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
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;
- }
- }
-}
-
static inline int
_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *tp)
{