MIPS/LD: Set symtab's `sh_info' correctly for IRIX emulations
authorMaciej W. Rozycki <macro@linux-mips.org>
Wed, 29 Jul 2020 19:56:41 +0000 (20:56 +0100)
committerMaciej W. Rozycki <macro@linux-mips.org>
Wed, 29 Jul 2020 19:56:41 +0000 (20:56 +0100)
Correct ELF linker code so as to set the `sh_info' value of the static
symbol table section according to the section symbols vs other symbols
split where required by the selection of the IRIX compatibility mode for
MIPS target.  Add a `elf_backend_elfsym_local_is_section' hook for that
purpose, returning TRUE if it is only STB_LOCAL/STT_SECTION symbols that
are to be considered local for the purpose of this split rather than all
STB_LOCAL symbols.

We do it already in generic ELF code, and have done it since 1993, with
the `elf_backend_sym_is_global' hook, affecting GAS and `objcopy', so
these tools produce correct ELF output in the IRIX compatibility mode,
however if such output is fed as input to `ld -r', then the linker's
output is no longer valid for that mode.  The relevant changes to
generic ELF code are:

commit 062189c6eab72c7ba1bab1cf30fdb27d67a7d668
Author: Ian Lance Taylor <ian@airs.com>
Date:   Thu Nov 18 17:12:47 1993 +0000

and:

commit 6e07e54f1b347f885cc6c021c3fd912c79bdaf55
Author: Ian Lance Taylor <ian@airs.com>
Date:   Thu Jan 6 20:01:42 1994 +0000

(split across two GIT commits likely due to repository conversion
peculiarities).

The `elf_backend_sym_is_global' hook however operates on BFD rather than
ELF symbols, making it unsuitable for the ELF linker as the linker does
not convert any symbol tables processed into the BFD format.  Converting
the hook to operate on ELF symbols would in principle be possible, but
it would still require a considerable rewrite of `bfd_elf_final_link' to
adapt to the interface.

Therefore, especially given that no new use for the IRIX compatibility
mode is expected, minimize changes made to the ELF linker code and just
add an entirely new hook, and wire it in the o32 and n32 MIPS backends
accordingly; the n64 backend never uses the IRIX compatibility mode.

Since we have no coverage here at all add suitable GAS, LD and `objcopy'
test cases to the relevant testsuites to keep these tools consistently
verified.

bfd/
* elf-bfd.h (elf_backend_data): Add
`elf_backend_elfsym_local_is_section' member.
* elfxx-target.h (elf_backend_elfsym_local_is_section): New
macro.
(elfNN_bed): Add `elf_backend_elfsym_local_is_section' member.
* elflink.c (bfd_elf_final_link): Use it to determine whether
set the `.symtab' section's `sh_info' value to the index of the
first non-local or non-section symbol.
* elf32-mips.c (mips_elf32_elfsym_local_is_section): New
function.
(elf_backend_elfsym_local_is_section): New macro.
* elfn32-mips.c (mips_elf_n32_elfsym_local_is_section): New
function.
(elf_backend_elfsym_local_is_section): New macro.

binutils/
* testsuite/binutils-all/mips/global-local-symtab-o32.d: New
test.
* testsuite/binutils-all/mips/global-local-symtab-o32t.d: New
test.
* testsuite/binutils-all/mips/global-local-symtab-n32.d: New
test.
* testsuite/binutils-all/mips/global-local-symtab-n32t.d: New
test.
* testsuite/binutils-all/mips/global-local-symtab-n64.d: New
test.
* testsuite/binutils-all/mips/mips.exp: Run the new tests.

gas/
* testsuite/gas/mips/global-local-symtab-o32.d: New test.
* testsuite/gas/mips/global-local-symtab-o32t.d: New test.
* testsuite/gas/mips/global-local-symtab-n32.d: New test.
* testsuite/gas/mips/global-local-symtab-n32t.d: New test.
* testsuite/gas/mips/global-local-symtab-n64.d: New test.
* testsuite/gas/mips/global-local-symtab.s: New test source.
* testsuite/gas/mips/mips.exp: Run the new tests.

