From 0854d50445a11847f80e655482fd180d7c4e4d00 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 15 Mar 2018 10:35:59 -0700 Subject: xtensa: bfd: fix assertion in xlate_offset_with_removed_text Linking objects containing jumps targeting the end of a section triggers assertion in the xlate_offset_with_removed_text. Such jumps may be generated by a compiler as a dead code and not removed at -O0. Allow such jumps. While at it make bsearch argument match comparison function expectations and use bfd_vma for address fields in the struct xlate_map_entry. bfd/ 2018-03-15 Max Filippov * elf32-xtensa.c (xlate_map_entry): Change types of address fields from 'unsigned' to 'bfd_vma'. (xlate_offset_with_removed_text): Use struct xlate_map_entry as the key argument to bsearch. Allow offsets past the end of a section, use the last map entry for translation of such offsets. --- bfd/elf32-xtensa.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'bfd/elf32-xtensa.c') diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index cd08796..c12b2f5 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -8150,8 +8150,8 @@ typedef struct xlate_map xlate_map_t; struct xlate_map_entry { - unsigned orig_address; - unsigned new_address; + bfd_vma orig_address; + bfd_vma new_address; unsigned size; }; @@ -8182,6 +8182,7 @@ xlate_offset_with_removed_text (const xlate_map_t *map, { void *r; xlate_map_entry_t *e; + struct xlate_map_entry se; if (map == NULL) return offset_with_removed_text (action_list, offset); @@ -8189,10 +8190,19 @@ xlate_offset_with_removed_text (const xlate_map_t *map, if (map->entry_count == 0) return offset; - r = bsearch (&offset, map->entry, map->entry_count, + se.orig_address = offset; + r = bsearch (&se, map->entry, map->entry_count, sizeof (xlate_map_entry_t), &xlate_compare); e = (xlate_map_entry_t *) r; + /* There could be a jump past the end of the section, + allow it using the last xlate map entry to translate its address. */ + if (e == NULL) + { + e = map->entry + map->entry_count - 1; + if (xlate_compare (&se, e) <= 0) + e = NULL; + } BFD_ASSERT (e != NULL); if (e == NULL) return offset; -- cgit v1.1