Index: bfd/elf32-avr.c |
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c |
index 38e41df48dfd863e3b1317563684e970e49d0669..b54b67fca12280e165d7c0950e169bdb9ff1464b 100644 |
--- a/bfd/elf32-avr.c |
+++ b/bfd/elf32-avr.c |
@@ -1,7 +1,5 @@ |
/* AVR-specific support for 32-bit ELF |
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, |
- 2010, 2011, 2012 |
- Free Software Foundation, Inc. |
+ Copyright 1999-2013 Free Software Foundation, Inc. |
Contributed by Denis Chertykov <denisc@overta.ru> |
This file is part of BFD, the Binary File Descriptor library. |
@@ -672,7 +670,7 @@ elf32_avr_link_hash_table_create (bfd *abfd) |
struct elf32_avr_link_hash_table *htab; |
bfd_size_type amt = sizeof (*htab); |
- htab = bfd_malloc (amt); |
+ htab = bfd_zmalloc (amt); |
if (htab == NULL) |
return NULL; |
@@ -690,15 +688,6 @@ elf32_avr_link_hash_table_create (bfd *abfd) |
sizeof (struct elf32_avr_stub_hash_entry))) |
return NULL; |
- htab->stub_bfd = NULL; |
- htab->stub_sec = NULL; |
- |
- /* Initialize the address mapping table. */ |
- htab->amt_stub_offsets = NULL; |
- htab->amt_destination_addr = NULL; |
- htab->amt_entry_cnt = 0; |
- htab->amt_max_entry_cnt = 0; |
- |
return &htab->etab.root; |
} |
@@ -717,7 +706,7 @@ elf32_avr_link_hash_table_free (struct bfd_link_hash_table *btab) |
free (htab->amt_destination_addr); |
bfd_hash_table_free (&htab->bstab); |
- _bfd_generic_link_hash_table_free (btab); |
+ _bfd_elf_link_hash_table_free (btab); |
} |
/* Calculates the effective distance of a pc relative jump/call. */ |
@@ -1225,12 +1214,12 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, |
} |
else |
{ |
- bfd_boolean unresolved_reloc, warned; |
+ bfd_boolean unresolved_reloc, warned, ignored; |
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
r_symndx, symtab_hdr, sym_hashes, |
h, sec, relocation, |
- unresolved_reloc, warned); |
+ unresolved_reloc, warned, ignored); |
name = h->root.root.string; |
} |
@@ -1558,7 +1547,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd, |
irel = elf_section_data (isec)->relocs; |
/* PR 12161: Read in the relocs for this section if necessary. */ |
if (irel == NULL) |
- irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, FALSE); |
+ irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE); |
for (irelend = irel + isec->reloc_count; |
irel < irelend; |
@@ -1617,9 +1606,6 @@ elf32_avr_relax_delete_bytes (bfd *abfd, |
/* else...Reference symbol is extern. No need for adjusting |
the addend. */ |
} |
- |
- if (elf_section_data (isec)->relocs == NULL) |
- free (irelend - isec->reloc_count); |
} |
} |
@@ -1706,8 +1692,8 @@ elf32_avr_relax_section (bfd *abfd, |
struct elf32_avr_link_hash_table *htab; |
/* If 'shrinkable' is FALSE, do not shrink by deleting bytes while |
- relaxing. Such shrinking can cause issues for the sections such |
- as .vectors and .jumptables. Instead the unused bytes should be |
+ relaxing. Such shrinking can cause issues for the sections such |
+ as .vectors and .jumptables. Instead the unused bytes should be |
filled with nop instructions. */ |
bfd_boolean shrinkable = TRUE; |
@@ -1878,7 +1864,7 @@ elf32_avr_relax_section (bfd *abfd, |
distance_short_enough = 1; |
/* If shrinkable, then we can check for a range of distance which |
is two bytes farther on both the directions because the call |
- or jump target will be closer by two bytes after the |
+ or jump target will be closer by two bytes after the |
relaxation. */ |
else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4097)) |
distance_short_enough = 1; |
@@ -1955,7 +1941,7 @@ elf32_avr_relax_section (bfd *abfd, |
R_AVR_13_PCREL); |
/* We should not modify the ordering if 'shrinkable' is |
- FALSE. */ |
+ FALSE. */ |
if (!shrinkable) |
{ |
/* Let's insert a nop. */ |
@@ -2150,6 +2136,7 @@ elf32_avr_relax_section (bfd *abfd, |
irel->r_offset + insn_size; |
Elf_Internal_Sym *isym, *isymend; |
unsigned int sec_shndx; |
+ struct bfd_section *isec; |
sec_shndx = |
_bfd_elf_section_from_bfd_section (abfd, sec); |
@@ -2200,80 +2187,85 @@ elf32_avr_relax_section (bfd *abfd, |
} |
} |
} |
- /* Now we check for relocations pointing to ret. */ |
- { |
- Elf_Internal_Rela *rel; |
- Elf_Internal_Rela *relend; |
- relend = elf_section_data (sec)->relocs |
- + sec->reloc_count; |
+ /* Now we check for relocations pointing to ret. */ |
+ for (isec = abfd->sections; isec && deleting_ret_is_safe; isec = isec->next) |
+ { |
+ Elf_Internal_Rela *rel; |
+ Elf_Internal_Rela *relend; |
+ |
+ rel = elf_section_data (isec)->relocs; |
+ if (rel == NULL) |
+ rel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE); |
- for (rel = elf_section_data (sec)->relocs; |
- rel < relend; rel++) |
- { |
- bfd_vma reloc_target = 0; |
+ relend = rel + isec->reloc_count; |
- /* Read this BFD's local symbols if we haven't |
- done so already. */ |
- if (isymbuf == NULL && symtab_hdr->sh_info != 0) |
- { |
- isymbuf = (Elf_Internal_Sym *) |
- symtab_hdr->contents; |
- if (isymbuf == NULL) |
- isymbuf = bfd_elf_get_elf_syms |
- (abfd, |
- symtab_hdr, |
- symtab_hdr->sh_info, 0, |
- NULL, NULL, NULL); |
- if (isymbuf == NULL) |
+ for (; rel && rel < relend; rel++) |
+ { |
+ bfd_vma reloc_target = 0; |
+ |
+ /* Read this BFD's local symbols if we haven't |
+ done so already. */ |
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0) |
+ { |
+ isymbuf = (Elf_Internal_Sym *) |
+ symtab_hdr->contents; |
+ if (isymbuf == NULL) |
+ isymbuf = bfd_elf_get_elf_syms |
+ (abfd, |
+ symtab_hdr, |
+ symtab_hdr->sh_info, 0, |
+ NULL, NULL, NULL); |
+ if (isymbuf == NULL) |
+ break; |
+ } |
+ |
+ /* Get the value of the symbol referred to |
+ by the reloc. */ |
+ if (ELF32_R_SYM (rel->r_info) |
+ < symtab_hdr->sh_info) |
+ { |
+ /* A local symbol. */ |
+ asection *sym_sec; |
+ |
+ isym = isymbuf |
+ + ELF32_R_SYM (rel->r_info); |
+ sym_sec = bfd_section_from_elf_index |
+ (abfd, isym->st_shndx); |
+ symval = isym->st_value; |
+ |
+ /* If the reloc is absolute, it will not |
+ have a symbol or section associated |
+ with it. */ |
+ |
+ if (sym_sec) |
+ { |
+ symval += |
+ sym_sec->output_section->vma |
+ + sym_sec->output_offset; |
+ reloc_target = symval + rel->r_addend; |
+ } |
+ else |
+ { |
+ reloc_target = symval + rel->r_addend; |
+ /* Reference symbol is absolute. */ |
+ } |
+ } |
+ /* else ... reference symbol is extern. */ |
+ |
+ if (address_of_ret == reloc_target) |
+ { |
+ deleting_ret_is_safe = 0; |
+ if (debug_relax) |
+ printf ("ret from " |
+ "rjmp/jmp ret sequence at address" |
+ " 0x%x could not be deleted. ret" |
+ " is target of a relocation.\n", |
+ (int) address_of_ret); |
break; |
- } |
- |
- /* Get the value of the symbol referred to |
- by the reloc. */ |
- if (ELF32_R_SYM (rel->r_info) |
- < symtab_hdr->sh_info) |
- { |
- /* A local symbol. */ |
- asection *sym_sec; |
- |
- isym = isymbuf |
- + ELF32_R_SYM (rel->r_info); |
- sym_sec = bfd_section_from_elf_index |
- (abfd, isym->st_shndx); |
- symval = isym->st_value; |
- |
- /* If the reloc is absolute, it will not |
- have a symbol or section associated |
- with it. */ |
- |
- if (sym_sec) |
- { |
- symval += |
- sym_sec->output_section->vma |
- + sym_sec->output_offset; |
- reloc_target = symval + rel->r_addend; |
- } |
- else |
- { |
- reloc_target = symval + rel->r_addend; |
- /* Reference symbol is absolute. */ |
- } |
- } |
- /* else ... reference symbol is extern. */ |
- |
- if (address_of_ret == reloc_target) |
- { |
- deleting_ret_is_safe = 0; |
- if (debug_relax) |
- printf ("ret from " |
- "rjmp/jmp ret sequence at address" |
- " 0x%x could not be deleted. ret" |
- " is target of a relocation.\n", |
- (int) address_of_ret); |
- } |
- } |
- } |
+ } |
+ } |
+ } |
if (deleting_ret_is_safe) |
{ |
@@ -2294,7 +2286,6 @@ elf32_avr_relax_section (bfd *abfd, |
break; |
} |
} |
- |
} |
} |
break; |