ld/
* testsuite/ld-mips-elf/global-local-symtab-o32.d: New test.
* testsuite/ld-mips-elf/global-local-symtab-o32t.d: New test.
* testsuite/ld-mips-elf/global-local-symtab-n32.d: New test.
* testsuite/ld-mips-elf/global-local-symtab-n32t.d: New test.
* testsuite/ld-mips-elf/global-local-symtab-n64.d: New test.
* testsuite/ld-mips-elf/global-local-symtab.ld: New test linker
script.
* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.

29 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-mips.c
bfd/elflink.c
bfd/elfn32-mips.c
bfd/elfxx-target.h
binutils/ChangeLog
binutils/testsuite/binutils-all/mips/global-local-symtab-n32.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/global-local-symtab-n32t.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/global-local-symtab-n64.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/global-local-symtab-o32.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/global-local-symtab-o32t.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/mips.exp
gas/ChangeLog
gas/testsuite/gas/mips/global-local-symtab-n32.d [new file with mode: 0644]
gas/testsuite/gas/mips/global-local-symtab-n32t.d [new file with mode: 0644]
gas/testsuite/gas/mips/global-local-symtab-n64.d [new file with mode: 0644]
gas/testsuite/gas/mips/global-local-symtab-o32.d [new file with mode: 0644]
gas/testsuite/gas/mips/global-local-symtab-o32t.d [new file with mode: 0644]
gas/testsuite/gas/mips/global-local-symtab.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
ld/ChangeLog
ld/testsuite/ld-mips-elf/global-local-symtab-n32.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/global-local-symtab-n32t.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/global-local-symtab-n64.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/global-local-symtab-o32.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/global-local-symtab-o32t.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/global-local-symtab.ld [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips-elf.exp

index 8e8dc99c1aa487aeaab4d965e88c25324652f1b4..63499ef6aeffa3734e032cf51bfef5eb453fce31 100644 (file)
@@ -1,3 +1,20 @@
+2020-07-29  Maciej W. Rozycki  <macro@linux-mips.org>
+
+       * elf-bfd.h (elf_backend_data): Add
+       `elf_backend_elfsym_local_is_section' member.
+       * elfxx-target.h (elf_backend_elfsym_local_is_section): New
+       macro.
+       (elfNN_bed): Add `elf_backend_elfsym_local_is_section' member.
+       * elflink.c (bfd_elf_final_link): Use it to determine whether
+       set the `.symtab' section's `sh_info' value to the index of the
+       first non-local or non-section symbol.
+       * elf32-mips.c (mips_elf32_elfsym_local_is_section): New
+       function.
+       (elf_backend_elfsym_local_is_section): New macro.
+       * elfn32-mips.c (mips_elf_n32_elfsym_local_is_section): New
+       function.
+       (elf_backend_elfsym_local_is_section): New macro.
+
 2020-07-29  Alan Modra  <amodra@gmail.com>
 
        * elflink.c (bfd_elf_final_link): Don't segfault on local dynsyms
index 1576724511d2f1cffce3c241754dfa3fe129ff96..fbfe65a9a9be8fb7b56c7f8cc6743da64e137183 100644 (file)
@@ -1402,6 +1402,14 @@ struct elf_backend_data
   bfd_boolean (*elf_backend_write_section)
     (bfd *, struct bfd_link_info *, asection *, bfd_byte *);
 
+  /* This function, if defined, returns TRUE if it is section symbols
+     only that are considered local for the purpose of partitioning the
+     symbol table into local and global symbols.  This should be NULL
+     for most targets, in which case the correct thing will be done.
+     MIPS ELF, at least on the Irix 5, has special requirements.  */
+  bfd_boolean (*elf_backend_elfsym_local_is_section)
+    (bfd *);
+
   /* The level of IRIX compatibility we're striving for.
      MIPS ELF specific function.  */
   irix_compat_t (*elf_backend_mips_irix_compat)
index a585e427cc5131dcd61b7d276c1cc4dcef8296d6..b17d51620eae94b5bad1a90d24b198c350614ced 100644 (file)
@@ -63,6 +63,8 @@ static bfd_boolean mips_info_to_howto_rela
   (bfd *, arelent *, Elf_Internal_Rela *);
 static bfd_boolean mips_elf_sym_is_global
   (bfd *, asymbol *);
+static bfd_boolean mips_elf32_elfsym_local_is_section
+  (bfd *);
 static bfd_boolean mips_elf32_object_p
   (bfd *);
 static bfd_boolean mips_elf_is_local_label_name
@@ -2284,6 +2286,14 @@ mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
            || bfd_is_und_section (bfd_asymbol_section (sym))
            || bfd_is_com_section (bfd_asymbol_section (sym)));
 }
