diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf32-avr.c | 21 |
2 files changed, 24 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d544d02..460e68b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2016-06-08 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> + + PR ld/20221 + * elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust syms + and relocs only if shrinking occurred. + 2016-06-08 H.J. Lu <hongjiu.lu@intel.com> * elf64-i386.c (elf_i386_link_hash_entry): Add tls_get_addr. diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index d463d78..b95e251 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1828,6 +1828,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd, unsigned int symcount; struct avr_relax_info *relax_info; struct avr_property_record *prop_record = NULL; + bfd_boolean did_shrink = FALSE; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); @@ -1863,10 +1864,16 @@ elf32_avr_relax_delete_bytes (bfd *abfd, /* Actually delete the bytes. */ if (toaddr - addr - count > 0) - memmove (contents + addr, contents + addr + count, - (size_t) (toaddr - addr - count)); + { + memmove (contents + addr, contents + addr + count, + (size_t) (toaddr - addr - count)); + did_shrink = TRUE; + } if (prop_record == NULL) - sec->size -= count; + { + sec->size -= count; + did_shrink = TRUE; + } else { /* Use the property record to fill in the bytes we've opened up. */ @@ -1885,6 +1892,11 @@ elf32_avr_relax_delete_bytes (bfd *abfd, prop_record->data.align.preceding_deleted += count; break; }; + /* If toaddr == (addr + count), then we didn't delete anything, yet + we fill count bytes backwards from toaddr. This is still ok - we + end up overwriting the bytes we would have deleted. We just need + to remember we didn't delete anything i.e. don't set did_shrink, + so that we don't corrupt reloc offsets or symbol values.*/ memset (contents + toaddr - count, fill, count); /* Adjust the TOADDR to avoid moving symbols located at the address @@ -1892,6 +1904,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd, toaddr -= count; } + if (!did_shrink) + return TRUE; + /* Adjust all the reloc addresses. */ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) { |