MIPS/LD: Fix crashing with a discarded dynamic relocation section
authorMaciej W. Rozycki <macro@mips.com>
Fri, 20 Jul 2018 12:21:33 +0000 (13:21 +0100)
committerMaciej W. Rozycki <macro@mips.com>
Fri, 20 Jul 2018 12:21:33 +0000 (13:21 +0100)
Fix a crash that occurs in `_bfd_mips_elf_finish_dynamic_sections' if a
dynamic relocation section has been created, but marked to be discarded
by an assignment to the /DISCARD/ output section in a linker script.
In that case the output section is the absolute section, which has no
ELF section data attached, so trying to set its `sh_size' parameter
causes a null pointer dereference.

This is only done as the value for the DT_RELSZ dynamic entry is being
set, so fix the problem by not creating DT_REL, DT_RELSZ or DT_RELENT
dynamic entries in the first place if the dynamic relocation section
will not be output, as with no dynamic relocation data present these
would not serve their purpose anyway.

Add a generic ELF test case to verify that no dynamic relocation data is
reported in the dynamic segment.

bfd/
* elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Do not
create DT_REL, DT_RELSZ or DT_RELENT dynamic entries if the
dynamic relocation section will be discarded from output.
(_bfd_mips_elf_finish_dynamic_sections) <DT_RELSZ>: Assert that
the dynamic relocation section will be retained in output.

ld/
* testsuite/ld-elf/reloc-discard.d: New test.
* testsuite/ld-elf/reloc-discard.ld: New test linker script.
* testsuite/ld-elf/reloc-discard.s: New test source.

bfd/ChangeLog
bfd/elfxx-mips.c
ld/ChangeLog
ld/testsuite/ld-elf/reloc-discard.d [new file with mode: 0644]
ld/testsuite/ld-elf/reloc-discard.ld [new file with mode: 0644]
ld/testsuite/ld-elf/reloc-discard.s [new file with mode: 0644]

index c5960e61be4bf538b410625006875d1c03125263..9b7048c60014e5ba4afd4789f7423e55c0c645d2 100644 (file)
@@ -1,3 +1,11 @@
+2018-07-20  Maciej W. Rozycki  <macro@mips.com>
+
+       * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Do not
+       create DT_REL, DT_RELSZ or DT_RELENT dynamic entries if the
+       dynamic relocation section will be discarded from output.
+       (_bfd_mips_elf_finish_dynamic_sections) <DT_RELSZ>: Assert that
+       the dynamic relocation section will be retained in output.
+
 2018-07-18  Maciej W. Rozycki  <macro@mips.com>
 
        * xcofflink.c (xcoff_write_global_symbol): Fix symbol type
index d91942301c3223b615c81e1b362e44452dcd7a73..cc767ea6bf9b232f8d4cdc133f184ea6b5e37f29 100644 (file)
@@ -9890,7 +9890,8 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
        }
       else
        {
-         if (sreldyn && sreldyn->size > 0)
+         if (sreldyn && sreldyn->size > 0
+             && !bfd_is_abs_section (sreldyn->output_section))
            {
              if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
                return FALSE;
@@ -11798,6 +11799,7 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
                                   : sizeof (Elf32_External_Rel)));
              /* Adjust the section size too.  Tools like the prelinker
                 can reasonably expect the values to the same.  */
+             BFD_ASSERT (!bfd_is_abs_section (s->output_section));
              elf_section_data (s->output_section)->this_hdr.sh_size
                = dyn.d_un.d_val;
              break;
index c2f6b283589d3a7cae84ea52e7fe9edeb05a7943..8c7d2dfcb393e0f771f9925f4499f2057d5b16c0 100644 (file)
@@ -1,3 +1,9 @@
+2018-07-20  Maciej W. Rozycki  <macro@mips.com>
+
+       * testsuite/ld-elf/reloc-discard.d: New test.
+       * testsuite/ld-elf/reloc-discard.ld: New test linker script.
+       * testsuite/ld-elf/reloc-discard.s: New test source.
+
 2018-07-18  Nick Clifton  <nickc@redhat.com>
 
        * po/fr.po: Updated French translation.
diff --git a/ld/testsuite/ld-elf/reloc-discard.d b/ld/testsuite/ld-elf/reloc-discard.d
new file mode 100644 (file)
index 0000000..b8aad88
--- /dev/null
@@ -0,0 +1,10 @@
+#name: Discarded dynamic relocation section
+#ld: -shared -T reloc-discard.ld
+#readelf: -r --use-dynamic
+#target: [check_shared_lib_support]
+#source: reloc-discard.s
+#xfail: nds32*-*-* tic6x-*-*
+# Need to figure out how to pass `-fpic' for NDS32 or `-mpic -mpid=near'
+# for TI C6X targets to GAS for this test.
+
+There are no dynamic relocations in this file\.
diff --git a/ld/testsuite/ld-elf/reloc-discard.ld b/ld/testsuite/ld-elf/reloc-discard.ld
new file mode 100644 (file)
index 0000000..b16b80a
--- /dev/null
@@ -0,0 +1,6 @@
+SECTIONS
+{
+  /* .dynamic needs to go first with MIPS IRIX-style emulations.  */
+  .dynamic : { *(.dynamic) }
+  /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) }
+}
diff --git a/ld/testsuite/ld-elf/reloc-discard.s b/ld/testsuite/ld-elf/reloc-discard.s
new file mode 100644 (file)
index 0000000..23f187a
--- /dev/null
@@ -0,0 +1,2 @@
+       .data
+       .dc.a   foo