+
+/* Likewise, return TRUE if the symbol table split overall must be
+   between section symbols and all other symbols.  */
+static bfd_boolean
+mips_elf32_elfsym_local_is_section (bfd *abfd)
+{
+  return SGI_COMPAT (abfd);
+}
 \f
 /* Set the right machine number for a MIPS ELF file.  */
 
@@ -2552,6 +2562,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define elf_backend_ignore_discarded_relocs \
                                        _bfd_mips_elf_ignore_discarded_relocs
 #define elf_backend_write_section      _bfd_mips_elf_write_section
+#define elf_backend_elfsym_local_is_section \
+                                       mips_elf32_elfsym_local_is_section
 #define elf_backend_mips_irix_compat   elf32_mips_irix_compat
 #define elf_backend_mips_rtype_to_howto        mips_elf32_rtype_to_howto
 #define elf_backend_sort_relocs_p      _bfd_mips_elf_sort_relocs_p
index 5089616aeefb103ffc28aa52bf2aeb8fc1f92815..32a2d6d7c198b7ee67896f63b1f3ec247b42bfb8 100644 (file)
@@ -12315,6 +12315,13 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
        }
     }
 
+  /* On some targets like Irix 5 the symbol split between local and global
+     ones recorded in the sh_info field needs to be done between section
+     and all other symbols.  */
+  if (bed->elf_backend_elfsym_local_is_section
+      && bed->elf_backend_elfsym_local_is_section (abfd))
+    symtab_hdr->sh_info = bfd_get_symcount (abfd);
+
   /* Allocate some memory to hold information read in from the input
      files.  */
   if (max_contents_size != 0)
@@ -12541,7 +12548,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
      converted to local in a version script.  */
 
   /* The sh_info field records the index of the first non local symbol.  */
-  symtab_hdr->sh_info = bfd_get_symcount (abfd);
+  if (!symtab_hdr->sh_info)
+    symtab_hdr->sh_info = bfd_get_symcount (abfd);
 
   if (dynamic
       && htab->dynsym != NULL
index 71242a55404b21cd500fc4d67acf503a8aca379a..16febe7d04d793040bb5c3ec0ba0921760e1ee1c 100644 (file)
@@ -72,6 +72,8 @@ static bfd_boolean mips_info_to_howto_rela
   (bfd *, arelent *, Elf_Internal_Rela *);
 static bfd_boolean mips_elf_sym_is_global
   (bfd *, asymbol *);
+static bfd_boolean mips_elf_n32_elfsym_local_is_section
+  (bfd *);
 static bfd_boolean mips_elf_n32_object_p
   (bfd *);
 static bfd_boolean elf32_mips_grok_prstatus
@@ -3844,6 +3846,14 @@ mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
            || bfd_is_und_section (bfd_asymbol_section (sym))
            || bfd_is_com_section (bfd_asymbol_section (sym)));
 }
+
+/* Likewise, return TRUE if the symbol table split overall must be
+   between section symbols and all other symbols.  */
+static bfd_boolean
+mips_elf_n32_elfsym_local_is_section (bfd *abfd)
+{
+  return SGI_COMPAT (abfd);
+}
 \f
 /* Set the right machine number for a MIPS ELF file.  */
 
@@ -4160,6 +4170,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define elf_backend_ignore_discarded_relocs \
                                        _bfd_mips_elf_ignore_discarded_relocs
 #define elf_backend_write_section      _bfd_mips_elf_write_section
+#define elf_backend_elfsym_local_is_section \
+                                       mips_elf_n32_elfsym_local_is_section
 #define elf_backend_mips_irix_compat   elf_n32_mips_irix_compat
 #define elf_backend_mips_rtype_to_howto        mips_elf_n32_rtype_to_howto
 #define bfd_elf32_bfd_is_target_special_symbol \
index c2b828b49939aa2bfbad9056e3bce8c67746fef0..a137c4681f1dc09cd6c817bcd7d93b72323be09f 100644 (file)
 #ifndef elf_backend_write_section
 #define elf_backend_write_section              NULL
 #endif
+#ifndef elf_backend_elfsym_local_is_section
+#define elf_backend_elfsym_local_is_section    NULL
+#endif
 #ifndef elf_backend_mips_irix_compat
 #define elf_backend_mips_irix_compat           NULL
 #endif
@@ -884,6 +887,7 @@ static struct elf_backend_data elfNN_bed =
   elf_backend_can_make_lsda_relative_eh_frame,
   elf_backend_encode_eh_address,
   elf_backend_write_section,
+  elf_backend_elfsym_local_is_section,
   elf_backend_mips_irix_compat,
   elf_backend_mips_rtype_to_howto,
   elf_backend_ecoff_debug_swap,
index 5d32d262c0348b14c861644f4e8e43df9472e7f4..a5efafc0fea1199a30fb7809a197b59504fc57bc 100644 (file)
@@ -1,3 +1,17 @@
+2020-07-29  Maciej W. Rozycki  <macro@linux-mips.org>
+
+       * testsuite/binutils-all/mips/global-local-symtab-o32.d: New
+       test.
+       * testsuite/binutils-all/mips/global-local-symtab-o32t.d: New
+       test.
+       * testsuite/binutils-all/mips/global-local-symtab-n32.d: New
+       test.
+       * testsuite/binutils-all/mips/global-local-symtab-n32t.d: New
+       test.
+       * testsuite/binutils-all/mips/global-local-symtab-n64.d: New
+       test.
+       * testsuite/binutils-all/mips/mips.exp: Run the new tests.
+
 2020-07-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR binutils/26301
diff --git a/binutils/testsuite/binutils-all/mips/global-local-symtab-n32.d b/binutils/testsuite/binutils-all/mips/global-local-symtab-n32.d
new file mode 100644 (file)
index 0000000..ef48105
--- /dev/null
@@ -0,0 +1,8 @@
+#PROG: objcopy
+#DUMPPROG: readelf
+#name: MIPS global/local symbol table split (n32)
+#as: -n32 -mno-pdr -mips3
+#objcopy: -j .data -j .symtab -j .strtab -j .shstrtab
+#readelf: -S
+#source: ../../../../gas/testsuite/gas/mips/global-local-symtab.s
+#dump: global-local-symtab-o32.d
diff --git a/binutils/testsuite/binutils-all/mips/global-local-symtab-n32t.d b/binutils/testsuite/binutils-all/mips/global-local-symtab-n32t.d
new file mode 100644 (file)
index 0000000..b44891f
--- /dev/null
@@ -0,0 +1,8 @@
+#PROG: objcopy
+#DUMPPROG: readelf
+#name: MIPS global/local symbol table split (n32)
+#as: -n32 -mno-pdr -mips3
+#objcopy: -j .data -j .symtab -j .strtab -j .shstrtab
+#readelf: -S
+#source: ../../../../gas/testsuite/gas/mips/global-local-symtab.s
+#dump: global-local-symtab-o32t.d
diff --git a/binutils/testsuite/binutils-all/mips/global-local-symtab-n64.d b/binutils/testsuite/binutils-all/mips/global-local-symtab-n64.d
new file mode 100644 (file)
index 0000000..a170d74
--- /dev/null
@@ -0,0 +1,10 @@
+#PROG: objcopy
+#DUMPPROG: readelf
+#name: MIPS global/local symbol table split (n64)
+#as: -64 -mno-pdr -mips3
+#objcopy: -j .data -j .symtab -j .strtab -j .shstrtab
+#readelf: -SW
+#source: ../../../../gas/testsuite/gas/mips/global-local-symtab.s
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +18 +3 +3 +8
+#pass
diff --git a/binutils/testsuite/binutils-all/mips/global-local-symtab-o32.d b/binutils/testsuite/binutils-all/mips/global-local-symtab-o32.d
new file mode 100644 (file)
index 0000000..4e6307e
--- /dev/null
@@ -0,0 +1,10 @@
+#PROG: objcopy
+#DUMPPROG: readelf
+#name: MIPS global/local symbol table split (o32)
+#as: -32 -mno-pdr
+#objcopy: -j .data -j .symtab -j .strtab -j .shstrtab
+#readelf: -S
+#source: ../../../../gas/testsuite/gas/mips/global-local-symtab.s
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +10 +3 +2 +4
+#pass
diff --git a/binutils/testsuite/binutils-all/mips/global-local-symtab-o32t.d b/binutils/testsuite/binutils-all/mips/global-local-symtab-o32t.d
new file mode 100644 (file)
index 0000000..1b2847d
--- /dev/null
@@ -0,0 +1,10 @@
+#PROG: objcopy
+#DUMPPROG: readelf
+#name: MIPS global/local symbol table split (o32)
+#as: -32 -mno-pdr
+#objcopy: -j .data -j .symtab -j .strtab -j .shstrtab
+#readelf: -S
+#source: ../../../../gas/testsuite/gas/mips/global-local-symtab.s
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +10 +3 +3 +4
+#pass
index ea06ee6c2b9fcfd5d771991d135d9bcbe02c3797..eed1dd124895c96eb71c3b32fab1d86ef5661bcd 100644 (file)
@@ -218,6 +218,7 @@ if {[istarget *-*-openbsd*] } {
     set abi_asflags(o32) -32
     set irixemul 1
 }
