This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]