* 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.
This commit is contained in:
Bob Wilson 2007-10-05 18:09:57 +00:00
parent 368d64cc37
commit 03669f1c02
2 changed files with 78 additions and 72 deletions

View File

@ -1,3 +1,11 @@
2007-10-05 Bob Wilson <bob.wilson@acm.org>
* 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 <bob.wilson@acm.org> 2007-10-04 Bob Wilson <bob.wilson@acm.org>
* elf32-xtensa.c (reloc_bfd_fix_struct): Delete target_abfd field. * elf32-xtensa.c (reloc_bfd_fix_struct): Delete target_abfd field.

View File

@ -4780,20 +4780,45 @@ text_action_add_literal (text_action_list *l,
} }
static bfd_vma /* Find the total offset adjustment for the relaxations specified by
offset_with_removed_text (text_action_list *action_list, bfd_vma offset) 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; text_action *r;
int removed = 0; 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 if (r->offset > offset)
|| (r->action == ta_fill && r->removed_bytes < 0)) break;
removed += r->removed_bytes;
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. */ /* The find_insn_action routine will only find non-fill actions. */
static text_action * static text_action *
@ -8943,14 +8954,16 @@ relax_property_section (bfd *abfd,
|| target_relax_info->is_relaxable_asm_section )) || target_relax_info->is_relaxable_asm_section ))
{ {
/* Translate the relocation's destination. */ /* 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; long old_size, new_size;
text_action *act = target_relax_info->action_list.head;
new_offset = offset_with_removed_text new_offset = old_offset -
(&target_relax_info->action_list, val.r_rel.target_offset); removed_by_actions (&act, old_offset, FALSE);
/* Assert that we are not out of bounds. */ /* Assert that we are not out of bounds. */
old_size = bfd_get_32 (abfd, size_p); old_size = bfd_get_32 (abfd, size_p);
new_size = old_size;
if (old_size == 0) if (old_size == 0)
{ {
@ -8962,39 +8975,34 @@ relax_property_section (bfd *abfd,
offset before or after the fill address depending offset before or after the fill address depending
on whether the expanding unreachable entry on whether the expanding unreachable entry
preceeds it. */ preceeds it. */
if (last_zfill_target_sec if (last_zfill_target_sec == 0
&& last_zfill_target_sec == target_sec || last_zfill_target_sec != target_sec
&& last_zfill_target_offset == val.r_rel.target_offset) || last_zfill_target_offset != old_offset)
new_end_offset = new_offset;
else
{ {
new_end_offset = new_offset; bfd_vma new_end_offset = new_offset;
new_offset = offset_with_removed_text_before_fill
(&target_relax_info->action_list, /* Recompute the new_offset, but this time don't
val.r_rel.target_offset); 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 /* If it is not unreachable and we have not yet
seen an unreachable at this address, place it seen an unreachable at this address, place it
before the fill address. */ before the fill address. */
if (!flags_p if (flags_p && (bfd_get_32 (abfd, flags_p)
|| (bfd_get_32 (abfd, flags_p) & XTENSA_PROP_UNREACHABLE) != 0)
& XTENSA_PROP_UNREACHABLE) == 0)
new_end_offset = new_offset;
else
{ {
new_size = new_end_offset - new_offset;
last_zfill_target_sec = target_sec; last_zfill_target_sec = target_sec;
last_zfill_target_offset = val.r_rel.target_offset; last_zfill_target_offset = old_offset;
} }
} }
} }
else else
{ new_size -=
new_end_offset = offset_with_removed_text_before_fill removed_by_actions (&act, old_offset + old_size, TRUE);
(&target_relax_info->action_list,
val.r_rel.target_offset + old_size);
}
new_size = new_end_offset - new_offset;
if (new_size != old_size) if (new_size != old_size)
{ {
@ -9002,9 +9010,9 @@ relax_property_section (bfd *abfd,
pin_contents (sec, contents); 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; irel->r_addend += diff;
pin_internal_relocs (sec, internal_relocs); pin_internal_relocs (sec, internal_relocs);
} }
@ -9257,19 +9265,14 @@ relax_section_symbols (bfd *abfd, asection *sec)
if (isym->st_shndx == sec_shndx) if (isym->st_shndx == sec_shndx)
{ {
bfd_vma new_address = offset_with_removed_text text_action *act = relax_info->action_list.head;
(&relax_info->action_list, isym->st_value); bfd_vma orig_addr = isym->st_value;
bfd_vma new_size = isym->st_size;
isym->st_value -= removed_by_actions (&act, orig_addr, FALSE);
if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC) if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC)
{ isym->st_size -=
bfd_vma new_end = offset_with_removed_text removed_by_actions (&act, orig_addr + isym->st_size, FALSE);
(&relax_info->action_list, isym->st_value + isym->st_size);
new_size = new_end - new_address;
}
isym->st_value = new_address;
isym->st_size = new_size;
} }
} }
@ -9287,20 +9290,15 @@ relax_section_symbols (bfd *abfd, asection *sec)
|| sym_hash->root.type == bfd_link_hash_defweak) || sym_hash->root.type == bfd_link_hash_defweak)
&& sym_hash->root.u.def.section == sec) && sym_hash->root.u.def.section == sec)
{ {
bfd_vma new_address = offset_with_removed_text text_action *act = relax_info->action_list.head;
(&relax_info->action_list, sym_hash->root.u.def.value); bfd_vma orig_addr = sym_hash->root.u.def.value;
bfd_vma new_size = sym_hash->size;
sym_hash->root.u.def.value -=
removed_by_actions (&act, orig_addr, FALSE);
if (sym_hash->type == STT_FUNC) if (sym_hash->type == STT_FUNC)
{ sym_hash->size -=
bfd_vma new_end = offset_with_removed_text removed_by_actions (&act, orig_addr + sym_hash->size, FALSE);
(&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 = new_address;
sym_hash->size = new_size;
} }
} }