+set tmips [expr $irixemul ? {""} : {"t"}]
 
 run_dump_test_o32 "mips-ase-1"
 run_dump_test_o32 "mips-ase-2"
@@ -247,3 +248,7 @@ run_dump_test_n64 "mips-note-2r-n64"
 
 run_dump_test_o32 "mips-reginfo"
 run_dump_test_n32 "mips-reginfo-n32"
+
+run_dump_test_o32 "global-local-symtab-o32${tmips}"
+run_dump_test_n32 "global-local-symtab-n32${tmips}"
+run_dump_test_n64 "global-local-symtab-n64"
index ebc99b6e9c63d06440e24177b050c1af8225e0a6..1da85af7fa89b57a296be46b9a7415f6e0f7e1d4 100644 (file)
@@ -1,3 +1,13 @@
+2020-07-29  Maciej W. Rozycki  <macro@linux-mips.org>
+
+       * testsuite/gas/mips/global-local-symtab-o32.d: New test.
+       * testsuite/gas/mips/global-local-symtab-o32t.d: New test.
+       * testsuite/gas/mips/global-local-symtab-n32.d: New test.
+       * testsuite/gas/mips/global-local-symtab-n32t.d: New test.
+       * testsuite/gas/mips/global-local-symtab-n64.d: New test.
+       * testsuite/gas/mips/global-local-symtab.s: New test source.
+       * testsuite/gas/mips/mips.exp: Run the new tests.
+
 2020-07-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR gas/26305
diff --git a/gas/testsuite/gas/mips/global-local-symtab-n32.d b/gas/testsuite/gas/mips/global-local-symtab-n32.d
new file mode 100644 (file)
index 0000000..cf7ca7e
--- /dev/null
@@ -0,0 +1,6 @@
+#DUMPPROG: readelf
+#readelf: -S
+#name: MIPS global/local symbol table split (n32)
+#as: -n32 -mno-pdr -mips3
+#source: global-local-symtab.s
+#dump: global-local-symtab-o32.d
diff --git a/gas/testsuite/gas/mips/global-local-symtab-n32t.d b/gas/testsuite/gas/mips/global-local-symtab-n32t.d
new file mode 100644 (file)
index 0000000..b3010f6
--- /dev/null
@@ -0,0 +1,6 @@
+#DUMPPROG: readelf
+#readelf: -S
+#name: MIPS global/local symbol table split (n32)
+#as: -n32 -mno-pdr -mips3
+#source: global-local-symtab.s
+#dump: global-local-symtab-o32t.d
diff --git a/gas/testsuite/gas/mips/global-local-symtab-n64.d b/gas/testsuite/gas/mips/global-local-symtab-n64.d
new file mode 100644 (file)
index 0000000..1255ade
--- /dev/null
@@ -0,0 +1,8 @@
+#DUMPPROG: readelf
+#readelf: -SW
+#name: MIPS global/local symbol table split (n64)
+#as: -64 -mno-pdr -mips3
+#source: global-local-symtab.s
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +18 +8 +8 +8
+#pass
diff --git a/gas/testsuite/gas/mips/global-local-symtab-o32.d b/gas/testsuite/gas/mips/global-local-symtab-o32.d
new file mode 100644 (file)
index 0000000..4793794
--- /dev/null
@@ -0,0 +1,8 @@
+#DUMPPROG: readelf
+#readelf: -S
+#name: MIPS global/local symbol table split (o32)
+#as: -32 -mno-pdr
+#source: global-local-symtab.s
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +10 +8 +7 +4
+#pass
diff --git a/gas/testsuite/gas/mips/global-local-symtab-o32t.d b/gas/testsuite/gas/mips/global-local-symtab-o32t.d
new file mode 100644 (file)
index 0000000..e16fa66
--- /dev/null
@@ -0,0 +1,8 @@
+#DUMPPROG: readelf
+#readelf: -S
+#name: MIPS global/local symbol table split (o32)
+#as: -32 -mno-pdr
+#source: global-local-symtab.s
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +10 +8 +8 +4
+#pass
diff --git a/gas/testsuite/gas/mips/global-local-symtab.s b/gas/testsuite/gas/mips/global-local-symtab.s
new file mode 100644 (file)
index 0000000..1ac85b3
--- /dev/null
@@ -0,0 +1,10 @@
+       .data
+       .globl  foo
+       .type   foo, @object
+foo:
+       .dc.l   0
+       .size   foo, . - foo
+       .type   bar, @object
+bar:
+       .dc.l   0
+       .size   bar, . - bar
index ddbb86d5fd212a3d2e504c80b846a7aae312ba3a..f16d1b1644698ebf97852b8d6892e2896ddc9651 100644 (file)
@@ -2092,4 +2092,10 @@ if { [istarget mips*-*-vxworks*] } {
 
     run_dump_test "pr14798${imips}"
     run_dump_test "insn-isa-mode"
+    run_dump_test "insn-isa-mode"
+    run_dump_test "global-local-symtab-o32${tmips}"
+    if $has_newabi {
+       run_dump_test "global-local-symtab-n32${tmips}"
+       run_dump_test "global-local-symtab-n64"
+    }
 }
index 5ee1a0ea55d0842d002c7ba426ca332f9b5495c0..96edfb38b11275f5b5743b570fb1d002b76330fd 100644 (file)
@@ -1,3 +1,14 @@
+2020-07-29  Maciej W. Rozycki  <macro@linux-mips.org>
+
+       * testsuite/ld-mips-elf/global-local-symtab-o32.d: New test.
+       * testsuite/ld-mips-elf/global-local-symtab-o32t.d: New test.
+       * testsuite/ld-mips-elf/global-local-symtab-n32.d: New test.
+       * testsuite/ld-mips-elf/global-local-symtab-n32t.d: New test.
+       * testsuite/ld-mips-elf/global-local-symtab-n64.d: New test.
+       * testsuite/ld-mips-elf/global-local-symtab.ld: New test linker
+       script.
+       * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
+
 2020-07-29  Alan Modra  <amodra@gmail.com>
 
        * ldelf.c (ldelf_before_place_orphans): Set SEC_EXCLUDE for
