http://sourceware.org/bugzilla/show_bug.cgi?id=14058
Jan Waclawek <konfera at efton dot sk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|DUPLICATE | --- Comment #8 from Jan Waclawek <konfera at efton dot sk> 2012-05-06 15:23:17 UTC --- The bug is consequence of performing a relaxation-related optimisation step - reduction of the stubs table (.trampolines section) through removing stubs targeting labels which are directly reachable (i.e. are in the "segment" pointed by the default EIND) when --relax has not been specified. This step is performed in the elf32_avr_size_stubs() function in [binutils]/bfd/elf32-avr.c. The stubs table is first created through calling elf32_avr_size_stubs() from avr_elf_${EMULATION_NAME}_before_allocation() in [binutils]/ld/emultempl/avrelf.em. It is called with the is_prealloc_run parameter set to TRUE, which results in the complete table being built containing all the targets of gs(). This step yields the maximal size of the stubs table (.trampolines section), which is then used in the initial output sections allocation. When no relax, elf32_avr_size_stubs() is called second time from avr_elf_after_allocation() (avrelf.em). The purpose of this is to fill the stubs table with instructions for jumps to the target addresses, which thus have to be known already (from the previous allocation). elf32_avr_size_stubs() is called with is_prealloc_run parameter set to FALSE, but that results in marking those stubs, which jump to "reachable" targets, as unused (note, that this is the only purpose of the is_prealloc_run parameter, so its name is misleading), thus the table's size might get reduced. As this results in moving the target labels in the subsequent address fixing step of the linker, the stub target addresses no longer match the real target addresses, which is then detected in avr_final_link_relocate() at labels R_AVR_LO8_LDI_GS:, R_AVR_HI8_LDI_GS: and R_AVR_16_PM: and the error is subsequently thrown. (When --relax, the change of stubs section size is detected when calling elf32_avr_size_stubs() from elf32_avr_relax_section() and if changed, through setting *again invokes one more relaxation iteration which takes care of fixing the changed target addresses). The fix is surprisingly simple: +++ avrelf.em Sun May 6 17:06:25 2012 @@ -152,7 +152,7 @@ { /* If relaxing, elf32_avr_size_stubs will be called from elf32_avr_relax_section. */ - if (!elf32_avr_size_stubs (link_info.output_bfd, &link_info, FALSE)) + if (!elf32_avr_size_stubs (link_info.output_bfd, &link_info, TRUE)) einfo ("%X%P: can not size stub section: %E\n"); } So now, elf32_avr_size_stubs() for the non-relax case won't drop any entry thus the target addresses will remain correct. It would be perhaps good also to rename the is_prealloc_run parameter of elf32_avr_size_stubs() to something more appropriate, e.g. no_resize or such. Please note, that while this fixes a genuine bug, it also removes a "beneficial side effect" of the bug for those applications, which don't use --relax and at the same time don't have gs() targets above 0x20000 - so far they benefited from complete removal of the unneeded stubs table (which went unnoticed as then there were no incorrect stubs targets anymore). So, they now will experience both growth in size (as the stubs table is not removed anymore) and decreased execution speed (as indirect jumps will go through the stubs). As many of these chips are in fact used for relatively small application and use the big flash only for extensive data, this would impair a fair number of applications. In spite of that, I don't think it's necessary to implement any other fix for this other than change in documentation, which should recommend using the --no-stubs switch for those cases. -- Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils