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]

fix Xtensa ld crash on bad input


The Xtensa linker relaxation needs to decode a lot of the instructions from the input objects. If the opcodes are not recognized, due to user error or whatever, ld is supposed to fail gracefully but instead it was crashing. This patch fixes the crash so that it fails nicely. It also adds an assertion to detect similar problems in the future. Tested with an xtensa-elf build and committed.

bfd/
	* elf32-xtensa.c (analyze_relocations): Zero src_count if not relaxing.
	(find_relaxable_sections): Do not increment src_count for unknown
	opcodes.  Decode only once instead of calling is_l32r_relocation.
	(compute_text_actions): Remove unused no_insn_move flag.  Assert that
	src_next matches src_count in relax_info.

Index: elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.80
diff -u -p -r1.80 elf32-xtensa.c
--- elf32-xtensa.c	5 Feb 2007 17:42:38 -0000	1.80
+++ elf32-xtensa.c	1 Mar 2007 23:31:31 -0000
@@ -5913,6 +5913,8 @@ analyze_relocations (struct bfd_link_inf
 	    relax_info->src_relocs = (source_reloc *)
 	      bfd_malloc (relax_info->src_count * sizeof (source_reloc));
 	  }
+	else
+	  relax_info->src_count = 0;
       }
 
   /* Collect info on relocations against each relaxable section.  */
@@ -5956,6 +5958,7 @@ find_relaxable_sections (bfd *abfd,
   bfd_boolean ok = TRUE;
   unsigned i;
   xtensa_relax_info *source_relax_info;
+  bfd_boolean is_l32r_reloc;
 
   internal_relocs = retrieve_internal_relocs (abfd, sec,
 					      link_info->keep_memory);
@@ -6006,13 +6009,21 @@ find_relaxable_sections (bfd *abfd,
       /* Count PC-relative operand relocations against the target section.
          Note: The conditions tested here must match the conditions under
 	 which init_source_reloc is called in collect_source_relocs().  */
-      if (is_operand_relocation (ELF32_R_TYPE (irel->r_info))
-	  && (!is_alt_relocation (ELF32_R_TYPE (irel->r_info))
-	      || is_l32r_relocation (abfd, sec, contents, irel)))
-	target_relax_info->src_count++;
+      is_l32r_reloc = FALSE;
+      if (is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
+	{
+	  xtensa_opcode opcode =
+	    get_relocation_opcode (abfd, sec, contents, irel);
+	  if (opcode != XTENSA_UNDEFINED)
+	    {
+	      is_l32r_reloc = (opcode == get_l32r_opcode ());
+	      if (!is_alt_relocation (ELF32_R_TYPE (irel->r_info))
+		  || is_l32r_reloc)
+		target_relax_info->src_count++;
+	    }
+	}
 
-      if (is_l32r_relocation (abfd, sec, contents, irel)
-	  && r_reloc_is_defined (&r_rel))
+      if (is_l32r_reloc && r_reloc_is_defined (&r_rel))
 	{
 	  /* Mark the target section as relaxable.  */
 	  target_relax_info->is_relaxable_literal_section = TRUE;
@@ -6333,14 +6344,12 @@ compute_text_actions (bfd *abfd,
   property_table_entry *prop_table = 0;
   int ptblsize = 0;
   bfd_size_type sec_size;
-  static bfd_boolean no_insn_move = FALSE;
 
-  if (no_insn_move)
-    return ok;
-
-  /* Do nothing if the section contains no optimized longcalls.  */
   relax_info = get_xtensa_relax_info (sec);
   BFD_ASSERT (relax_info);
+  BFD_ASSERT (relax_info->src_next == relax_info->src_count);
+
+  /* Do nothing if the section contains no optimized longcalls.  */
   if (!relax_info->is_relaxable_asm_section)
     return ok;
 

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