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

Reply via email to