[PATCH] x86-64: Allow direct access relocations referencing a protected symbol for -shared
Fangrui Song
maskray@google.com
Thu Jun 17 03:48:23 GMT 2021
This fixes the bogus "relocation R_* against protected symbol `foo'
can not be used when making a shared object" for gcc -fpic -shared:
// R_X86_64_PC32
// old behavior: error
// new behavior: resolved at link time
__attribute__((visibility("protected"))) void *foo() {
return (void *)foo;
}
R_X86_64_GOTOFF64 is fixed as well.
(Note: aarch64 has the similar bug. Hope a maintainer can fix it.)
This is a no-op for R_X86_64_REX_GOTPCRELX, which is used by the controversial
"copy relocations on protected data symbols" (which has some fragile glibc
support), and .protected directives in inline asm:
// R_X86_64_REX_GOTPCRELX => R_X86_64_GLOB_DAT
__attribute__((visibility("protected"))) int var;
int load() { return var; }
// R_X86_64_REX_GOTPCRELX => R_X86_64_GLOB_DAT
void *addr() { return (void *)addr; }
asm(".protected addr");
// Note: non-x86 ports generally don't produce a GLOB_DAT.
This is a no-op for R_X86_64_PLT32, which already suppresses JUMP_SLOT.
bfd/
PR ld/27973
* bfd/elf64-x86-64.c (elf_x86_64_relocate_section): Use
_bfd_elf_symbol_refs_local_p.
* bfd/elfxx-x86.c (_bfd_elf_x86_valid_reloc_p): Likewise.
ld/
PR ld/27973
* testsuite/ld-x86-64/pr24151a-x32.d: Likewise.
* testsuite/ld-x86-64/pr24151a.d: Likewise.
* testsuite/ld-x86-64/protected1.d: Likewise.
* testsuite/ld-x86-64/protected6a.d: Likewise.
* testsuite/ld-x86-64/protected7a.d: Likewise.
---
bfd/elf64-x86-64.c | 4 ++--
bfd/elfxx-x86.c | 2 +-
ld/testsuite/ld-x86-64/pr24151a-x32.d | 4 +++-
ld/testsuite/ld-x86-64/pr24151a.d | 4 +++-
ld/testsuite/ld-x86-64/protected1.d | 4 +++-
ld/testsuite/ld-x86-64/protected6a.d | 4 +++-
ld/testsuite/ld-x86-64/protected7a.d | 4 +++-
7 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 98fb88113c0..3300e6027c9 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -3007,7 +3007,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
return false;
}
else if (!bfd_link_executable (info)
- && !SYMBOL_REFERENCES_LOCAL_P (info, h)
+ && !_bfd_elf_symbol_refs_local_p (h, info, 1)
&& (h->type == STT_FUNC
|| h->type == STT_OBJECT)
&& ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
@@ -3163,7 +3163,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|| bfd_link_dll (info)))
{
bool fail = false;
- if (SYMBOL_REFERENCES_LOCAL_P (info, h))
+ if (_bfd_elf_symbol_refs_local_p (h, info, 1))
{
/* Symbol is referenced locally. Make sure it is
defined locally. */
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 62d516aab8d..9eb3fea1087 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -909,7 +909,7 @@ _bfd_elf_x86_valid_reloc_p (asection *input_section,
it may call _bfd_elf_link_hide_sym_by_version and result in
ld-elfvers/ vers21 test failure. */
if (bfd_link_pic (info)
- && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, h)))
+ && (h == NULL || _bfd_elf_symbol_refs_local_p (h, info, 1)))
{
const struct elf_backend_data *bed;
unsigned int r_type;
diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
index 130611ddf49..a22ad01bd04 100644
--- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
+++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
@@ -1,4 +1,6 @@
#source: pr24151a.s
#as: --x32
#ld: -shared -melf32_x86_64
-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
+#readelf: -r
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
index 783b85a1a6f..63f8d990370 100644
--- a/ld/testsuite/ld-x86-64/pr24151a.d
+++ b/ld/testsuite/ld-x86-64/pr24151a.d
@@ -1,3 +1,5 @@
#as: --64
#ld: -shared -melf_x86_64
-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
+#readelf: -r
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
index 783b85a1a6f..63f8d990370 100644
--- a/ld/testsuite/ld-x86-64/protected1.d
+++ b/ld/testsuite/ld-x86-64/protected1.d
@@ -1,3 +1,5 @@
#as: --64
#ld: -shared -melf_x86_64
-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
+#readelf: -r
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
index 3a7963ffd2f..871d23e1b4e 100644
--- a/ld/testsuite/ld-x86-64/protected6a.d
+++ b/ld/testsuite/ld-x86-64/protected6a.d
@@ -1,4 +1,6 @@
#source: protected6.s
#as: --64
#ld: -shared -melf_x86_64
-#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
+#readelf: -r
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
index 3082084a7b8..d675d5460ff 100644
--- a/ld/testsuite/ld-x86-64/protected7a.d
+++ b/ld/testsuite/ld-x86-64/protected7a.d
@@ -1,4 +1,6 @@
#source: protected7.s
#as: --64
#ld: -shared -melf_x86_64
-#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
+#readelf: -r
+
+There are no relocations in this file.
--
2.32.0.272.g935e593368-goog
More information about the Binutils
mailing list