http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38549
Georg-Johann Lay <gjl at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
CC| |gjl at gcc dot gnu.org
Resolution| |INVALID
--- Comment #6 from Georg-Johann Lay <gjl at gcc dot gnu.org> 2011-10-23
15:24:15 UTC ---
Closed as INVALID.
In the remainder you find an ouline of how to cope with indirect jumps on
devices with more than >128 KiB of code.
Actually, the flaw is that the following explanation is not yet part of the
documentation, see PR50820.
* The compiler never sets EIND.
* The startup code from libgcc never sets EIND.
Notice that startup code is a blend of code from libgcc and avr-libc.
For the impact of avr-libc on EIND, see avr-libc documentation.
* The compiler uses EIND in EICALL/EIJMP instructions or might read
EIND directly.
* The compiler assumes that EIND is not changed during startup code or
run of the application. In particular, EIND is not saved/restored in
function or interrupt service routine prologue/epilogue.
* It is legitimate for user-specific startup code to setup EIND
early, for example by means of initialization code located in
section .init3 prior to general startup code that initializes
RAM and calls constructors.
* For indirect calls to functions and computed goto, the linker will
generate stubs. Stubs are jump pads sometimes also called trampolines.
Thus, the indirect call/jump will jump to such a stub.
The stub contains a direct jump to the desired address.
* Jump pads will be generated automatically by the linker if
- the address of label is taken like so
LDI r24, lo8(gs(func))
LDI r25, hi8(gs(func))
- and if the final location of that label is in a code segment
*outside* the segment where the stubs are located.
The compiler will emit gs() relocations (short for generate
stubs) if the address of a label is taken.
* Addresses of labals are taken in the following situations:
- Taking address of of a function or code label
- Computed goto
- If prologue-save function is used, see -mcall-prologues
command line option
- Switch/case dispatch tables. If you do not want such dispatch
tables you can specify the -fno-jump-tables command line option.
- C and C++ constructors called during startup
- C and C++ destructors called during shutdown
- If the tools hit a gs() directive explained above
* The default linker script is arranged for code with EIND = 0.
If code is supposed to work for a setup with EIND != 0, a custom
linker script has to be used in order to place the sections whose
name start with .trampolines into the segment where EIND points to.
* Jumping to a non-symbolic addresse like so:
int main (void)
{
// Call function at word address 0x2
return ((int(*)(void)) 0x2)();
}
is /not/ supported. Instead, a stub has to be set up like so:
int main (void)
{
extern int func_4 (void);
// Call function at byte address 0x4
return func_4();
}
and the application be linked with -Wl,-defsym=func_4=0x4