diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d544d0296d0..460e68b8f0e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2016-06-08 Senthil Kumar Selvaraj + + 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 * 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 d463d78c861..b95e251e1e0 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++) { diff --git a/ld/ChangeLog b/ld/ChangeLog index cbb98e3dee4..11470c56d16 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,4 +1,11 @@ +2016-06-08 Senthil Kumar Selvaraj + + PR ld/20221 + * testsuite/ld-avr/avr-prop-5.d: New. + * testsuite/ld-avr/avr-prop-5.s: New. + 2016-06-09 Pitchumani Sivanupandi + * testsuite/ld-avr/lds-mega.d: New test. * testsuite/ld-avr/lds-mega.s: New test source. * testsuite/ld-avr/lds-tiny.d: New test. diff --git a/ld/testsuite/ld-avr/avr-prop-5.d b/ld/testsuite/ld-avr/avr-prop-5.d new file mode 100644 index 00000000000..5f62ba33184 --- /dev/null +++ b/ld/testsuite/ld-avr/avr-prop-5.d @@ -0,0 +1,10 @@ +#name: AVR .avr.prop, single .align proper sym val test. +#as: -mmcu=avrxmega2 -mlink-relax +#ld: -mavrxmega2 --relax +#source: avr-prop-5.s +#objdump: -S +#target: avr-*-* + +#... + 0: 00 d0\s+rcall\s+\.\+0\s+; 0x2 +#... \ No newline at end of file diff --git a/ld/testsuite/ld-avr/avr-prop-5.s b/ld/testsuite/ld-avr/avr-prop-5.s new file mode 100644 index 00000000000..6a3359aef34 --- /dev/null +++ b/ld/testsuite/ld-avr/avr-prop-5.s @@ -0,0 +1,7 @@ + .text + .global _start, dest +_start: + CALL dest + .align 1 +dest: + NOP