Module Name: src
Committed By: joerg
Date: Thu Aug 10 19:03:27 UTC 2017
Modified Files:
src/libexec/ld.elf_so: reloc.c rtld.c rtld.h
src/libexec/ld.elf_so/arch/aarch64: mdreloc.c
src/libexec/ld.elf_so/arch/alpha: alpha_reloc.c
src/libexec/ld.elf_so/arch/arm: mdreloc.c
src/libexec/ld.elf_so/arch/hppa: hppa_reloc.c
src/libexec/ld.elf_so/arch/i386: mdreloc.c
src/libexec/ld.elf_so/arch/m68k: mdreloc.c
src/libexec/ld.elf_so/arch/mips: mips_reloc.c
src/libexec/ld.elf_so/arch/or1k: mdreloc.c
src/libexec/ld.elf_so/arch/powerpc: ppc_reloc.c
src/libexec/ld.elf_so/arch/riscv: mdreloc.c
src/libexec/ld.elf_so/arch/sh3: mdreloc.c
src/libexec/ld.elf_so/arch/sparc: mdreloc.c
src/libexec/ld.elf_so/arch/sparc64: mdreloc.c
src/libexec/ld.elf_so/arch/vax: mdreloc.c
src/libexec/ld.elf_so/arch/x86_64: mdreloc.c
src/sys/arch/arm/include: elf_machdep.h
src/sys/arch/powerpc/include: elf_machdep.h
src/sys/sys: cdefs_elf.h
src/tests/libexec/ld.elf_so: t_ifunc.c
src/tests/libexec/ld.elf_so/helper_ifunc_dso: h_helper_ifunc.c
Log Message:
Add IRELATIVE support for ARM, X86 and PowerPC.
To generate a diff of this commit:
cvs rdiff -u -r1.110 -r1.111 src/libexec/ld.elf_so/reloc.c
cvs rdiff -u -r1.185 -r1.186 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.129 -r1.130 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.3 -r1.4 src/libexec/ld.elf_so/arch/aarch64/mdreloc.c
cvs rdiff -u -r1.42 -r1.43 src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c
cvs rdiff -u -r1.41 -r1.42 src/libexec/ld.elf_so/arch/arm/mdreloc.c
cvs rdiff -u -r1.44 -r1.45 src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c
cvs rdiff -u -r1.38 -r1.39 src/libexec/ld.elf_so/arch/i386/mdreloc.c
cvs rdiff -u -r1.32 -r1.33 src/libexec/ld.elf_so/arch/m68k/mdreloc.c
cvs rdiff -u -r1.68 -r1.69 src/libexec/ld.elf_so/arch/mips/mips_reloc.c
cvs rdiff -u -r1.2 -r1.3 src/libexec/ld.elf_so/arch/or1k/mdreloc.c
cvs rdiff -u -r1.54 -r1.55 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
cvs rdiff -u -r1.3 -r1.4 src/libexec/ld.elf_so/arch/riscv/mdreloc.c
cvs rdiff -u -r1.34 -r1.35 src/libexec/ld.elf_so/arch/sh3/mdreloc.c
cvs rdiff -u -r1.50 -r1.51 src/libexec/ld.elf_so/arch/sparc/mdreloc.c
cvs rdiff -u -r1.63 -r1.64 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
cvs rdiff -u -r1.33 -r1.34 src/libexec/ld.elf_so/arch/vax/mdreloc.c
cvs rdiff -u -r1.44 -r1.45 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/arm/include/elf_machdep.h
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/powerpc/include/elf_machdep.h
cvs rdiff -u -r1.52 -r1.53 src/sys/sys/cdefs_elf.h
cvs rdiff -u -r1.2 -r1.3 src/tests/libexec/ld.elf_so/t_ifunc.c
cvs rdiff -u -r1.4 -r1.5 \
src/tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.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.110 src/libexec/ld.elf_so/reloc.c:1.111
--- src/libexec/ld.elf_so/reloc.c:1.110 Thu Apr 27 08:37:15 2017
+++ src/libexec/ld.elf_so/reloc.c Thu Aug 10 19:03:25 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: reloc.c,v 1.110 2017/04/27 08:37:15 uwe Exp $ */
+/* $NetBSD: reloc.c,v 1.111 2017/08/10 19:03:25 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.110 2017/04/27 08:37:15 uwe Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.111 2017/08/10 19:03:25 joerg Exp $");
#endif /* not lint */
#include <err.h>
@@ -261,9 +261,18 @@ _rtld_resolve_ifunc(const Obj_Entry *obj
Elf_Addr target;
_rtld_shared_exit();
- target = _rtld_call_function_addr(obj,
+ target = _rtld_resolve_ifunc2(obj,
(Elf_Addr)obj->relocbase + def->st_value);
_rtld_shared_enter();
+ return target;
+}
+
+Elf_Addr
+_rtld_resolve_ifunc2(const Obj_Entry *obj, Elf_Addr addr)
+{
+ Elf_Addr target;
+
+ target = _rtld_call_function_addr(obj, addr);
return target;
}
Index: src/libexec/ld.elf_so/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.185 src/libexec/ld.elf_so/rtld.c:1.186
--- src/libexec/ld.elf_so/rtld.c:1.185 Tue Jul 11 15:21:35 2017
+++ src/libexec/ld.elf_so/rtld.c Thu Aug 10 19:03:25 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.185 2017/07/11 15:21:35 joerg Exp $ */
+/* $NetBSD: rtld.c,v 1.186 2017/08/10 19:03:25 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.185 2017/07/11 15:21:35 joerg Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.186 2017/08/10 19:03:25 joerg Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -273,7 +273,20 @@ restart:
SIMPLEQ_INIT(&initlist);
_rtld_initlist_tsort(&initlist, 0);
- /* First pass: objects marked with DF_1_INITFIRST. */
+ /* First pass: objects with IRELATIVE relocations. */
+ SIMPLEQ_FOREACH(elm, &initlist, link) {
+ Obj_Entry * const obj = elm->obj;
+ if (obj->ifunc_remaining) {
+ _rtld_call_ifunc(obj, mask, cur_objgen);
+ if (_rtld_objgen != 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) {
Obj_Entry * const obj = elm->obj;
if (obj->z_initfirst) {
@@ -286,7 +299,7 @@ restart:
}
}
- /* Second pass: all other objects. */
+ /* Third pass: all other objects. */
SIMPLEQ_FOREACH(elm, &initlist, link) {
_rtld_call_init_function(elm->obj, mask, cur_objgen);
if (_rtld_objgen != cur_objgen) {
Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.129 src/libexec/ld.elf_so/rtld.h:1.130
--- src/libexec/ld.elf_so/rtld.h:1.129 Tue Jul 11 15:21:35 2017
+++ src/libexec/ld.elf_so/rtld.h Thu Aug 10 19:03:25 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.h,v 1.129 2017/07/11 15:21:35 joerg Exp $ */
+/* $NetBSD: rtld.h,v 1.130 2017/08/10 19:03:25 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -298,6 +298,8 @@ typedef struct Struct_Obj_Entry {
size_t init_arraysz; /* # of entries in it */
Elf_Addr *fini_array; /* start of fini array */
size_t fini_arraysz; /* # of entries in it */
+ /* IRELATIVE relocations */
+ size_t ifunc_remaining;
size_t cxa_refcount; /* For TLS destructors. */
#ifdef __ARM_EABI__
void *exidx_start;
@@ -328,6 +330,7 @@ extern bool _rtld_trust;
extern Objlist _rtld_list_global;
extern Objlist _rtld_list_main;
extern Elf_Sym _rtld_sym_zero;
+extern u_int _rtld_objgen;
#define RTLD_MODEMASK 0x3
@@ -407,10 +410,13 @@ int _rtld_sysctl(const char *, void *, s
int _rtld_do_copy_relocations(const Obj_Entry *);
int _rtld_relocate_objects(Obj_Entry *, bool);
int _rtld_relocate_nonplt_objects(Obj_Entry *);
-int _rtld_relocate_plt_lazy(const Obj_Entry *);
+int _rtld_relocate_plt_lazy(Obj_Entry *);
int _rtld_relocate_plt_objects(const Obj_Entry *);
void _rtld_setup_pltgot(const Obj_Entry *);
Elf_Addr _rtld_resolve_ifunc(const Obj_Entry *, const Elf_Sym *);
+Elf_Addr _rtld_resolve_ifunc2(const Obj_Entry *, Elf_Addr);
+
+void _rtld_call_ifunc(Obj_Entry *, sigset_t *, u_int);
/* search.c */
Obj_Entry *_rtld_load_library(const char *, const Obj_Entry *, int);
Index: src/libexec/ld.elf_so/arch/aarch64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.3 src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.4
--- src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.3 Mon Jun 19 11:57:01 2017
+++ src/libexec/ld.elf_so/arch/aarch64/mdreloc.c Thu Aug 10 19:03:25 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:01 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.4 2017/08/10 19:03:25 joerg Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:01 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.4 2017/08/10 19:03:25 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -190,7 +190,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
if (!obj->relocbase)
Index: src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c
diff -u src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.42 src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.43
--- src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.42 Mon Jun 19 11:57:01 2017
+++ src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c Thu Aug 10 19:03:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: alpha_reloc.c,v 1.42 2017/06/19 11:57:01 joerg Exp $ */
+/* $NetBSD: alpha_reloc.c,v 1.43 2017/08/10 19:03:26 joerg Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -62,7 +62,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: alpha_reloc.c,v 1.42 2017/06/19 11:57:01 joerg Exp $");
+__RCSID("$NetBSD: alpha_reloc.c,v 1.43 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -343,7 +343,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rela *rela;
Index: src/libexec/ld.elf_so/arch/arm/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.41 src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.42
--- src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.41 Tue Jun 20 12:41:49 2017
+++ src/libexec/ld.elf_so/arch/arm/mdreloc.c Thu Aug 10 19:03:26 2017
@@ -1,8 +1,8 @@
-/* $NetBSD: mdreloc.c,v 1.41 2017/06/20 12:41:49 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.42 2017/08/10 19:03:26 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.41 2017/06/20 12:41:49 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.42 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -253,17 +253,21 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rel *rel;
if (!obj->relocbase)
return 0;
- for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
+ for (rel = obj->pltrellim; rel-- > obj->pltrel; ) {
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
- assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JUMP_SLOT));
+ assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JUMP_SLOT) ||
+ ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE));
+
+ if (ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE))
+ obj->ifunc_remaining = obj->pltrellim - rel;
/* Just relocate the GOT slots pointing into the PLT */
*where += (Elf_Addr)obj->relocbase;
@@ -273,6 +277,26 @@ _rtld_relocate_plt_lazy(const Obj_Entry
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/hppa/hppa_reloc.c
diff -u src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.44 src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.45
--- src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.44 Mon Jun 19 11:57:01 2017
+++ src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c Thu Aug 10 19:03:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: hppa_reloc.c,v 1.44 2017/06/19 11:57:01 joerg Exp $ */
+/* $NetBSD: hppa_reloc.c,v 1.45 2017/08/10 19:03:26 joerg Exp $ */
/*-
* Copyright (c) 2002, 2004 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: hppa_reloc.c,v 1.44 2017/06/19 11:57:01 joerg Exp $");
+__RCSID("$NetBSD: hppa_reloc.c,v 1.45 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <stdlib.h>
@@ -589,7 +589,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rela *rela;
Index: src/libexec/ld.elf_so/arch/i386/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.38 src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.39
--- src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.38 Mon Jun 19 11:57:01 2017
+++ src/libexec/ld.elf_so/arch/i386/mdreloc.c Thu Aug 10 19:03:26 2017
@@ -1,8 +1,8 @@
-/* $NetBSD: mdreloc.c,v 1.38 2017/06/19 11:57:01 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.39 2017/08/10 19:03:26 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.38 2017/06/19 11:57:01 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.39 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -194,17 +194,21 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rel *rel;
if (!obj->relocbase)
return 0;
- for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
+ for (rel = obj->pltrellim; rel-- > obj->pltrel; ) {
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
- assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));
+ assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT) ||
+ ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE));
+
+ if (ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE))
+ obj->ifunc_remaining = obj->pltrellim - rel;
/* Just relocate the GOT slots pointing into the PLT */
*where += (Elf_Addr)obj->relocbase;
@@ -214,6 +218,26 @@ _rtld_relocate_plt_lazy(const Obj_Entry
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)
@@ -224,6 +248,9 @@ _rtld_relocate_plt_object(const Obj_Entr
const Obj_Entry *defobj;
unsigned long info = rel->r_info;
+ if (ELF_R_TYPE(info) == R_TYPE(IRELATIVE))
+ return 0;
+
assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT));
def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL);
Index: src/libexec/ld.elf_so/arch/m68k/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.32 src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.33
--- src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.32 Mon Jun 19 11:57:01 2017
+++ src/libexec/ld.elf_so/arch/m68k/mdreloc.c Thu Aug 10 19:03:26 2017
@@ -1,8 +1,8 @@
-/* $NetBSD: mdreloc.c,v 1.32 2017/06/19 11:57:01 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.33 2017/08/10 19:03:26 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.32 2017/06/19 11:57:01 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.33 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -181,7 +181,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rela *rela;
Index: src/libexec/ld.elf_so/arch/mips/mips_reloc.c
diff -u src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.68 src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.69
--- src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.68 Wed Jun 21 12:34:01 2017
+++ src/libexec/ld.elf_so/arch/mips/mips_reloc.c Thu Aug 10 19:03:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_reloc.c,v 1.68 2017/06/21 12:34:01 joerg Exp $ */
+/* $NetBSD: mips_reloc.c,v 1.69 2017/08/10 19:03:26 joerg Exp $ */
/*
* Copyright 1997 Michael L. Hitch <[email protected]>
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mips_reloc.c,v 1.68 2017/06/21 12:34:01 joerg Exp $");
+__RCSID("$NetBSD: mips_reloc.c,v 1.69 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -480,7 +480,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
/* PLT fixups were done above in the GOT relocation. */
return 0;
Index: src/libexec/ld.elf_so/arch/or1k/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/or1k/mdreloc.c:1.2 src/libexec/ld.elf_so/arch/or1k/mdreloc.c:1.3
--- src/libexec/ld.elf_so/arch/or1k/mdreloc.c:1.2 Mon Jun 19 11:57:02 2017
+++ src/libexec/ld.elf_so/arch/or1k/mdreloc.c Thu Aug 10 19:03:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.2 2017/06/19 11:57:02 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.3 2017/08/10 19:03:26 joerg Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.2 2017/06/19 11:57:02 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.3 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <stdarg.h>
@@ -210,7 +210,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rela *rela;
int reloff;
Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.54 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.55
--- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.54 Mon Jun 19 11:57:02 2017
+++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Thu Aug 10 19:03:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ppc_reloc.c,v 1.54 2017/06/19 11:57:02 joerg Exp $ */
+/* $NetBSD: ppc_reloc.c,v 1.55 2017/08/10 19:03:26 joerg Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: ppc_reloc.c,v 1.54 2017/06/19 11:57:02 joerg Exp $");
+__RCSID("$NetBSD: ppc_reloc.c,v 1.55 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <stdarg.h>
@@ -303,24 +303,31 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
#ifdef _LP64
/*
* For PowerPC64, the plt stubs handle an empty function descriptor
* so there's nothing to do.
*/
+ /* XXX ifunc support */
#else
Elf_Addr * const pltresolve = obj->pltgot + 8;
const Elf_Rela *rela;
int reloff;
- for (rela = obj->pltrela, reloff = 0;
- rela < obj->pltrelalim;
- rela++, reloff++) {
+ rela = obj->pltrelalim;
+ for (reloff = rela - obj->pltrela; rela-- > obj->pltrela; --reloff) {
Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
- assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
+ assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JUMP_SLOT) ||
+ ELF_R_TYPE(rela->r_info) == R_TYPE(IRELATIVE));
+
+ if (ELF_R_TYPE(rela->r_info) == R_TYPE(IRELATIVE)) {
+ /* No ifunc support for old-style insecure PLT. */
+ assert(obj->gotptr != NULL);
+ obj->ifunc_remaining = obj->pltrelalim - rela;
+ }
if (obj->gotptr != NULL) {
/*
@@ -357,6 +364,27 @@ _rtld_relocate_plt_lazy(const Obj_Entry
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 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/riscv/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/riscv/mdreloc.c:1.3 src/libexec/ld.elf_so/arch/riscv/mdreloc.c:1.4
--- src/libexec/ld.elf_so/arch/riscv/mdreloc.c:1.3 Mon Jun 19 11:57:02 2017
+++ src/libexec/ld.elf_so/arch/riscv/mdreloc.c Thu Aug 10 19:03:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:02 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.4 2017/08/10 19:03:26 joerg Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:02 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.4 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -198,7 +198,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
/* PLT fixups were done above in the GOT relocation. */
return 0;
Index: src/libexec/ld.elf_so/arch/sh3/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.34 src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.35
--- src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.34 Tue Jun 20 13:45:20 2017
+++ src/libexec/ld.elf_so/arch/sh3/mdreloc.c Thu Aug 10 19:03:26 2017
@@ -1,8 +1,8 @@
-/* $NetBSD: mdreloc.c,v 1.34 2017/06/20 13:45:20 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.35 2017/08/10 19:03:26 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.34 2017/06/20 13:45:20 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.35 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -204,7 +204,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rela *rela;
Index: src/libexec/ld.elf_so/arch/sparc/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.50 src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.51
--- src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.50 Mon Jun 19 11:57:02 2017
+++ src/libexec/ld.elf_so/arch/sparc/mdreloc.c Thu Aug 10 19:03:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.50 2017/06/19 11:57:02 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.51 2017/08/10 19:03:26 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.50 2017/06/19 11:57:02 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.51 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <errno.h>
@@ -385,7 +385,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
return (0);
}
Index: src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.63 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.64
--- src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.63 Mon Jul 24 08:08:34 2017
+++ src/libexec/ld.elf_so/arch/sparc64/mdreloc.c Thu Aug 10 19:03:26 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.63 2017/07/24 08:08:34 martin Exp $ */
+/* $NetBSD: mdreloc.c,v 1.64 2017/08/10 19:03:26 joerg Exp $ */
/*-
* Copyright (c) 2000 Eduardo Horvath.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.63 2017/07/24 08:08:34 martin Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.64 2017/08/10 19:03:26 joerg Exp $");
#endif /* not lint */
#include <errno.h>
@@ -505,7 +505,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
return (0);
}
Index: src/libexec/ld.elf_so/arch/vax/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.33 src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.34
--- src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.33 Tue Jun 20 15:02:54 2017
+++ src/libexec/ld.elf_so/arch/vax/mdreloc.c Thu Aug 10 19:03:27 2017
@@ -1,8 +1,8 @@
-/* $NetBSD: mdreloc.c,v 1.33 2017/06/20 15:02:54 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.34 2017/08/10 19:03:27 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.33 2017/06/20 15:02:54 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.34 2017/08/10 19:03:27 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -136,7 +136,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rela *rela;
Index: src/libexec/ld.elf_so/arch/x86_64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.44 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.45
--- src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.44 Wed Jul 12 17:55:24 2017
+++ src/libexec/ld.elf_so/arch/x86_64/mdreloc.c Thu Aug 10 19:03:27 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.44 2017/07/12 17:55:24 christos Exp $ */
+/* $NetBSD: mdreloc.c,v 1.45 2017/08/10 19:03: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.44 2017/07/12 17:55:24 christos Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.45 2017/08/10 19:03:27 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -278,17 +278,21 @@ _rtld_relocate_nonplt_objects(Obj_Entry
}
int
-_rtld_relocate_plt_lazy(const Obj_Entry *obj)
+_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
const Elf_Rela *rela;
if (!obj->relocbase)
return 0;
- for (rela = obj->pltrela; rela < obj->pltrelalim; rela++) {
+ for (rela = obj->pltrelalim; rela-- > obj->pltrela; ) {
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
- assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JUMP_SLOT));
+ assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JUMP_SLOT) ||
+ ELF_R_TYPE(rela->r_info) == R_TYPE(IRELATIVE));
+
+ if (ELF_R_TYPE(rela->r_info) == R_TYPE(IRELATIVE))
+ obj->ifunc_remaining = obj->pltrelalim - rela;
/* Just relocate the GOT slots pointing into the PLT */
*where += (Elf_Addr)obj->relocbase;
@@ -298,6 +302,27 @@ _rtld_relocate_plt_lazy(const Obj_Entry
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)
{
@@ -307,6 +332,9 @@ _rtld_relocate_plt_object(const Obj_Entr
const Obj_Entry *defobj;
unsigned long info = rela->r_info;
+ if (ELF_R_TYPE(info) == R_TYPE(IRELATIVE))
+ return 0;
+
assert(ELF_R_TYPE(info) == R_TYPE(JUMP_SLOT));
def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL);
Index: src/sys/arch/arm/include/elf_machdep.h
diff -u src/sys/arch/arm/include/elf_machdep.h:1.17 src/sys/arch/arm/include/elf_machdep.h:1.18
--- src/sys/arch/arm/include/elf_machdep.h:1.17 Tue Feb 25 19:20:09 2014
+++ src/sys/arch/arm/include/elf_machdep.h Thu Aug 10 19:03:27 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: elf_machdep.h,v 1.17 2014/02/25 19:20:09 matt Exp $ */
+/* $NetBSD: elf_machdep.h,v 1.18 2017/08/10 19:03:27 joerg Exp $ */
#ifndef _ARM_ELF_MACHDEP_H_
#define _ARM_ELF_MACHDEP_H_
@@ -119,6 +119,8 @@
/* 112-127 are reserved for private experiments. */
+#define R_ARM_IRELATIVE 160
+
#define R_ARM_RXPC25 249
#define R_ARM_RSBREL32 250
#define R_ARM_THM_RPC22 251
Index: src/sys/arch/powerpc/include/elf_machdep.h
diff -u src/sys/arch/powerpc/include/elf_machdep.h:1.12 src/sys/arch/powerpc/include/elf_machdep.h:1.13
--- src/sys/arch/powerpc/include/elf_machdep.h:1.12 Fri Mar 7 04:11:07 2014
+++ src/sys/arch/powerpc/include/elf_machdep.h Thu Aug 10 19:03:27 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: elf_machdep.h,v 1.12 2014/03/07 04:11:07 matt Exp $ */
+/* $NetBSD: elf_machdep.h,v 1.13 2017/08/10 19:03:27 joerg Exp $ */
#ifndef _POWERPC_ELF_MACHDEP_H_
#define _POWERPC_ELF_MACHDEP_H_
@@ -198,6 +198,9 @@
#define R_PPC_DTPREL16_HIGHEST 105 // #highest(@dtprel)
#define R_PPC_DTPREL16_HIGHESTA 106 // #highesta(@dtprel)
+/* Indirect-function support */
+#define R_PPC_IRELATIVE 248
+
/* Used for the secure-plt PIC code sequences */
#define R_PPC_REL16 249 // S + A - P
#define R_PPC_REL16_LO 250 // #lo(S + A - P)
Index: src/sys/sys/cdefs_elf.h
diff -u src/sys/sys/cdefs_elf.h:1.52 src/sys/sys/cdefs_elf.h:1.53
--- src/sys/sys/cdefs_elf.h:1.52 Tue Jun 7 12:09:29 2016
+++ src/sys/sys/cdefs_elf.h Thu Aug 10 19:03:27 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: cdefs_elf.h,v 1.52 2016/06/07 12:09:29 joerg Exp $ */
+/* $NetBSD: cdefs_elf.h,v 1.53 2017/08/10 19:03:27 joerg Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -117,11 +117,21 @@
__asm(".globl " _C_LABEL_STRING(#name) "\n" \
".type " _C_LABEL_STRING(#name) ", %gnu_indirect_function\n" \
_C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
+#define __hidden_ifunc(name, resolver) \
+ __asm(".globl " _C_LABEL_STRING(#name) "\n" \
+ ".hidden " _C_LABEL_STRING(#name) "\n" \
+ ".type " _C_LABEL_STRING(#name) ", %gnu_indirect_function\n" \
+ _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
#else
#define __ifunc(name, resolver) \
__asm(".globl " _C_LABEL_STRING(#name) "\n" \
".type " _C_LABEL_STRING(#name) ", @gnu_indirect_function\n" \
_C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
+#define __hidden_ifunc(name, resolver) \
+ __asm(".globl " _C_LABEL_STRING(#name) "\n" \
+ ".hidden " _C_LABEL_STRING(#name) "\n" \
+ ".type " _C_LABEL_STRING(#name) ", @gnu_indirect_function\n" \
+ _C_LABEL_STRING(#name) " = " _C_LABEL_STRING(#resolver))
#endif
#if __STDC__
Index: src/tests/libexec/ld.elf_so/t_ifunc.c
diff -u src/tests/libexec/ld.elf_so/t_ifunc.c:1.2 src/tests/libexec/ld.elf_so/t_ifunc.c:1.3
--- src/tests/libexec/ld.elf_so/t_ifunc.c:1.2 Fri Jan 13 21:30:42 2017
+++ src/tests/libexec/ld.elf_so/t_ifunc.c Thu Aug 10 19:03:27 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: t_ifunc.c,v 1.2 2017/01/13 21:30:42 christos Exp $ */
+/* $NetBSD: t_ifunc.c,v 1.3 2017/08/10 19:03:27 joerg Exp $ */
/*
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -56,6 +56,10 @@ ATF_TC_BODY(rtld_ifunc, tc)
const char *error;
size_t i;
+#if !defined( __arm__) && !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__)
+ atf_tc_expect_fail("Missing linker support for hidden ifunc relocations");
+#endif
+
for (i = 0; i < __arraycount(envstr); ++i) {
setenv("USE_IFUNC2", envstr[i], 1);
@@ -85,8 +89,59 @@ ATF_TC_BODY(rtld_ifunc, tc)
}
}
+ATF_TC(rtld_hidden_ifunc);
+
+ATF_TC_HEAD(rtld_hidden_ifunc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "hidden ifunc functions are resolved");
+}
+
+ATF_TC_BODY(rtld_hidden_ifunc, tc)
+{
+ const char *envstr[] = {
+ "0", "1"
+ };
+ int expected_result[] = {
+ 0xdeadbeef, 0xbeefdead
+ };
+ void *handle;
+ int (*sym)(void);
+ int result;
+ const char *error;
+ size_t i;
+
+ for (i = 0; i < __arraycount(envstr); ++i) {
+ setenv("USE_IFUNC2", envstr[i], 1);
+
+ handle = dlopen("libh_helper_ifunc_dso.so", RTLD_LAZY);
+ error = dlerror();
+ ATF_CHECK(error == NULL);
+ ATF_CHECK(handle != NULL);
+
+ sym = dlsym(handle, "ifunc_plt");
+ error = dlerror();
+ ATF_CHECK(error == NULL);
+ ATF_CHECK(sym != NULL);
+
+ result = (*sym)();
+ ATF_CHECK(result == expected_result[!i]);
+
+ dlclose(handle);
+ error = dlerror();
+ ATF_CHECK(error == NULL);
+
+ char *command;
+ easprintf(&command, "%s/h_ifunc %d",
+ atf_tc_get_config_var(tc, "srcdir"), expected_result[i]);
+ if (system(command) != EXIT_SUCCESS)
+ atf_tc_fail("Test failed; see output for details");
+ free(command);
+ }
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, rtld_ifunc);
+ ATF_TP_ADD_TC(tp, rtld_hidden_ifunc);
return 0;
}
Index: src/tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.c
diff -u src/tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.c:1.4 src/tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.c:1.5
--- src/tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.c:1.4 Tue Aug 26 17:13:42 2014
+++ src/tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.c Thu Aug 10 19:03:27 2017
@@ -49,4 +49,20 @@ int (*resolve_ifunc(void))(void)
return e && strcmp(e, "1") == 0 ? ifunc2 : ifunc1;
}
+static __attribute__((used))
+int (*resolve_ifunc2(void))(void)
+{
+ const char *e = getenv("USE_IFUNC2");
+ return e && strcmp(e, "1") == 0 ? ifunc1 : ifunc2;
+}
+
__ifunc(ifunc, resolve_ifunc);
+__hidden_ifunc(ifunc_hidden, resolve_ifunc2);
+
+int ifunc_hidden(void);
+int ifunc_plt(void);
+
+int ifunc_plt(void)
+{
+ return ifunc_hidden();
+}