Fix PR 20221 - adjust syms and relocs only if relax shrunk section.

This patch fixes an edge case in linker relaxation that causes symbol
values to be computed incorrectly in the presence of align directives
in input source code.

bfd/
	* elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust syms
	and relocs only if shrinking occurred.

ld/
	* testsuite/ld-avr/avr-prop-5.d: New.
	* testsuite/ld-avr/avr-prop-5.s: New.
This commit is contained in:
Denis Chertykov
2016-06-09 19:17:43 +03:00
parent 1857fe72af
commit 5c41dbc302
5 changed files with 48 additions and 3 deletions

View File

@ -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> 2016-06-08 H.J. Lu <hongjiu.lu@intel.com>
* elf64-i386.c (elf_i386_link_hash_entry): Add tls_get_addr. * elf64-i386.c (elf_i386_link_hash_entry): Add tls_get_addr.

View File

@ -1828,6 +1828,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
unsigned int symcount; unsigned int symcount;
struct avr_relax_info *relax_info; struct avr_relax_info *relax_info;
struct avr_property_record *prop_record = NULL; struct avr_property_record *prop_record = NULL;
bfd_boolean did_shrink = FALSE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 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. */ /* Actually delete the bytes. */
if (toaddr - addr - count > 0) 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) if (prop_record == NULL)
sec->size -= count; {
sec->size -= count;
did_shrink = TRUE;
}
else else
{ {
/* Use the property record to fill in the bytes we've opened up. */ /* 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; prop_record->data.align.preceding_deleted += count;
break; 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); memset (contents + toaddr - count, fill, count);
/* Adjust the TOADDR to avoid moving symbols located at the address /* Adjust the TOADDR to avoid moving symbols located at the address
@ -1892,6 +1904,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
toaddr -= count; toaddr -= count;
} }
if (!did_shrink)
return TRUE;
/* Adjust all the reloc addresses. */ /* Adjust all the reloc addresses. */
for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
{ {

View File

@ -1,4 +1,11 @@
2016-06-08 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR ld/20221
* testsuite/ld-avr/avr-prop-5.d: New.
* testsuite/ld-avr/avr-prop-5.s: New.
2016-06-09 Pitchumani Sivanupandi <pitchumani.s@atmel.com> 2016-06-09 Pitchumani Sivanupandi <pitchumani.s@atmel.com>
* testsuite/ld-avr/lds-mega.d: New test. * testsuite/ld-avr/lds-mega.d: New test.
* testsuite/ld-avr/lds-mega.s: New test source. * testsuite/ld-avr/lds-mega.s: New test source.
* testsuite/ld-avr/lds-tiny.d: New test. * testsuite/ld-avr/lds-tiny.d: New test.

View File

@ -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 <dest>
#...

View File

@ -0,0 +1,7 @@
.text
.global _start, dest
_start:
CALL dest
.align 1
dest:
NOP