[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/14058] Internal overflow error, on >128kB FLASH with no relaxati

From: konfera at efton dot sk
Subject: [Bug ld/14058] Internal overflow error, on >128kB FLASH with no relaxation
Date: Sun, 06 May 2012 15:23:17 +0000


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.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]