This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH + test RFA] MIPS/LD: Fix crashing with a discarded dynamic relocation section
- From: "Maciej W. Rozycki" <macro at mips dot com>
- To: Nick Clifton <nickc at redhat dot com>, Alan Modra <amodra at gmail dot com>
- Cc: <binutils at sourceware dot org>
- Date: Thu, 19 Jul 2018 23:06:35 +0100
- Subject: [PATCH + test RFA] MIPS/LD: Fix crashing with a discarded dynamic relocation section
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.
---
Hi,
I made the test case deliberately ELF-generic so that port maintainers
have a chance to check their targets.
Most fail though, having produced rubbish in the dynamic segment just as
MIPS would had it not crashed in `_bfd_mips_elf_finish_dynamic_sections'.
I'm leaving it up to the respective maintainers to address; the piece I
added in `_bfd_mips_elf_size_dynamic_sections' can serve as an obvious
example. The only winners are `bfin-*-*' and `score-*-*'; they pass.
One problem with a generic ELF `run_dump_test' case is that they are run
in bulk with a glob matcher, precluding target-specific flag passing. As
a result the test fails for `nds32*-*-*' and `tic6x-*-*' targets without
actually checking whether they set dynamic contents right. I have XFAILed
them for the time being, but a solution has to be eventually found.
OK for the test part then?
Maciej
---
bfd/elfxx-mips.c | 4 +++-
ld/testsuite/ld-elf/reloc-discard.d | 10 ++++++++++
ld/testsuite/ld-elf/reloc-discard.ld | 6 ++++++
ld/testsuite/ld-elf/reloc-discard.s | 2 ++
4 files changed, 21 insertions(+), 1 deletion(-)
binutils-mips-bfd-finish-dynamic-sections-discard.diff
Index: binutils/bfd/elfxx-mips.c
===================================================================
--- binutils.orig/bfd/elfxx-mips.c 2018-07-19 17:53:12.986154546 +0100
+++ binutils/bfd/elfxx-mips.c 2018-07-19 17:55:55.465147387 +0100
@@ -9890,7 +9890,8 @@ _bfd_mips_elf_size_dynamic_sections (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 (b
: 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: binutils/ld/testsuite/ld-elf/reloc-discard.d
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-elf/reloc-discard.d 2018-07-19 20:36:43.398411533 +0100
@@ -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\.
Index: binutils/ld/testsuite/ld-elf/reloc-discard.ld
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-elf/reloc-discard.ld 2018-07-19 20:29:08.648514653 +0100
@@ -0,0 +1,6 @@
+SECTIONS
+{
+ /* .dynamic needs to go first with MIPS IRIX-style emulations. */
+ .dynamic : { *(.dynamic) }
+ /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) }
+}
Index: binutils/ld/testsuite/ld-elf/reloc-discard.s
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-elf/reloc-discard.s 2018-07-19 18:10:05.019135393 +0100
@@ -0,0 +1,2 @@
+ .data
+ .dc.a foo