]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
MIPS/BFD: Account for VxWorks .got.plt references
authorMaciej W. Rozycki <macro@orcam.me.uk>
Mon, 6 Oct 2025 20:37:28 +0000 (21:37 +0100)
committerMaciej W. Rozycki <macro@orcam.me.uk>
Mon, 6 Oct 2025 20:37:28 +0000 (21:37 +0100)
On VxWorks calls can refer directly to a .got.plt entry, in which case
they won't have an entry in the regular GOT.  It was missed with commit
6c42ddb92b90 ("MIPS GOT: Remove TLS GOT info from the symbol table"),
<https://inbox.sourceware.org/binutils/878v6uyaw3.fsf@talisman.default/>,
which revamped GOT entry bookkeeping, and consequently space for regular
GOT entries is needlessly reserved and then not used, with extraneous
null dynamic relocations attached, e.g.:

Relocation section '.rela.dyn' at offset 0x1400 contains 11 entries:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00080c0c  00000405 R_MIPS_HI16       00000000   __GOTT_BASE__ + 0
00080c10  00000406 R_MIPS_LO16       00000000   __GOTT_BASE__ + 0
00080c14  00000601 R_MIPS_16         00000000   __GOTT_INDEX__ + 0
0008141c  00000002 R_MIPS_32                    80c5c
00081800  00000002 R_MIPS_32                    80c5c
00081804  00000002 R_MIPS_32                    81800
00081808  00000502 R_MIPS_32         00081808   dglobal + 0
0008180c  00000202 R_MIPS_32         00000000   dexternal + 0
00081428  00000a02 R_MIPS_32         00081c00   x + 0
00000000  00000000 R_MIPS_NONE                  0
00000000  00000000 R_MIPS_NONE                  0

Adjust regular GOT entry counting then to take .got.plt entries into
account, removing a regression from the commit referred:

mips-vxworks  -FAIL: VxWorks shared library test 1
mipsel-vxworks  -FAIL: VxWorks shared library test 1

bfd/elfxx-mips.c

index 181f9f5e9fcc47d2f357a27e820c40d6378d6e18..00ef06637280613dbaf59ce027d8046f85f9bee1 100644 (file)
@@ -3459,8 +3459,21 @@ mips_elf_count_got_entry (struct bfd_link_info *info,
                                        entry->symndx < 0
                                        ? &entry->d.h->root : NULL);
     }
-  else if (entry->symndx >= 0 || entry->d.h->global_got_area == GGA_NONE)
+  else if (entry->symndx >= 0)
     g->local_gotno += 1;
+  else if (entry->d.h->global_got_area == GGA_NONE)
+    {
+      /* On VxWorks, calls can refer directly to the .got.plt entry,
+        in which case they won't have an entry in the regular GOT.
+        This is arranged for in `mips_elf_count_got_symbols' and we
+        need to refrain from counting these entries for the regular
+        GOT here.  */
+      if (mips_elf_hash_table (info)->root.target_os != is_vxworks
+         || entry->d.h->root.dynindx == -1
+         || !entry->d.h->got_only_for_calls
+         || entry->d.h->root.plt.plist->mips_offset == MINUS_ONE)
+       g->local_gotno += 1;
+    }
   else
     g->global_gotno += 1;
 }