| [ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
3.17.4.1 EIND and Devices with more than 128 Ki Bytes of Flash
Pointers in the implementation are 16 bits wide. The address of a function or label is represented as word address so that indirect jumps and calls can target any code address in the range of 64 Ki words.
In order to facilitate indirect jump on devices with more than 128 Ki
bytes of program memory space, there is a special function register called
EIND that serves as most significant part of the target address
when EICALL or EIJMP instructions are used.
Indirect jumps and calls on these devices are handled as follows by the compiler and are subject to some limitations:
-
The compiler never sets
EIND. -
The compiler uses
EINDimplicitely inEICALL/EIJMPinstructions or might readEINDdirectly in order to emulate an indirect call/jump by means of aRETinstruction. -
The compiler assumes that
EINDnever changes during the startup code or during the application. In particular,EINDis not saved/restored in function or interrupt service routine prologue/epilogue. - For indirect calls to functions and computed goto, the linker generates stubs. Stubs are jump pads sometimes also called trampolines. Thus, the indirect call/jump jumps to such a stub. The stub contains a direct jump to the desired address.
-
Linker relaxation must be turned on so that the linker will generate
the stubs correctly an all situaltion. See the compiler option
-mrelaxand the linler option--relax. There are corner cases where the linker is supposed to generate stubs but aborts without relaxation and without a helpful error message. -
The default linker script is arranged for code with
EIND = 0. If code is supposed to work for a setup withEIND != 0, a custom linker script has to be used in order to place the sections whose name start with.trampolinesinto the segment whereEINDpoints to. -
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 onEIND, see the http://nongnu.org/avr-libc/user-manual/">AVR-LibC user manual. -
It is legitimate for user-specific startup code to set up
EINDearly, for example by means of initialization code located in section.init3. Such code runs prior to general startup code that initializes RAM and calls constructors, but after the bit of startup code from AVR-LibC that setsEINDto the segment where the vector table is located.#include <avr/io.h> static void __attribute__((section(".init3"),naked,used,no_instrument_function)) init3_set_eind (void) { __asm volatile ("ldi r24,pm_hh8(__trampolines_start)\n\t" "out %i0,r24" :: "n" (&EIND) : "r24","memory"); }The
__trampolines_startsymbol is defined in the linker script. -
Stubs are generated automatically by the linker if
the following two conditions are met:
- - The address of a label is taken by means of the
gsmodifier (short for generate stubs) like so:LDI r24, lo8(gs(func)) LDI r25, hi8(gs(func))
- - The final location of that label is in a code segment outside the segment where the stubs are located.
- - The address of a label is taken by means of the
-
The compiler emits such
gsmodifiers for code labels in the following situations:- - Taking address 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/destructors called during startup/shutdown.
- - If the tools hit a
gs()modifier explained above.
-
Jumping to non-symbolic addresses like so is not supported:
int main (void) { /* Call function at word address 0x2 */ return ((int(*)(void)) 0x2)(); }Instead, a stub has to be set up, i.e. the function has to be called through a symbol (
func_4in the example):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. Alternatively,func_4can be defined in the linker script.
| [ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on October 19, 2013 using texi2html 5.0.
