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]

Commit: Fix test for .dynstr section


Hi Guys,

  I am applying the patch below to fix a bug reported on the Fedora
  Bugzilla system:

     https://bugzilla.redhat.com/show_bug.cgi?id=712166

  The problem involves a broken linker script that accidentally marked
  all of the dynamic sections as being notes.  Now this is obviously a
  bad idea, but even so the linker should not seg-fault under such
  circumstances.

  The patch does two things.  It fixes the test for the .dynstr section
  in bfd_elf_final_link() so that it must have have both the SHT_STRTAB
  type and the name .dynstr.  (This was the cause of the original
  seg-fault).  Plus it makes the linker issue a warning message if it
  finds any dynamic section with the SHT_NOTE type, and sets the error
  to nonrepresentable_section.

  The patch also adds a test case for the warning message and fixes a
  mis-assumption in the ARM and HPPA ports that dynamic sections are
  always present in the output binary.  It also tidies up the
  description of the run_ld_link_tests function in the ld-lib.exp
  library, as this function is used to run the new test and the
  description was inaccurate in places.

  Tested with a large variety of different toolchains.

Cheers
  Nick

bfd/ChangeLog
2011-06-10  Nick Clifton  <nickc@redhat.com>

	* elflink.c (_bfd_elf_link_create_dynamic_sections): If the
	backend does not provide a function for creating dynamic sections
	then fail.
	(bfd_elf_final_link): Issue a warning message if a dynamic section
	has the SHT_NOTE type.
	(bfd_elf_final_link): Do not look for dynamic strings in a section
	that does not have the SHT_STRTAB type or the name .dynstr.
	* elf32-arm.c (elf32_arm_finish_dynamic_sections): Fail if the got
	section is not in the output binary.
	* elf32-hppa.c (elf32_hppa_finish_dynamic_sections): Likewise.

ld/testsuite/ChangeLog
2011-06-10  Nick Clifton  <nickc@redhat.com>

	* ld-elf/elf.exp: Add test for linking a shared library with a
	broken linker script that marks dynamic sections as being notes.
	* ld-elf/note-3.s: New test source file.
	* ld-elf/note-3.t: New test linker script.
	* ld-elf/note-3.l: Expected output from the linker.
	* lib/ld-lib.exp (run_ld_link_tests): Improve description.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.268
