Module Name: src
Committed By: martin
Date: Sun Mar 6 18:17:56 UTC 2016
Modified Files:
src/libexec/ld.elf_so [netbsd-7]: headers.c map_object.c paths.c
reloc.c rtld.c rtld.h
src/libexec/ld.elf_so/arch/aarch64 [netbsd-7]: mdreloc.c
src/libexec/ld.elf_so/arch/alpha [netbsd-7]: alpha_reloc.c
src/libexec/ld.elf_so/arch/arm [netbsd-7]: mdreloc.c
src/libexec/ld.elf_so/arch/hppa [netbsd-7]: hppa_reloc.c
src/libexec/ld.elf_so/arch/i386 [netbsd-7]: mdreloc.c
src/libexec/ld.elf_so/arch/m68k [netbsd-7]: mdreloc.c
src/libexec/ld.elf_so/arch/mips [netbsd-7]: mips_reloc.c
src/libexec/ld.elf_so/arch/powerpc [netbsd-7]: ppc_reloc.c
src/libexec/ld.elf_so/arch/sh3 [netbsd-7]: mdreloc.c
src/libexec/ld.elf_so/arch/sparc [netbsd-7]: mdreloc.c
src/libexec/ld.elf_so/arch/sparc64 [netbsd-7]: mdreloc.c
src/libexec/ld.elf_so/arch/vax [netbsd-7]: mdreloc.c
src/libexec/ld.elf_so/arch/x86_64 [netbsd-7]: mdreloc.c
Log Message:
Catch up to -current, via patch, requested by christos in ticket #1126:
To generate a diff of this commit:
cvs rdiff -u -r1.54 -r1.54.4.1 src/libexec/ld.elf_so/headers.c
cvs rdiff -u -r1.52 -r1.52.4.1 src/libexec/ld.elf_so/map_object.c
cvs rdiff -u -r1.41 -r1.41.6.1 src/libexec/ld.elf_so/paths.c
cvs rdiff -u -r1.106 -r1.106.18.1 src/libexec/ld.elf_so/reloc.c
cvs rdiff -u -r1.173.4.2 -r1.173.4.3 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.118 -r1.118.2.1 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.1 -r1.1.2.1 src/libexec/ld.elf_so/arch/aarch64/mdreloc.c
cvs rdiff -u -r1.40 -r1.40.22.1 \
src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c
cvs rdiff -u -r1.37 -r1.37.18.1 src/libexec/ld.elf_so/arch/arm/mdreloc.c
cvs rdiff -u -r1.42 -r1.42.18.1 src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c
cvs rdiff -u -r1.35 -r1.35.8.1 src/libexec/ld.elf_so/arch/i386/mdreloc.c
cvs rdiff -u -r1.29 -r1.29.18.1 src/libexec/ld.elf_so/arch/m68k/mdreloc.c
cvs rdiff -u -r1.62 -r1.62.22.1 src/libexec/ld.elf_so/arch/mips/mips_reloc.c
cvs rdiff -u -r1.52 -r1.52.2.1 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
cvs rdiff -u -r1.30 -r1.30.22.1 src/libexec/ld.elf_so/arch/sh3/mdreloc.c
cvs rdiff -u -r1.47 -r1.47.22.1 src/libexec/ld.elf_so/arch/sparc/mdreloc.c
cvs rdiff -u -r1.56 -r1.56.4.1 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
cvs rdiff -u -r1.29 -r1.29.4.1 src/libexec/ld.elf_so/arch/vax/mdreloc.c
cvs rdiff -u -r1.40 -r1.40.22.1 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/headers.c
diff -u src/libexec/ld.elf_so/headers.c:1.54 src/libexec/ld.elf_so/headers.c:1.54.4.1
--- src/libexec/ld.elf_so/headers.c:1.54 Fri Mar 7 01:27:14 2014
+++ src/libexec/ld.elf_so/headers.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: headers.c,v 1.54 2014/03/07 01:27:14 matt Exp $ */
+/* $NetBSD: headers.c,v 1.54.4.1 2016/03/06 18:17:55 martin Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: headers.c,v 1.54 2014/03/07 01:27:14 matt Exp $");
+__RCSID("$NetBSD: headers.c,v 1.54.4.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <err.h>
@@ -74,7 +74,9 @@ _rtld_digest_dynamic(const char *execnam
bool use_pltrela = false;
Elf_Addr relsz = 0, relasz = 0;
Elf_Addr pltrel = 0, pltrelsz = 0;
+#ifdef RTLD_LOADER
Elf_Addr init = 0, fini = 0;
+#endif
dbg(("headers: digesting PT_DYNAMIC at %p", obj->dynamic));
for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; ++dynp) {
@@ -227,13 +229,15 @@ _rtld_digest_dynamic(const char *execnam
break;
case DT_INIT:
+#ifdef RTLD_LOADER
init = dynp->d_un.d_ptr;
+#endif
break;
#ifdef HAVE_INITFINI_ARRAY
case DT_INIT_ARRAY:
obj->init_array =
- (fptr_t *)(obj->relocbase + dynp->d_un.d_ptr);
+ (Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
dbg(("headers: DT_INIT_ARRAY at %p",
obj->init_array));
break;
@@ -246,13 +250,15 @@ _rtld_digest_dynamic(const char *execnam
#endif
case DT_FINI:
+#ifdef RTLD_LOADER
fini = dynp->d_un.d_ptr;
+#endif
break;
#ifdef HAVE_INITFINI_ARRAY
case DT_FINI_ARRAY:
obj->fini_array =
- (fptr_t *)(obj->relocbase + dynp->d_un.d_ptr);
+ (Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
dbg(("headers: DT_FINI_ARRAY at %p",
obj->fini_array));
break;
@@ -345,20 +351,11 @@ _rtld_digest_dynamic(const char *execnam
obj->relalim = obj->pltrela;
}
-#if defined(RTLD_LOADER) && defined(__HAVE_FUNCTION_DESCRIPTORS)
- if (init != 0)
- obj->init = (void (*)(void))
- _rtld_function_descriptor_alloc(obj, NULL, init);
- if (fini != 0)
- obj->fini = (void (*)(void))
- _rtld_function_descriptor_alloc(obj, NULL, fini);
-#else
+#ifdef RTLD_LOADER
if (init != 0)
- obj->init = (void (*)(void))
- (obj->relocbase + init);
+ obj->init = (Elf_Addr) obj->relocbase + init;
if (fini != 0)
- obj->fini = (void (*)(void))
- (obj->relocbase + fini);
+ obj->fini = (Elf_Addr) obj->relocbase + fini;
#endif
if (dyn_rpath != NULL) {
Index: src/libexec/ld.elf_so/map_object.c
diff -u src/libexec/ld.elf_so/map_object.c:1.52 src/libexec/ld.elf_so/map_object.c:1.52.4.1
--- src/libexec/ld.elf_so/map_object.c:1.52 Sat Aug 3 13:17:05 2013
+++ src/libexec/ld.elf_so/map_object.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: map_object.c,v 1.52 2013/08/03 13:17:05 skrll Exp $ */
+/* $NetBSD: map_object.c,v 1.52.4.1 2016/03/06 18:17:55 martin Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: map_object.c,v 1.52 2013/08/03 13:17:05 skrll Exp $");
+__RCSID("$NetBSD: map_object.c,v 1.52.4.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <errno.h>
@@ -442,10 +442,10 @@ _rtld_obj_free(Obj_Entry *obj)
}
if (!obj->phdr_loaded)
xfree((void *)(uintptr_t)obj->phdr);
- xfree(obj);
#ifdef COMBRELOC
_rtld_combreloc_reset(obj);
#endif
+ xfree(obj);
}
Obj_Entry *
Index: src/libexec/ld.elf_so/paths.c
diff -u src/libexec/ld.elf_so/paths.c:1.41 src/libexec/ld.elf_so/paths.c:1.41.6.1
--- src/libexec/ld.elf_so/paths.c:1.41 Mon May 6 08:02:20 2013
+++ src/libexec/ld.elf_so/paths.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: paths.c,v 1.41 2013/05/06 08:02:20 skrll Exp $ */
+/* $NetBSD: paths.c,v 1.41.6.1 2016/03/06 18:17:55 martin Exp $ */
/*
* Copyright 1996 Matt Thomas <[email protected]>
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: paths.c,v 1.41 2013/05/06 08:02:20 skrll Exp $");
+__RCSID("$NetBSD: paths.c,v 1.41.6.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <err.h>
@@ -49,7 +49,6 @@ __RCSID("$NetBSD: paths.c,v 1.41 2013/05
#include <sys/gmon.h>
#include <sys/socket.h>
#include <sys/mount.h>
-#include <sys/mbuf.h>
#include <sys/resource.h>
#include <machine/cpu.h>
Index: src/libexec/ld.elf_so/reloc.c
diff -u src/libexec/ld.elf_so/reloc.c:1.106 src/libexec/ld.elf_so/reloc.c:1.106.18.1
--- src/libexec/ld.elf_so/reloc.c:1.106 Fri Jan 6 10:38:56 2012
+++ src/libexec/ld.elf_so/reloc.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: reloc.c,v 1.106 2012/01/06 10:38:56 skrll Exp $ */
+/* $NetBSD: reloc.c,v 1.106.18.1 2016/03/06 18:17:55 martin Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.106 2012/01/06 10:38:56 skrll Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.106.18.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <err.h>
@@ -226,3 +226,16 @@ _rtld_relocate_objects(Obj_Entry *first,
return 0;
}
+
+Elf_Addr
+_rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def)
+{
+ Elf_Addr target;
+
+ _rtld_shared_exit();
+ target = _rtld_call_function_addr(obj,
+ (Elf_Addr)obj->relocbase + def->st_value);
+ _rtld_shared_enter();
+
+ return target;
+}
Index: src/libexec/ld.elf_so/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.173.4.2 src/libexec/ld.elf_so/rtld.c:1.173.4.3
--- src/libexec/ld.elf_so/rtld.c:1.173.4.2 Mon Apr 6 02:01:39 2015
+++ src/libexec/ld.elf_so/rtld.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.173.4.2 2015/04/06 02:01:39 snj Exp $ */
+/* $NetBSD: rtld.c,v 1.173.4.3 2016/03/06 18:17:55 martin Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.173.4.2 2015/04/06 02:01:39 snj Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.173.4.3 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -136,25 +136,25 @@ static void _rtld_unref_dag(Obj_Entry *)
static Obj_Entry *_rtld_obj_from_addr(const void *);
static inline void
-_rtld_call_initfini_function(fptr_t func, sigset_t *mask)
+_rtld_call_initfini_function(const Obj_Entry *obj, Elf_Addr func, sigset_t *mask)
{
_rtld_exclusive_exit(mask);
- (*func)();
+ _rtld_call_function_void(obj, func);
_rtld_exclusive_enter(mask);
}
static void
_rtld_call_fini_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
{
- if (obj->fini_arraysz == 0 && (obj->fini == NULL || obj->fini_called)) {
- return;
- }
- if (obj->fini != NULL && !obj->fini_called) {
+ if (obj->fini_arraysz == 0 && (obj->fini == 0 || obj->fini_called))
+ return;
+
+ if (obj->fini != 0 && !obj->fini_called) {
dbg (("calling fini function %s at %p%s", obj->path,
(void *)obj->fini,
obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
obj->fini_called = 1;
- _rtld_call_initfini_function(obj->fini, mask);
+ _rtld_call_initfini_function(obj, obj->fini, mask);
}
#ifdef HAVE_INITFINI_ARRAY
/*
@@ -164,12 +164,12 @@ _rtld_call_fini_function(Obj_Entry *obj,
* the loop.
*/
while (obj->fini_arraysz > 0 && _rtld_objgen == cur_objgen) {
- fptr_t fini = *obj->fini_array++;
+ Elf_Addr fini = *obj->fini_array++;
obj->fini_arraysz--;
dbg (("calling fini array function %s at %p%s", obj->path,
(void *)fini,
obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
- _rtld_call_initfini_function(fini, mask);
+ _rtld_call_initfini_function(obj, fini, mask);
}
#endif /* HAVE_INITFINI_ARRAY */
}
@@ -230,15 +230,15 @@ restart:
static void
_rtld_call_init_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
{
- if (obj->init_arraysz == 0 && (obj->init_called || obj->init == NULL)) {
+ if (obj->init_arraysz == 0 && (obj->init_called || obj->init == 0))
return;
- }
- if (!obj->init_called && obj->init != NULL) {
+
+ if (!obj->init_called && obj->init != 0) {
dbg (("calling init function %s at %p%s",
obj->path, (void *)obj->init,
obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
obj->init_called = 1;
- _rtld_call_initfini_function(obj->init, mask);
+ _rtld_call_initfini_function(obj, obj->init, mask);
}
#ifdef HAVE_INITFINI_ARRAY
@@ -249,12 +249,12 @@ _rtld_call_init_function(Obj_Entry *obj,
* the loop.
*/
while (obj->init_arraysz > 0 && _rtld_objgen == cur_objgen) {
- fptr_t init = *obj->init_array++;
+ Elf_Addr init = *obj->init_array++;
obj->init_arraysz--;
dbg (("calling init_array function %s at %p%s",
obj->path, (void *)init,
obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
- _rtld_call_initfini_function(init, mask);
+ _rtld_call_initfini_function(obj, init, mask);
}
#endif /* HAVE_INITFINI_ARRAY */
}
@@ -1176,6 +1176,17 @@ do_dlsym(void *handle, const char *name,
if (def != NULL) {
void *p;
+
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+#ifdef __HAVE_FUNCTION_DESCRIPTORS
+ lookup_mutex_exit();
+ _rtld_shared_enter();
+#endif
+ p = (void *)_rtld_resolve_ifunc(defobj, def);
+ _rtld_shared_exit();
+ return p;
+ }
+
#ifdef __HAVE_FUNCTION_DESCRIPTORS
if (ELF_ST_TYPE(def->st_info) == STT_FUNC) {
p = (void *)_rtld_function_descriptor_alloc(defobj,
@@ -1533,6 +1544,7 @@ _rtld_shared_enter(void)
/* Yes, so increment use counter */
if (atomic_cas_uint(&_rtld_mutex, cur, cur + 1) != cur)
continue;
+ membar_enter();
return;
}
/*
@@ -1550,6 +1562,7 @@ _rtld_shared_enter(void)
/*
* Check for race against _rtld_exclusive_exit before sleeping.
*/
+ membar_sync();
if ((_rtld_mutex & RTLD_EXCLUSIVE_MASK) ||
_rtld_waiter_exclusive)
_lwp_park(CLOCK_REALTIME, 0, NULL, 0,
@@ -1577,12 +1590,12 @@ _rtld_shared_exit(void)
* Wakeup LWPs waiting for an exclusive lock if this is the last
* LWP on the shared lock.
*/
+ membar_exit();
if (atomic_dec_uint_nv(&_rtld_mutex))
return;
+ membar_sync();
if ((waiter = _rtld_waiter_exclusive) != 0)
_lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
-
- membar_exit();
}
void
@@ -1597,12 +1610,13 @@ _rtld_exclusive_enter(sigset_t *mask)
sigdelset(&blockmask, SIGTRAP); /* Allow the debugger */
sigprocmask(SIG_BLOCK, &blockmask, mask);
- membar_enter();
-
for (;;) {
- if (atomic_cas_uint(&_rtld_mutex, 0, locked_value) == 0)
+ if (atomic_cas_uint(&_rtld_mutex, 0, locked_value) == 0) {
+ membar_enter();
break;
+ }
waiter = atomic_swap_uint(&_rtld_waiter_exclusive, self);
+ membar_sync();
cur = _rtld_mutex;
if (cur == locked_value) {
_rtld_error("dead lock detected");
@@ -1622,13 +1636,14 @@ _rtld_exclusive_exit(sigset_t *mask)
{
lwpid_t waiter;
+ membar_exit();
_rtld_mutex = 0;
+ membar_sync();
if ((waiter = _rtld_waiter_exclusive) != 0)
_lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
if ((waiter = _rtld_waiter_shared) != 0)
_lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
- membar_exit();
sigprocmask(SIG_SETMASK, mask, NULL);
}
Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.118 src/libexec/ld.elf_so/rtld.h:1.118.2.1
--- src/libexec/ld.elf_so/rtld.h:1.118 Sun Aug 10 23:35:26 2014
+++ src/libexec/ld.elf_so/rtld.h Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.h,v 1.118 2014/08/10 23:35:26 matt Exp $ */
+/* $NetBSD: rtld.h,v 1.118.2.1 2016/03/06 18:17:55 martin Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -179,7 +179,7 @@ typedef struct Struct_Obj_Entry {
const Elf_Sym *symtab; /* Symbol table */
const char *strtab; /* String table */
unsigned long strsize; /* Size in bytes of string table */
-#ifdef __mips__
+#if defined(__mips__) || defined(__riscv__)
Elf_Word local_gotno; /* Number of local GOT entries */
Elf_Word symtabno; /* Number of dynamic symbols */
Elf_Word gotsym; /* First dynamic symbol in GOT */
@@ -193,8 +193,8 @@ typedef struct Struct_Obj_Entry {
Search_Path *rpaths; /* Search path specified in object */
Needed_Entry *needed; /* Shared objects needed by this (%) */
- fptr_t init; /* Initialization function to call */
- fptr_t fini; /* Termination function to call */
+ Elf_Addr init; /* Initialization function to call */
+ Elf_Addr fini; /* Termination function to call */
/*
* BACKWARDS COMPAT Entry points for dlopen() and friends.
@@ -288,9 +288,9 @@ typedef struct Struct_Obj_Entry {
int vertabnum; /* Number of entries in vertab */
/* init_array/fini_array */
- fptr_t *init_array; /* start of init array */
+ Elf_Addr *init_array; /* start of init array */
size_t init_arraysz; /* # of entries in it */
- fptr_t *fini_array; /* start of fini array */
+ Elf_Addr *fini_array; /* start of fini array */
size_t fini_arraysz; /* # of entries in it */
#ifdef __ARM_EABI__
void *exidx_start;
@@ -326,7 +326,7 @@ extern Elf_Sym _rtld_sym_zero;
/* Flags to be passed into _rtld_symlook_ family of functions. */
#define SYMLOOK_IN_PLT 0x01 /* Lookup for PLT symbol */
-#define SYMLOOK_DLSYM 0x02 /* Return newes versioned symbol.
+#define SYMLOOK_DLSYM 0x02 /* Return newest versioned symbol.
Used by dlsym. */
/* Flags for _rtld_load_object() and friends. */
@@ -404,6 +404,7 @@ int _rtld_relocate_nonplt_objects(Obj_En
int _rtld_relocate_plt_lazy(const 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 *);
/* search.c */
Obj_Entry *_rtld_load_library(const char *, const Obj_Entry *, int);
@@ -474,12 +475,28 @@ Obj_Entry *_rtld_map_object(const char *
void _rtld_obj_free(Obj_Entry *);
Obj_Entry *_rtld_obj_new(void);
+#ifdef RTLD_LOADER
/* function descriptors */
#ifdef __HAVE_FUNCTION_DESCRIPTORS
Elf_Addr _rtld_function_descriptor_alloc(const Obj_Entry *,
const Elf_Sym *, Elf_Addr);
const void *_rtld_function_descriptor_function(const void *);
+
+void _rtld_call_function_void(const Obj_Entry *, Elf_Addr);
+Elf_Addr _rtld_call_function_addr(const Obj_Entry *, Elf_Addr);
+#else
+static inline void
+_rtld_call_function_void(const Obj_Entry *obj, Elf_Addr addr)
+{
+ ((void (*)(void))addr)();
+}
+static inline Elf_Addr
+_rtld_call_function_addr(const Obj_Entry *obj, Elf_Addr addr)
+{
+ return ((Elf_Addr(*)(void))addr)();
+}
#endif /* __HAVE_FUNCTION_DESCRIPTORS */
+#endif /* RTLD_LOADER */
#endif /* _RTLD_SOURCE */
Index: src/libexec/ld.elf_so/arch/aarch64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.1 src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.1.2.1
--- src/libexec/ld.elf_so/arch/aarch64/mdreloc.c:1.1 Sun Aug 10 05:47:37 2014
+++ src/libexec/ld.elf_so/arch/aarch64/mdreloc.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.1 2014/08/10 05:47:37 matt Exp $ */
+/* $NetBSD: mdreloc.c,v 1.1.2.1 2016/03/06 18:17:55 martin Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.1 2014/08/10 05:47:37 matt Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.1.2.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -222,7 +222,13 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ new_value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
Index: src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c
diff -u src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.40 src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.40.22.1
--- src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c:1.40 Thu Mar 31 15:30:31 2011
+++ src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: alpha_reloc.c,v 1.40 2011/03/31 15:30:31 skrll Exp $ */
+/* $NetBSD: alpha_reloc.c,v 1.40.22.1 2016/03/06 18:17:55 martin Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -62,7 +62,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: alpha_reloc.c,v 1.40 2011/03/31 15:30:31 skrll Exp $");
+__RCSID("$NetBSD: alpha_reloc.c,v 1.40.22.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -376,7 +376,13 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ new_value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
Index: src/libexec/ld.elf_so/arch/arm/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.37 src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.37.18.1
--- src/libexec/ld.elf_so/arch/arm/mdreloc.c:1.37 Fri Nov 18 16:10:03 2011
+++ src/libexec/ld.elf_so/arch/arm/mdreloc.c Sun Mar 6 18:17:55 2016
@@ -1,8 +1,8 @@
-/* $NetBSD: mdreloc.c,v 1.37 2011/11/18 16:10:03 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.37.18.1 2016/03/06 18:17:55 martin Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.37 2011/11/18 16:10:03 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.37.18.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -286,7 +286,13 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ new_value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
/* Set the Thumb bit, if needed. */
if (ELF_ST_TYPE(def->st_info) == STT_ARM_TFUNC)
new_value |= 1;
Index: src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c
diff -u src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.42 src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.42.18.1
--- src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c:1.42 Fri Jan 6 10:38:57 2012
+++ src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: hppa_reloc.c,v 1.42 2012/01/06 10:38:57 skrll Exp $ */
+/* $NetBSD: hppa_reloc.c,v 1.42.18.1 2016/03/06 18:17:55 martin 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.42 2012/01/06 10:38:57 skrll Exp $");
+__RCSID("$NetBSD: hppa_reloc.c,v 1.42.18.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <stdlib.h>
@@ -656,9 +656,19 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- func_pc = (Elf_Addr)(defobj->relocbase + def->st_value +
- rela->r_addend);
- func_sl = (Elf_Addr)(defobj->pltgot);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ Elf_Addr ptr = _rtld_resolve_ifunc(defobj, def);
+ assert(RTLD_IS_PLABEL(ptr));
+ hppa_plabel *label = RTLD_GET_PLABEL(ptr);
+ func_pc = label->hppa_plabel_pc;
+ func_sl = label->hppa_plabel_sl;
+ } else {
+ func_pc = (Elf_Addr)(defobj->relocbase + def->st_value +
+ rela->r_addend);
+ func_sl = (Elf_Addr)(defobj->pltgot);
+ }
rdbg(("bind now/fixup in %s --> old=(%p,%p) new=(%p,%p)",
defobj->strtab + def->st_name,
@@ -710,3 +720,29 @@ _rtld_relocate_plt_objects(const Obj_Ent
}
return 0;
}
+
+void
+_rtld_call_function_void(const Obj_Entry *obj, Elf_Addr ptr)
+{
+ volatile hppa_plabel plabel;
+ void (*f)(void);
+
+ plabel.hppa_plabel_pc = (Elf_Addr)ptr;
+ plabel.hppa_plabel_sl = (Elf_Addr)(obj->pltgot);
+ f = (void (*)(void))RTLD_MAKE_PLABEL(&plabel);
+
+ f();
+}
+
+Elf_Addr
+_rtld_call_function_addr(const Obj_Entry *obj, Elf_Addr ptr)
+{
+ volatile hppa_plabel plabel;
+ Elf_Addr (*f)(void);
+
+ plabel.hppa_plabel_pc = (Elf_Addr)ptr;
+ plabel.hppa_plabel_sl = (Elf_Addr)(obj->pltgot);
+ f = (Elf_Addr (*)(void))RTLD_MAKE_PLABEL(&plabel);
+
+ return f();
+}
Index: src/libexec/ld.elf_so/arch/i386/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.35 src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.35.8.1
--- src/libexec/ld.elf_so/arch/i386/mdreloc.c:1.35 Wed Nov 7 07:24:46 2012
+++ src/libexec/ld.elf_so/arch/i386/mdreloc.c Sun Mar 6 18:17:55 2016
@@ -1,8 +1,8 @@
-/* $NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $ */
+/* $NetBSD: mdreloc.c,v 1.35.8.1 2016/03/06 18:17:55 martin Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.35.8.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -230,7 +230,14 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- target = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ target = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ target = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
+
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where,
(void *)target));
Index: src/libexec/ld.elf_so/arch/m68k/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.29 src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.29.18.1
--- src/libexec/ld.elf_so/arch/m68k/mdreloc.c:1.29 Tue Nov 22 15:25:28 2011
+++ src/libexec/ld.elf_so/arch/m68k/mdreloc.c Sun Mar 6 18:17:55 2016
@@ -1,13 +1,13 @@
-/* $NetBSD: mdreloc.c,v 1.29 2011/11/22 15:25:28 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.29.18.1 2016/03/06 18:17:55 martin Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.29 2011/11/22 15:25:28 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.29.18.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.29 2011/11/22 15:25:28 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.29.18.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -223,8 +223,14 @@ _rtld_relocate_plt_object(const Obj_Entr
return 0;
assert(rela->r_addend == 0);
- new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
- rela->r_addend);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ new_value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
+ rela->r_addend);
+ }
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
Index: src/libexec/ld.elf_so/arch/mips/mips_reloc.c
diff -u src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.62 src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.62.22.1
--- src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.62 Fri Mar 25 18:07:05 2011
+++ src/libexec/ld.elf_so/arch/mips/mips_reloc.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_reloc.c,v 1.62 2011/03/25 18:07:05 joerg Exp $ */
+/* $NetBSD: mips_reloc.c,v 1.62.22.1 2016/03/06 18:17:55 martin 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.62 2011/03/25 18:07:05 joerg Exp $");
+__RCSID("$NetBSD: mips_reloc.c,v 1.62.22.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -445,7 +445,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry
rdbg(("TPREL %s in %s --> %p in %s",
obj->strtab + obj->symtab[r_symndx].st_name,
- obj->path, (void *)*where, defobj->path));
+ obj->path, where, defobj->path));
break;
}
@@ -487,7 +487,13 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ new_value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)new_value));
got[obj->local_gotno + sym - obj->gotsym] = new_value;
Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.52 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.52.2.1
--- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.52 Mon Jul 28 17:28:13 2014
+++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Sun Mar 6 18:17:55 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ppc_reloc.c,v 1.52 2014/07/28 17:28:13 matt Exp $ */
+/* $NetBSD: ppc_reloc.c,v 1.52.2.1 2016/03/06 18:17:55 martin Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: ppc_reloc.c,v 1.52 2014/07/28 17:28:13 matt Exp $");
+__RCSID("$NetBSD: ppc_reloc.c,v 1.52.2.1 2016/03/06 18:17:55 martin Exp $");
#endif /* not lint */
#include <stdarg.h>
@@ -366,7 +366,13 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)value));
Index: src/libexec/ld.elf_so/arch/sh3/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.30 src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.30.22.1
--- src/libexec/ld.elf_so/arch/sh3/mdreloc.c:1.30 Fri Mar 25 18:07:06 2011
+++ src/libexec/ld.elf_so/arch/sh3/mdreloc.c Sun Mar 6 18:17:56 2016
@@ -1,13 +1,13 @@
-/* $NetBSD: mdreloc.c,v 1.30 2011/03/25 18:07:06 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.30.22.1 2016/03/06 18:17:56 martin Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.30 2011/03/25 18:07:06 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.30.22.1 2016/03/06 18:17:56 martin Exp $");
#endif /* not lint */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.30 2011/03/25 18:07:06 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.30.22.1 2016/03/06 18:17:56 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -282,7 +282,13 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ new_value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
Index: src/libexec/ld.elf_so/arch/sparc/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.47 src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.47.22.1
--- src/libexec/ld.elf_so/arch/sparc/mdreloc.c:1.47 Thu Mar 31 12:47:01 2011
+++ src/libexec/ld.elf_so/arch/sparc/mdreloc.c Sun Mar 6 18:17:56 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.47 2011/03/31 12:47:01 nakayama Exp $ */
+/* $NetBSD: mdreloc.c,v 1.47.22.1 2016/03/06 18:17:56 martin 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.47 2011/03/31 12:47:01 nakayama Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.47.22.1 2016/03/06 18:17:56 martin Exp $");
#endif /* not lint */
#include <errno.h>
@@ -448,7 +448,13 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)value));
Index: src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.56 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.56.4.1
--- src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.56 Wed Apr 2 14:11:25 2014
+++ src/libexec/ld.elf_so/arch/sparc64/mdreloc.c Sun Mar 6 18:17:56 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.56 2014/04/02 14:11:25 martin Exp $ */
+/* $NetBSD: mdreloc.c,v 1.56.4.1 2016/03/06 18:17:56 martin Exp $ */
/*-
* Copyright (c) 2000 Eduardo Horvath.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.56 2014/04/02 14:11:25 martin Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.56.4.1 2016/03/06 18:17:56 martin Exp $");
#endif /* not lint */
#include <errno.h>
@@ -602,7 +602,13 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ }
rdbg(("bind now/fixup in %s at %p --> new=%p",
defobj->strtab + def->st_name, (void*)where, (void *)value));
Index: src/libexec/ld.elf_so/arch/vax/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.29 src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.29.4.1
--- src/libexec/ld.elf_so/arch/vax/mdreloc.c:1.29 Fri Mar 21 01:43:33 2014
+++ src/libexec/ld.elf_so/arch/vax/mdreloc.c Sun Mar 6 18:17:56 2016
@@ -1,13 +1,13 @@
-/* $NetBSD: mdreloc.c,v 1.29 2014/03/21 01:43:33 matt Exp $ */
+/* $NetBSD: mdreloc.c,v 1.29.4.1 2016/03/06 18:17:56 martin Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.29 2014/03/21 01:43:33 matt Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.29.4.1 2016/03/06 18:17:56 martin Exp $");
#endif /* not lint */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.29 2014/03/21 01:43:33 matt Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.29.4.1 2016/03/06 18:17:56 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -166,8 +166,14 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
- rela->r_addend);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ new_value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
+ rela->r_addend);
+ }
rdbg(("bind now/fixup pltgot %p in %s --> old=%p new=%p", where,
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
Index: src/libexec/ld.elf_so/arch/x86_64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.40 src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.40.22.1
--- src/libexec/ld.elf_so/arch/x86_64/mdreloc.c:1.40 Fri Mar 25 18:07:07 2011
+++ src/libexec/ld.elf_so/arch/x86_64/mdreloc.c Sun Mar 6 18:17:56 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.40 2011/03/25 18:07:07 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.40.22.1 2016/03/06 18:17:56 martin Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -68,7 +68,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.40 2011/03/25 18:07:07 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.40.22.1 2016/03/06 18:17:56 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -313,8 +313,15 @@ _rtld_relocate_plt_object(const Obj_Entr
if (__predict_false(def == &_rtld_sym_zero))
return 0;
- new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
- rela->r_addend);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ if (tp == NULL)
+ return 0;
+ new_value = _rtld_resolve_ifunc(defobj, def);
+ } else {
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
+ rela->r_addend);
+ }
+
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)