| commit 8dbb7a08ec52057819db4ee234f9429ab99eb4ae |
| Author: Vineet Gupta <vgupta@synopsys.com> |
| Date: Wed May 27 12:54:21 2020 -0700 |
| |
| 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> |
| |
| diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c |
| index 72b03e000dcf190e..4ccd7c30678fafad 100644 |
| |
| |
| @@ -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); |
| diff --git a/elf/dl-runtime.h b/elf/dl-runtime.h |
| new file mode 100644 |
| index 0000000000000000..78f1da77fb4ed905 |
| |
| |
| @@ -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; |
| +} |
| diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c |
| index 885a3f1837cbc56d..2d061b150f0602c1 100644 |
| |
| |
| @@ -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. |
| diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h |
| new file mode 100644 |
| index 0000000000000000..6983aa0ae9b4296c |
| |
| |
| @@ -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; |
| +} |
| diff --git a/sysdeps/x86_64/dl-runtime.c b/sysdeps/x86_64/dl-runtime.c |
| deleted file mode 100644 |
| index b625d1e88257b018..0000000000000000 |
| |
| |
| @@ -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> |
| diff --git a/sysdeps/x86_64/dl-runtime.h b/sysdeps/x86_64/dl-runtime.h |
| new file mode 100644 |
| index 0000000000000000..3fa61d7a4697cf3f |
| |
| |
| @@ -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; |
| +} |