Like Sparc, PowerPC can use IRELATIVE relocations in non-PLT sections.
This commit is contained in:
parent
919a72802e
commit
64156cbaf3
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ppc_reloc.c,v 1.55 2017/08/10 19:03:26 joerg Exp $ */
|
||||
/* $NetBSD: ppc_reloc.c,v 1.56 2018/03/09 20:19:11 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1998 Tsubai Masanari
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ppc_reloc.c,v 1.55 2017/08/10 19:03:26 joerg Exp $");
|
||||
__RCSID("$NetBSD: ppc_reloc.c,v 1.56 2018/03/09 20:19:11 joerg Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdarg.h>
|
||||
@ -285,6 +285,14 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
|
||||
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 =
|
||||
rela - obj->rela + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
rdbg(("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
@ -314,10 +322,9 @@ _rtld_relocate_plt_lazy(Obj_Entry *obj)
|
||||
#else
|
||||
Elf_Addr * const pltresolve = obj->pltgot + 8;
|
||||
const Elf_Rela *rela;
|
||||
int reloff;
|
||||
|
||||
rela = obj->pltrelalim;
|
||||
for (reloff = rela - obj->pltrela; rela-- > obj->pltrela; --reloff) {
|
||||
for (rela = obj->pltrelalim; rela-- > obj->pltrela;) {
|
||||
size_t reloff = rela - obj->pltrela;
|
||||
Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
|
||||
|
||||
assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JUMP_SLOT) ||
|
||||
@ -383,6 +390,19 @@ _rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
|
||||
*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
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtld.c,v 1.190 2018/02/11 18:58:44 jakllsch Exp $ */
|
||||
/* $NetBSD: rtld.c,v 1.191 2018/03/09 20:19:11 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: rtld.c,v 1.190 2018/02/11 18:58:44 jakllsch Exp $");
|
||||
__RCSID("$NetBSD: rtld.c,v 1.191 2018/03/09 20:19:11 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
|
||||
#ifdef __sparc__
|
||||
#if defined(__sparc__) || defined(__powerpc__)
|
||||
|| obj->ifunc_remaining_nonplt
|
||||
#endif
|
||||
) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtld.h,v 1.131 2017/08/12 09:03:27 joerg Exp $ */
|
||||
/* $NetBSD: rtld.h,v 1.132 2018/03/09 20:19:11 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -300,7 +300,7 @@ typedef struct Struct_Obj_Entry {
|
||||
size_t fini_arraysz; /* # of entries in it */
|
||||
/* IRELATIVE relocations */
|
||||
size_t ifunc_remaining;
|
||||
#ifdef __sparc__
|
||||
#if defined(__sparc__) || defined(__powerpc__)
|
||||
/* On SPARC, the PLT variant is called JMP_IREL and counted above. */
|
||||
size_t ifunc_remaining_nonplt;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user