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) {