[Patch, avr] Fix PR 12494
[Patch, avr] Fix PR 12494 - Make relaxation consider relocations from all sections before deleting ret
Senthil Kumar Selvaraj senthil_kumar.selvaraj@atmel.comThu Mar 21 13:28:00 GMT 2013
- Previous message (by thread): [gold] Merging string literals with bigger alignment
- Next message (by thread): [Patch, avr] Fix PR 12494 - Make relaxation consider relocations from all sections before deleting ret
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
This patch fixes PR 12494 (relaxation leads to wrong code optimization), by considering relocations from all sections in the BFD before determining that it is safe to delete a ret instruction. The linker relaxation code, as part of relaxing call/ret sequences to jumps, checks whether the ret instruction involved is referred by symbols or by relocation values, before deleting the instruction. The current code only checks relocations in the same (input) section containing the ret instruction. This breaks if a relocation entry is emitted in a different section - which is what happened in the buggy scenario. Computed gotos caused the compiler to place the array of labels in a different section (.rodata), and the assembler dutifully emitted relocations in that section (values resolve to the actual label locations in the .text section). The linker, however, only considered relocations in the .text section and deleted the ret instruction. The fix simply iterates over relocations in all input sections in the BFD, instead of just the input section containing the instruction to delete. If ok, could someone apply please? Regards Senthil ChangeLog 2013-03-21 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> * elf32-avr.c (elf32_avr_relax_section) : Loop over all input sections diff --git bfd/elf32-avr.c bfd/elf32-avr.c index a2d4401..a5a9395 100644 --- bfd/elf32-avr.c +++ bfd/elf32-avr.c @@ -2189,15 +2189,20 @@ elf32_avr_relax_section (bfd *abfd, } } /* Now we check for relocations pointing to ret. */ + struct bfd_section *isec; + + 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); - relend = elf_section_data (sec)->relocs - + sec->reloc_count; + relend = rel + isec->reloc_count; - for (rel = elf_section_data (sec)->relocs; - rel < relend; rel++) + for (; rel && rel < relend; rel++) { bfd_vma reloc_target = 0; @@ -2259,6 +2264,7 @@ elf32_avr_relax_section (bfd *abfd, " 0x%x could not be deleted. ret" " is target of a relocation.\n", (int) address_of_ret); + break; } } }
- Previous message (by thread): [gold] Merging string literals with bigger alignment
- Next message (by thread): [Patch, avr] Fix PR 12494 - Make relaxation consider relocations from all sections before deleting ret
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list