[PATCH 2/3] MIPS/BFD: Correct IRIX 6 DT_MIPS_OPTIONS processing

Maciej W. Rozycki macro@codesourcery.com
Wed Aug 8 22:50:00 GMT 2012


Hello,

 The change below fixes a segmentation fault in LD triggered when the 
.MIPS.options n64 ABI special section is forcefully removed by a /DISCARD/ 
clause in the linker script used.  In this case a DT_MIPS_OPTIONS dynamic 
tag is nevertheless created and when later on in 
_bfd_mips_elf_finish_dynamic_sections LD tries to retrieve the section's 
address to use as the value of the tag it crashes on a NULL pointer 
dereference.

 For reasons beyond my knowledge the tag is only used for IRIX 6 targets 
and never for Linux, although the special .MIPS.options section is always 
produced; `readelf' is only capable of decoding the contents of the 
section if the dynamic tag has also been created.

 The fix causes the creation of a DT_MIPS_OPTIONS dynamic 
section/segment's entry to be omitted if no output section has been made 
for .MIPS.options, making the crash go away.  The fix is covered by the 
test cases used to verify processing of R_MIPS_CALL16 relocations that end 
up satified by a symbol of the protected export class.  The test cases are 
provided separately.

 No regressions for the other 22 MIPS targets, OK to apply?

2012-08-08  Maciej W. Rozycki  <macro@codesourcery.com>

	bfd/
	* elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Only add a 
	DT_MIPS_OPTIONS tag if output options section has been created.

  Maciej

binutils-bfd-mips-irix-options.diff
Index: binutils-fsf-trunk-quilt/bfd/elfxx-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/bfd/elfxx-mips.c	2012-07-26 03:29:00.000000000 +0100
+++ binutils-fsf-trunk-quilt/bfd/elfxx-mips.c	2012-07-26 04:45:31.560520511 +0100
@@ -9268,11 +9268,17 @@ _bfd_mips_elf_size_dynamic_sections (bfd
 	      && ! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_HIPAGENO, 0))
 	    return FALSE;
 
-	  if (IRIX_COMPAT (dynobj) == ict_irix6
-	      && (bfd_get_section_by_name
-		  (dynobj, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
-	      && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0))
-	    return FALSE;
+	  if (IRIX_COMPAT (dynobj) == ict_irix6)
+	    {
+	      const char *const name = MIPS_ELF_OPTIONS_SECTION_NAME (dynobj);
+	      asection *opt_sec;
+
+	      opt_sec = bfd_get_section_by_name (dynobj, name);
+	      if (opt_sec != NULL
+		  && opt_sec->output_section != bfd_abs_section_ptr
+		  && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0))
+		return FALSE;
+	    }
 	}
       if (htab->splt->size > 0)
 	{



More information about the Binutils mailing list