x86: Count PLT for GOTOFF relocation against IFUNC symbol
authorH.J. Lu <hjl.tools@gmail.com>
Sun, 20 Jun 2021 03:20:52 +0000 (20:20 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sun, 20 Jun 2021 03:21:04 +0000 (20:21 -0700)
Since GOTOFF relocations against IFUNC symbols must go through PLT,
set PLT reference count to 1 for GOTOFF relocation.

bfd/

PR ld/27998
* elfxx-x86.c (elf_x86_allocate_dynrelocs): Count PLT for GOTOFF
relocation against IFUNC symbols.
(_bfd_x86_elf_adjust_dynamic_symbol): Likewise.

ld/

PR ld/27998
* testsuite/ld-i386/i386.exp: Run PR ld/27998 tests.
* testsuite/ld-i386/pr27998a.d: New file.
* testsuite/ld-i386/pr27998a.s: Likewise.
* testsuite/ld-i386/pr27998b.d: Likewise.
* testsuite/ld-i386/pr27998b.s: Likewise.

bfd/ChangeLog
bfd/elfxx-x86.c
ld/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pr27998a.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr27998a.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr27998b.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr27998b.s [new file with mode: 0644]

index 5211e98e111c39e215aaa340d6bea99a99f10a78..212fe332e2def21c7e3222708954d9879b9c5ad0 100644 (file)
@@ -1,3 +1,10 @@
+2021-06-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/27998
+       * elfxx-x86.c (elf_x86_allocate_dynrelocs): Count PLT for GOTOFF
+       relocation against IFUNC symbols.
+       (_bfd_x86_elf_adjust_dynamic_symbol): Likewise.
+
 2021-06-19  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elflink.c (bfd_elf_final_link): Correct DT_TEXTREL warning in
index 62d516aab8d3bba2aec7f436c99705ea6d4ea740..088f6e5c5366495e77ee5e80a881b67d551765ab 100644 (file)
@@ -131,6 +131,10 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   if (h->type == STT_GNU_IFUNC
       && h->def_regular)
     {
+      /* GOTOFF relocation needs PLT.  */
+      if (eh->gotoff_ref)
+       h->plt.refcount = 1;
+
       if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs,
                                              plt_entry_size,
                                              (htab->plt.has_plt0
@@ -1818,6 +1822,8 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   const struct elf_backend_data *bed
     = get_elf_backend_data (info->output_bfd);
 
+  eh = (struct elf_x86_link_hash_entry *) h;
+
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (h->type == STT_GNU_IFUNC)
     {
@@ -1856,6 +1862,10 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
                    h->plt.refcount += 1;
                }
            }
+
+         /* GOTOFF relocation needs PLT.  */
+         if (eh->gotoff_ref)
+           h->plt.refcount = 1;
        }
 
       if (h->plt.refcount <= 0)
@@ -1896,8 +1906,6 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
        the link may change h->type.  So fix it now.  */
     h->plt.offset = (bfd_vma) -1;
 
-  eh = (struct elf_x86_link_hash_entry *) h;
-
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
index 36f8d4b5268f26767b728a80571378a76af181d0..dc08ec9f0a00f8a5e976ac638e42624cb818901e 100644 (file)
@@ -1,3 +1,12 @@
+2021-06-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/27998
+       * testsuite/ld-i386/i386.exp: Run PR ld/27998 tests.
+       * testsuite/ld-i386/pr27998a.d: New file.
+       * testsuite/ld-i386/pr27998a.s: Likewise.
+       * testsuite/ld-i386/pr27998b.d: Likewise.
+       * testsuite/ld-i386/pr27998b.s: Likewise.
+
 2021-06-19  H.J. Lu  <hongjiu.lu@intel.com>
 
        * testsuite/ld-x86-64/textrel-1.err: New file.
index 3d6047b790d526586592521c06542a358b1fe50a..ceb60002d130f4f025f2a0161754f1f8faa4a884 100644 (file)
@@ -519,6 +519,8 @@ run_dump_test "pr19939a"
 run_dump_test "pr19939b"
 run_dump_test "tlsdesc2"
 run_dump_test "report-reloc-1"
+run_dump_test "pr27998a"
+run_dump_test "pr27998b"
 
 proc undefined_weak {cflags ldflags} {
     set testname "Undefined weak symbol"
diff --git a/ld/testsuite/ld-i386/pr27998a.d b/ld/testsuite/ld-i386/pr27998a.d
new file mode 100644 (file)
index 0000000..ca3c920
--- /dev/null
@@ -0,0 +1,7 @@
+#as: --32
+#ld: -shared -melf_i386
+#readelf: -r --wide
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
diff --git a/ld/testsuite/ld-i386/pr27998a.s b/ld/testsuite/ld-i386/pr27998a.s
new file mode 100644 (file)
index 0000000..ec55cd6
--- /dev/null
@@ -0,0 +1,22 @@
+       .text
+       .p2align 4
+       .type   my_foo, @function
+my_foo:
+       ret
+       .size   my_foo, .-my_foo
+       .p2align 4
+       .type   resolve_foo, @function
+resolve_foo:
+       leal    my_foo@GOTOFF(%eax), %eax
+       ret
+       .size   resolve_foo, .-resolve_foo
+       .globl  foo
+       .hidden foo
+       .type   foo, @gnu_indirect_function
+       .set    foo,resolve_foo
+       .p2align 4
+       .globl  bar
+       .type   bar, @function
+bar:
+       leal    foo@GOTOFF(%eax), %eax
+       ret
diff --git a/ld/testsuite/ld-i386/pr27998b.d b/ld/testsuite/ld-i386/pr27998b.d
new file mode 100644 (file)
index 0000000..ca3c920
--- /dev/null
@@ -0,0 +1,7 @@
+#as: --32
+#ld: -shared -melf_i386
+#readelf: -r --wide
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
diff --git a/ld/testsuite/ld-i386/pr27998b.s b/ld/testsuite/ld-i386/pr27998b.s
new file mode 100644 (file)
index 0000000..8b023e9
--- /dev/null
@@ -0,0 +1,20 @@
+       .text
+       .p2align 4
+       .type   my_foo, @function
+my_foo:
+       ret
+       .size   my_foo, .-my_foo
+       .p2align 4
+       .type   resolve_foo, @function
+resolve_foo:
+       leal    my_foo@GOTOFF(%eax), %eax
+       ret
+       .size   resolve_foo, .-resolve_foo
+       .type   foo, @gnu_indirect_function
+       .set    foo,resolve_foo
+       .p2align 4
+       .globl  bar
+       .type   bar, @function
+bar:
+       leal    foo@GOTOFF(%eax), %eax
+       ret