-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Closed
Labels
Description
Consider the following C code:
int func (void);
int main (void)
{
int (*f)(void) = func;
__asm ("" : "+r" (f));
return f();
}
and compiled with:
> clang --target=avr foo.c -Os -save-temps -mmcu=atmega2560 -Os -o foo.elf -Wl,--defsym,func=0x22222
> avr-objdump -d foo.elf > foo.lst
> avr-objdump -dr foo.o > foo.lss
So that the code mimics a function func
located at 0x22222. There are problems with the generated code:
- main is using
icall
to executef()
, buticall
will always target the low 128KiB segment. The correct instruction iseicall
resp.eijmp
for tail-calls. - The compiler uses the wrong relocations like
pm_lo8(sym)
andpm_hi8(sym)
, where the correct code will uselo8(gs(sym))
andhi8(gs(sym))
; so the GNU linker will generate stubs as needed. Correct RELOCs areR_AVR_LO8_LDI_GS
resp.R_AVR_HI8_LDI_GS
. - If main was located beyond the first 128KiB segment,
icall
/ijmp
won't work either, correct areeicall
/eijmp
, cf. also startup-code.
FYI, the disassembly of main is as of foo.lst
is:
0000012c <main>:
12c: e1 e1 ldi r30, 0x11 ; 17
12e: f1 e1 ldi r31, 0x11 ; 17
130: 09 95 icall
132: 08 95 ret
so the call will target 0x2222, not 0x22222.