mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
dl-runtime: reloc_{offset,index} now functions arch overide'able
The existing macros are fragile and expect local variables with a certain name. Fix this by defining them as functions with default implementation in a new header dl-runtime.h which arches can override if need be. This came up during ARC port review, hence the need for argument pltgot in reloc_index() which is not needed by existing ports. This patch potentially only affects hppa/x86 ports, build tested for both those configs and a few more. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
parent
a23bd00f9d
commit
8dbb7a08ec
@ -27,6 +27,7 @@
|
||||
#include "dynamic-link.h"
|
||||
#include <tls.h>
|
||||
#include <dl-irel.h>
|
||||
#include <dl-runtime.h>
|
||||
|
||||
|
||||
#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
|
||||
@ -42,13 +43,6 @@
|
||||
# define ARCH_FIXUP_ATTRIBUTE
|
||||
#endif
|
||||
|
||||
#ifndef reloc_offset
|
||||
# define reloc_offset reloc_arg
|
||||
# define reloc_index reloc_arg / sizeof (PLTREL)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* This function is called through a special trampoline from the PLT the
|
||||
first time each PLT entry is called. We must perform the relocation
|
||||
specified in the PLT of the given shared object, and return the resolved
|
||||
@ -68,8 +62,11 @@ _dl_fixup (
|
||||
= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
|
||||
const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
|
||||
|
||||
const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
|
||||
const PLTREL *const reloc
|
||||
= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
|
||||
= (const void *) (D_PTR (l, l_info[DT_JMPREL])
|
||||
+ reloc_offset (pltgot, reloc_arg));
|
||||
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
|
||||
const ElfW(Sym) *refsym = sym;
|
||||
void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
|
||||
@ -180,9 +177,12 @@ _dl_profile_fixup (
|
||||
l, reloc_arg);
|
||||
}
|
||||
|
||||
const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
|
||||
/* This is the address in the array where we store the result of previous
|
||||
relocations. */
|
||||
struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
|
||||
struct reloc_result *reloc_result
|
||||
= &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||
|
||||
/* CONCURRENCY NOTES:
|
||||
|
||||
@ -219,8 +219,11 @@ _dl_profile_fixup (
|
||||
= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
|
||||
const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
|
||||
|
||||
const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
|
||||
const PLTREL *const reloc
|
||||
= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
|
||||
= (const void *) (D_PTR (l, l_info[DT_JMPREL])
|
||||
+ reloc_offset (pltgot, reloc_arg));
|
||||
const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
|
||||
const ElfW(Sym) *defsym = refsym;
|
||||
lookup_t result;
|
||||
@ -485,11 +488,14 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||
const void *inregs, void *outregs)
|
||||
{
|
||||
#ifdef SHARED
|
||||
const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
|
||||
/* This is the address in the array where we store the result of previous
|
||||
relocations. */
|
||||
// XXX Maybe the bound information must be stored on the stack since
|
||||
// XXX with bind_not a new value could have been stored in the meantime.
|
||||
struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
|
||||
struct reloc_result *reloc_result =
|
||||
&l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||
l_info[DT_SYMTAB])
|
||||
+ reloc_result->boundndx);
|
||||
|
30
elf/dl-runtime.h
Normal file
30
elf/dl-runtime.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* Helpers for On-demand PLT fixup for shared objects. Generic version.
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
static inline uintptr_t
|
||||
reloc_offset (uintptr_t plt0, uintptr_t pltn)
|
||||
{
|
||||
return pltn;
|
||||
}
|
||||
|
||||
static inline uintptr_t
|
||||
reloc_index (uintptr_t plt0, uintptr_t pltn, size_t size)
|
||||
{
|
||||
return pltn / size;
|
||||
}
|
@ -17,10 +17,6 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* Clear PA_GP_RELOC bit in relocation offset. */
|
||||
#define reloc_offset (reloc_arg & ~PA_GP_RELOC)
|
||||
#define reloc_index (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL)
|
||||
|
||||
#include <elf/dl-runtime.c>
|
||||
|
||||
/* The caller has encountered a partially relocated function descriptor.
|
||||
|
31
sysdeps/hppa/dl-runtime.h
Normal file
31
sysdeps/hppa/dl-runtime.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* Helpers for On-demand PLT fixup for shared objects. HPAA version.
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* Clear PA_GP_RELOC bit in relocation offset. */
|
||||
static inline uintptr_t
|
||||
reloc_offset (uintptr_t plt0, uintptr_t pltn)
|
||||
{
|
||||
return pltn & ~PA_GP_RELOC;
|
||||
}
|
||||
|
||||
static inline uintptr_t
|
||||
reloc_index (uintptr_t plt0, uintptr_t pltn, size_t size)
|
||||
{
|
||||
return (pltn & ~PA_GP_RELOC )/ size;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
/* The ABI calls for the PLT stubs to pass the index of the relocation
|
||||
and not its offset. In _dl_profile_fixup and _dl_call_pltexit we
|
||||
also use the index. Therefore it is wasteful to compute the offset
|
||||
in the trampoline just to reverse the operation immediately
|
||||
afterwards. */
|
||||
#define reloc_offset reloc_arg * sizeof (PLTREL)
|
||||
#define reloc_index reloc_arg
|
||||
|
||||
#include <elf/dl-runtime.c>
|
35
sysdeps/x86_64/dl-runtime.h
Normal file
35
sysdeps/x86_64/dl-runtime.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* Helpers for On-demand PLT fixup for shared objects. x86_64 version.
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* The ABI calls for the PLT stubs to pass the index of the relocation
|
||||
and not its offset. In _dl_profile_fixup and _dl_call_pltexit we
|
||||
also use the index. Therefore it is wasteful to compute the offset
|
||||
in the trampoline just to reverse the operation immediately
|
||||
afterwards. */
|
||||
static inline uintptr_t
|
||||
reloc_offset (uintptr_t plt0, uintptr_t pltn)
|
||||
{
|
||||
return pltn * sizeof (ElfW(Rela));
|
||||
}
|
||||
|
||||
static inline uintptr_t
|
||||
reloc_index (uintptr_t plt0, uintptr_t pltn, size_t size)
|
||||
{
|
||||
return pltn;
|
||||
}
|
Loading…
Reference in New Issue
Block a user