You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
9.2 KiB
246 lines
9.2 KiB
2 years ago
|
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
|
||
|
--- a/elf/dl-runtime.c
|
||
|
+++ b/elf/dl-runtime.c
|
||
|
@@ -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
|
||
|
--- /dev/null
|
||
|
+++ b/elf/dl-runtime.h
|
||
|
@@ -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
|
||
|
--- a/sysdeps/hppa/dl-runtime.c
|
||
|
+++ b/sysdeps/hppa/dl-runtime.c
|
||
|
@@ -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
|
||
|
--- /dev/null
|
||
|
+++ b/sysdeps/hppa/dl-runtime.h
|
||
|
@@ -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
|
||
|
--- a/sysdeps/x86_64/dl-runtime.c
|
||
|
+++ /dev/null
|
||
|
@@ -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
|
||
|
--- /dev/null
|
||
|
+++ b/sysdeps/x86_64/dl-runtime.h
|
||
|
@@ -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;
|
||
|
+}
|