diff -u -3 -p -r1.268 elf32-arm.c
--- bfd/elf32-arm.c	2 Jun 2011 13:43:14 -0000	1.268
+++ bfd/elf32-arm.c	10 Jun 2011 14:00:07 -0000
@@ -13744,6 +13744,10 @@ elf32_arm_finish_dynamic_sections (bfd *
   dynobj = elf_hash_table (info)->dynobj;
 
   sgot = htab->root.sgotplt;
+  /* A broken linker script might have discarded the dynamic sections.
+     Catch this here so that we do not seg-fault later on.  */
+  if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
+    return FALSE;
   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.176
diff -u -3 -p -r1.176 elf32-hppa.c
--- bfd/elf32-hppa.c	25 Oct 2010 15:54:14 -0000	1.176
+++ bfd/elf32-hppa.c	10 Jun 2011 14:00:08 -0000
@@ -4498,6 +4498,7 @@ elf32_hppa_finish_dynamic_sections (bfd 
   bfd *dynobj;
   struct elf32_hppa_link_hash_table *htab;
   asection *sdyn;
+  asection * sgot;
 
   htab = hppa_link_hash_table (info);
   if (htab == NULL)
@@ -4505,6 +4506,12 @@ elf32_hppa_finish_dynamic_sections (bfd 
 
   dynobj = htab->etab.dynobj;
 
+  sgot = htab->sgot;
+  /* A broken linker script might have discarded the dynamic sections.
+     Catch this here so that we do not seg-fault later on.  */
+  if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
+    return FALSE;
+
   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
 
   if (htab->etab.dynamic_sections_created)
@@ -4569,19 +4576,19 @@ elf32_hppa_finish_dynamic_sections (bfd 
 	}
     }
 
-  if (htab->sgot != NULL && htab->sgot->size != 0)
+  if (sgot != NULL && sgot->size != 0)
     {
       /* Fill in the first entry in the global offset table.
 	 We use it to point to our dynamic section, if we have one.  */
       bfd_put_32 (output_bfd,
 		  sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
-		  htab->sgot->contents);
+		  sgot->contents);
 
       /* The second entry is reserved for use by the dynamic linker.  */
-      memset (htab->sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
+      memset (sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
 
       /* Set .got entry size.  */
-      elf_section_data (htab->sgot->output_section)
+      elf_section_data (sgot->output_section)
 	->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
     }
 
@@ -4601,8 +4608,8 @@ elf32_hppa_finish_dynamic_sections (bfd 
 	  if ((htab->splt->output_offset
 	       + htab->splt->output_section->vma
 	       + htab->splt->size)
-	      != (htab->sgot->output_offset
-		  + htab->sgot->output_section->vma))
+	      != (sgot->output_offset
+		  + sgot->output_section->vma))
 	    {
 	      (*_bfd_error_handler)
 		(_(".got section not immediately after .plt section"));
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.408
diff -u -3 -p -r1.408 elflink.c
--- bfd/elflink.c	9 Jun 2011 04:52:14 -0000	1.408
+++ bfd/elflink.c	10 Jun 2011 14:00:08 -0000
@@ -286,7 +286,8 @@ _bfd_elf_link_create_dynamic_sections (b
   /* Let the backend create the rest of the sections.  This lets the
      backend set the right flags.  The backend will normally create
      the .got and .plt sections.  */
-  if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
+  if (bed->elf_backend_create_dynamic_sections == NULL
+      || ! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
     return FALSE;
 
   elf_hash_table (info)->dynamic_sections_created = TRUE;
@@ -11148,6 +11149,13 @@ bfd_elf_final_link (bfd *abfd, struct bf
 		    (_("%B: could not find output section %s"), abfd, name);
 		  goto error_return;
 		}
+	      if (elf_section_data (o->output_section)->this_hdr.sh_type == SHT_NOTE)
+		{
+		  (*_bfd_error_handler)
+		    (_("warning: section '%s' is being made into a note"), name);
+		  bfd_set_error (bfd_error_nonrepresentable_section);
+		  goto error_return;
+		}
 	      dyn.d_un.d_ptr = o->vma;
 	      break;
 
@@ -11235,7 +11243,7 @@ bfd_elf_final_link (bfd *abfd, struct bf
 	    continue;
 	  if ((elf_section_data (o->output_section)->this_hdr.sh_type
 	       != SHT_STRTAB)
-	      || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)
+	      && (strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0))
 	    {
 	      /* FIXME: octets_per_byte.  */
 	      if (! bfd_set_section_contents (abfd, o->output_section,
Index: ld/testsuite/ld-elf/elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-elf/elf.exp,v
retrieving revision 1.23
diff -u -3 -p -r1.23 elf.exp
--- ld/testsuite/ld-elf/elf.exp	8 Jun 2011 04:47:03 -0000	1.23
+++ ld/testsuite/ld-elf/elf.exp	10 Jun 2011 14:00:11 -0000
@@ -49,6 +49,46 @@ run_ld_link_tests {
      {symbol3w.s} {} "symbol3w.a"}
 }
 
+# Run a test to check linking a shared library with a broken linker
+# script that accidentally marks dynamic sections as notes.  The
+# resulting executable is not expected to work, but the linker
+# should not seg-fault whilst creating the binary.
+#
+# Only run the test on targets thats support creating shared libraries.
+if {    ! [istarget arc-*-*]
+     && ! [istarget avr-*-*]
+     && ! [istarget cr16-*-*]
+     && ! [istarget cris*-*-*]
+     && ! [istarget crx-*-*]
+     && ! [istarget d10v-*-*]
+     && ! [istarget d30v-*-*]
+     && ! [istarget dlx-*-*]
+     && ! [istarget fr30-*-*]
+     && ! [istarget frv-*-*]
+     && ! [istarget h8300-*-*]
+     && ! [istarget ip2k-*-*]
+     && ! [istarget m32r-*-*]
+     && ! [istarget mcore*-*-*]
+     && ! [istarget mn10200-*-*]
+     && ! [istarget msp430-*-*]
+     && ! [istarget openrisc-*-*]
+     && ! [istarget or32-*-*]
+     && ! [istarget pj-*-*]
+     && ! [istarget rx-*-*]
+     && ! [istarget v850-*-*]
+     && ! [istarget *-*-irix*]
+     && ! [istarget *-*-rtems] } {
+  run_ld_link_tests {
+      {"Build shared library for next test"
+       "-shared" "" "note-3.s" {} "note-3.so" }
+      {"Link using broken linker script"
+        "--script note-3.t tmpdir/note-3.so" "" ""
+	  { { ld "note-3.l" } }
+	  "a.out" }
+  }
+}
+
+
 set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
 foreach t $test_list {
     # We need to strip the ".d", but can leave the dirname.
Index: ld/testsuite/lib/ld-lib.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/lib/ld-lib.exp,v
retrieving revision 1.83
diff -u -3 -p -r1.83 ld-lib.exp
--- ld/testsuite/lib/ld-lib.exp	18 May 2011 14:04:32 -0000	1.83
+++ ld/testsuite/lib/ld-lib.exp	10 Jun 2011 14:00:11 -0000
@@ -903,18 +903,24 @@ proc ar_simple_create { ar aropts target
 
 # List contains test-items with 3 items followed by 2 lists, one item and
 # one optional item:
-# 0:name 1:ld/ar options 2:assembler options
-# 3:filenames of assembler files 4: action and options. 5: name of output file
-# 6:compiler flags (optional)
+#  0:name
+#  1:ld/ar options
+#  2:assembler options
+#  3:filenames of assembler files
+#  4:list of actions, options and expected outputs.
+#  5:name of output file
+#  6:compiler flags (optional)
 #
-# Actions:
-# objdump: Apply objdump options on result.  Compare with regex (last arg).
-# nm: Apply nm options on result.  Compare with regex (last arg).
-# readelf: Apply readelf options on result.  Compare with regex (last arg).
-# ld: Don't apply anything on result.  Compare output during linking with 
-#     regex (second arg).  Note that this *must* be the first action if it
-#     is to be used at all; in all other cases, any output from the linker
-#     during linking is treated as a sign of an error and FAILs the test.
+# Actions: { command command-line-options file-containg-expected-output-regexps }
+# Commands:
+#   objdump: Apply objdump options on result.
+#   nm: Apply nm options on result.
+#   readelf: Apply readelf options on result.
+#   ld: Don't apply anything on result.  Compare output during linking with 
+#     the file containing regexps (which is the second arg, not the third).
+#     Note that this *must* be the first action if it is to be used at all;
+#     in all other cases, any output from the linker during linking is
+#     treated as a sign of an error and FAILs the test.
 #
 proc run_ld_link_tests { ldtests } {
     global ld
*** /dev/null	2011-06-10 08:00:32.297000001 +0100
--- ld/testsuite/ld-elf/note-3.s	2011-06-10 12:22:16.356479004 +0100
***************
*** 0 ****
--- 1,10 ----
+ 	.globl _entry
+ 	.text
+ _entry:
+ 	.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ 	.global foo
+ foo:
+ 	.byte 9
+ 	
+ 	.section .note,"",%note
+ 	.byte 0
*** /dev/null	2011-06-10 08:00:32.297000001 +0100
--- ld/testsuite/ld-elf/note-3.t	2011-06-10 14:25:32.408479004 +0100
***************
*** 0 ****
--- 1,22 ----
+ PHDRS
+ {
+   text PT_LOAD FILEHDR PHDRS ;
+   note PT_NOTE;
+ }
+ SECTIONS
+ {
+   . = . + SIZEOF_HEADERS ;
+   .text : { *(.text) *(.rodata) } :text
+   .note : { *(.note) } :note :text
+ 
+   /* BUG:  This linker script is broken here.  It has not reset the
+      output segment for the following sections, so they are all
+      treated as notes...   */
+   
+   .hash : { *(.hash) }
+   
+   .dynstr : { *(.dynstr) }
+   .dynsym : { *(.dynsym) }
+   .got.plt : { *(.got.plt) *(.igot.plt) }
+   /DISCARD/ : { *(*) }
+ }
*** /dev/null	2011-06-10 08:00:32.297000001 +0100
--- ld/testsuite/ld-elf/note-3.l	2011-06-10 13:09:09.545481556 +0100
***************
*** 0 ****
--- 1,2 ----
+ .*warning: section '.hash' is being made into a note
+ .*

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