From 03669f1c025b2f1bf007cffb03a8dfe6dc7ee448 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Fri, 5 Oct 2007 18:09:57 +0000 Subject: [PATCH] * elf32-xtensa.c (removed_by_actions): New. (offset_with_removed_text): Reimplement using removed_by_actions. (offset_with_removed_text_before_fill): Delete. (relax_property_section): Use removed_by_actions. Rearrange logic. (relax_section_symbols): Likewise. --- bfd/ChangeLog | 8 +++ bfd/elf32-xtensa.c | 142 ++++++++++++++++++++++----------------------- 2 files changed, 78 insertions(+), 72 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 52af1bbf16..c265a25987 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2007-10-05 Bob Wilson + + * elf32-xtensa.c (removed_by_actions): New. + (offset_with_removed_text): Reimplement using removed_by_actions. + (offset_with_removed_text_before_fill): Delete. + (relax_property_section): Use removed_by_actions. Rearrange logic. + (relax_section_symbols): Likewise. + 2007-10-04 Bob Wilson * elf32-xtensa.c (reloc_bfd_fix_struct): Delete target_abfd field. diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 6454a88780..acdff77423 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -4780,20 +4780,45 @@ text_action_add_literal (text_action_list *l, } -static bfd_vma -offset_with_removed_text (text_action_list *action_list, bfd_vma offset) +/* Find the total offset adjustment for the relaxations specified by + text_actions, beginning from a particular starting action. This is + typically used from offset_with_removed_text to search an entire list of + actions, but it may also be called directly when adjusting adjacent offsets + so that each search may begin where the previous one left off. */ + +static int +removed_by_actions (text_action **p_start_action, + bfd_vma offset, + bfd_boolean before_fill) { text_action *r; int removed = 0; - for (r = action_list->head; r && r->offset <= offset; r = r->next) + r = *p_start_action; + while (r) { - if (r->offset < offset - || (r->action == ta_fill && r->removed_bytes < 0)) - removed += r->removed_bytes; + if (r->offset > offset) + break; + + if (r->offset == offset + && (before_fill || r->action != ta_fill || r->removed_bytes >= 0)) + break; + + removed += r->removed_bytes; + + r = r->next; } - return (offset - removed); + *p_start_action = r; + return removed; +} + + +static bfd_vma +offset_with_removed_text (text_action_list *action_list, bfd_vma offset) +{ + text_action *r = action_list->head; + return offset - removed_by_actions (&r, offset, FALSE); } @@ -4810,20 +4835,6 @@ action_list_count (text_action_list *action_list) } -static bfd_vma -offset_with_removed_text_before_fill (text_action_list *action_list, - bfd_vma offset) -{ - text_action *r; - int removed = 0; - - for (r = action_list->head; r && r->offset < offset; r = r->next) - removed += r->removed_bytes; - - return (offset - removed); -} - - /* The find_insn_action routine will only find non-fill actions. */ static text_action * @@ -8943,14 +8954,16 @@ relax_property_section (bfd *abfd, || target_relax_info->is_relaxable_asm_section )) { /* Translate the relocation's destination. */ - bfd_vma new_offset, new_end_offset; + bfd_vma old_offset = val.r_rel.target_offset; + bfd_vma new_offset; long old_size, new_size; - - new_offset = offset_with_removed_text - (&target_relax_info->action_list, val.r_rel.target_offset); + text_action *act = target_relax_info->action_list.head; + new_offset = old_offset - + removed_by_actions (&act, old_offset, FALSE); /* Assert that we are not out of bounds. */ old_size = bfd_get_32 (abfd, size_p); + new_size = old_size; if (old_size == 0) { @@ -8962,39 +8975,34 @@ relax_property_section (bfd *abfd, offset before or after the fill address depending on whether the expanding unreachable entry preceeds it. */ - if (last_zfill_target_sec - && last_zfill_target_sec == target_sec - && last_zfill_target_offset == val.r_rel.target_offset) - new_end_offset = new_offset; - else + if (last_zfill_target_sec == 0 + || last_zfill_target_sec != target_sec + || last_zfill_target_offset != old_offset) { - new_end_offset = new_offset; - new_offset = offset_with_removed_text_before_fill - (&target_relax_info->action_list, - val.r_rel.target_offset); + bfd_vma new_end_offset = new_offset; + + /* Recompute the new_offset, but this time don't + include any fill inserted by relaxation. */ + act = target_relax_info->action_list.head; + new_offset = old_offset - + removed_by_actions (&act, old_offset, TRUE); /* If it is not unreachable and we have not yet seen an unreachable at this address, place it before the fill address. */ - if (!flags_p - || (bfd_get_32 (abfd, flags_p) - & XTENSA_PROP_UNREACHABLE) == 0) - new_end_offset = new_offset; - else + if (flags_p && (bfd_get_32 (abfd, flags_p) + & XTENSA_PROP_UNREACHABLE) != 0) { + new_size = new_end_offset - new_offset; + last_zfill_target_sec = target_sec; - last_zfill_target_offset = val.r_rel.target_offset; + last_zfill_target_offset = old_offset; } } } else - { - new_end_offset = offset_with_removed_text_before_fill - (&target_relax_info->action_list, - val.r_rel.target_offset + old_size); - } - - new_size = new_end_offset - new_offset; + new_size -= + removed_by_actions (&act, old_offset + old_size, TRUE); if (new_size != old_size) { @@ -9002,9 +9010,9 @@ relax_property_section (bfd *abfd, pin_contents (sec, contents); } - if (new_offset != val.r_rel.target_offset) + if (new_offset != old_offset) { - bfd_vma diff = new_offset - val.r_rel.target_offset; + bfd_vma diff = new_offset - old_offset; irel->r_addend += diff; pin_internal_relocs (sec, internal_relocs); } @@ -9257,19 +9265,14 @@ relax_section_symbols (bfd *abfd, asection *sec) if (isym->st_shndx == sec_shndx) { - bfd_vma new_address = offset_with_removed_text - (&relax_info->action_list, isym->st_value); - bfd_vma new_size = isym->st_size; + text_action *act = relax_info->action_list.head; + bfd_vma orig_addr = isym->st_value; - if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC) - { - bfd_vma new_end = offset_with_removed_text - (&relax_info->action_list, isym->st_value + isym->st_size); - new_size = new_end - new_address; - } + isym->st_value -= removed_by_actions (&act, orig_addr, FALSE); - isym->st_value = new_address; - isym->st_size = new_size; + if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC) + isym->st_size -= + removed_by_actions (&act, orig_addr + isym->st_size, FALSE); } } @@ -9287,20 +9290,15 @@ relax_section_symbols (bfd *abfd, asection *sec) || sym_hash->root.type == bfd_link_hash_defweak) && sym_hash->root.u.def.section == sec) { - bfd_vma new_address = offset_with_removed_text - (&relax_info->action_list, sym_hash->root.u.def.value); - bfd_vma new_size = sym_hash->size; + text_action *act = relax_info->action_list.head; + bfd_vma orig_addr = sym_hash->root.u.def.value; - if (sym_hash->type == STT_FUNC) - { - bfd_vma new_end = offset_with_removed_text - (&relax_info->action_list, - sym_hash->root.u.def.value + sym_hash->size); - new_size = new_end - new_address; - } + sym_hash->root.u.def.value -= + removed_by_actions (&act, orig_addr, FALSE); - sym_hash->root.u.def.value = new_address; - sym_hash->size = new_size; + if (sym_hash->type == STT_FUNC) + sym_hash->size -= + removed_by_actions (&act, orig_addr + sym_hash->size, FALSE); } } -- 2.34.1