This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
fix Xtensa ld crash on bad input
- From: Bob Wilson <bwilson at tensilica dot com>
- To: binutils at sources dot redhat dot com
- Date: Thu, 01 Mar 2007 15:41:51 -0800
- Subject: 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;