[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