diff --git a/ld/testsuite/ld-mips-elf/global-local-symtab-n32.d b/ld/testsuite/ld-mips-elf/global-local-symtab-n32.d
new file mode 100644 (file)
index 0000000..619295e
--- /dev/null
@@ -0,0 +1,6 @@
+#name: MIPS global/local symbol table split (n32)
+#source: ../../../gas/testsuite/gas/mips/global-local-symtab.s
+#as: -mno-pdr
+#ld: -r -T global-local-symtab.ld
+#readelf: -S
+#dump: global-local-symtab-o32.d
diff --git a/ld/testsuite/ld-mips-elf/global-local-symtab-n32t.d b/ld/testsuite/ld-mips-elf/global-local-symtab-n32t.d
new file mode 100644 (file)
index 0000000..a87c1d6
--- /dev/null
@@ -0,0 +1,6 @@
+#name: MIPS global/local symbol table split (n32)
+#source: ../../../gas/testsuite/gas/mips/global-local-symtab.s
+#as: -mno-pdr
+#ld: -r -T global-local-symtab.ld
+#readelf: -S
+#dump: global-local-symtab-o32t.d
diff --git a/ld/testsuite/ld-mips-elf/global-local-symtab-n64.d b/ld/testsuite/ld-mips-elf/global-local-symtab-n64.d
new file mode 100644 (file)
index 0000000..b77625c
--- /dev/null
@@ -0,0 +1,8 @@
+#name: MIPS global/local symbol table split (n64)
+#source: ../../../gas/testsuite/gas/mips/global-local-symtab.s
+#as: -mno-pdr
+#ld: -r -T global-local-symtab.ld
+#readelf: -SW
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +18 +3 +4 +8
+#pass
diff --git a/ld/testsuite/ld-mips-elf/global-local-symtab-o32.d b/ld/testsuite/ld-mips-elf/global-local-symtab-o32.d
new file mode 100644 (file)
index 0000000..c7e1cd2
--- /dev/null
@@ -0,0 +1,8 @@
+#name: MIPS global/local symbol table split (o32)
+#source: ../../../gas/testsuite/gas/mips/global-local-symtab.s
+#as: -mno-pdr
+#ld: -r -T global-local-symtab.ld
+#readelf: -S
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +10 +3 +2 +4
+#pass
diff --git a/ld/testsuite/ld-mips-elf/global-local-symtab-o32t.d b/ld/testsuite/ld-mips-elf/global-local-symtab-o32t.d
new file mode 100644 (file)
index 0000000..612d557
--- /dev/null
@@ -0,0 +1,8 @@
+#name: MIPS global/local symbol table split (o32)
+#source: ../../../gas/testsuite/gas/mips/global-local-symtab.s
+#as: -mno-pdr
+#ld: -r -T global-local-symtab.ld
+#readelf: -S
+#...
+ *\[ *[0-9]+\] +\.symtab +SYMTAB +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +10 +3 +4 +4
+#pass
diff --git a/ld/testsuite/ld-mips-elf/global-local-symtab.ld b/ld/testsuite/ld-mips-elf/global-local-symtab.ld
new file mode 100644 (file)
index 0000000..57ea4de
--- /dev/null
@@ -0,0 +1,8 @@
+SECTIONS
+{
+  .data : { *(.data) }
+  .symtab : { *(.symtab) }
+  .strtab : { *(.strtab) }
+  .shstrtab : { *(.shstrtab) }
+  /DISCARD/ : { *(*) }
+}
index e98429c80102b10b4f645558328278c31ed3e4ba..4b257c31e659f1f0d1e8d9a80ea61039ec3af9a5 100644 (file)
@@ -248,6 +248,7 @@ if {[istarget *-*-openbsd*] } {
     set abi_asflags(o32) -32
     set irixemul 1
 }
+set tmips [expr $irixemul ? {""} : {"t"}]
 
 if { $linux_gnu } {
     run_ld_link_tests [list \
@@ -1657,3 +1658,8 @@ run_dump_test_n64 "pic-reloc-7" [list [list name (microMIPS)] \
                                      [list as "-mmicromips"]]
 
 run_dump_test_o32 "reloc-pcrel-r6"
+
+# Global/local symbol table split tests.
+run_dump_test_o32 "global-local-symtab-o32${tmips}"
+run_dump_test_n32 "global-local-symtab-n32${tmips}"
+run_dump_test_n64 "global-local-symtab-n64"