| 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; | 
|  |