"kernel coder" <[EMAIL PROTECTED]> writes:
> Following is the code for which i'm trying to undertsand the generated
> trampoline code.
>
> int foo(int (*f)()){
> (*f)();
> }
> main(){
> int i;
> int g(){printf("hello,%d",i);}
> foo(g);
> }
>
> Parts of generated assembly code which are confusing are
I think you need to trim down your question. Which parts do you not
understand?
> $LTRAMP0:
> .word 0x03e00821 # move $1,$31
> .word 0x04110001 # bgezal $0,.+8
> .word 0x00000000 # nop
> .word 0x8fe30014 # lw $3,20($31)
> .word 0x8fe20018 # lw $2,24($31)
> .word 0x0060c821 # move $25,$3 (abicalls)
> .word 0x00600008 # jr $3
> .word 0x0020f821 # move $31,$1
> .word 0x00000000 # <function address>
> .word 0x00000000 # <static chain value>
This is the trampoline. Its purpose is to load the static chain
pointer into $2 and then jump to the function. In your example, the
static chain pointer is, conceptually, the address of the local
variable i in the stack frame of main(). The function g() needs that
address so that it can access the variable. When you take the address
of g(), you get a pointer to a copy of the trampoline with the values
of the static chain pointer and the real function address filled in.
That way a call through the function pointer will pass the correct
static chain pointer to g(). This has to be done dynamically because
the address of i is not a fixed number at compile time.
> lui $2,%hi($LTRAMP0)
> move $3,$16
> addiu $2,$2,%lo($LTRAMP0)
> li $5,40 # 0x28
> move $4,$2
> jal memcpy
> nop
Here the compiler copies the trampoline template onto the stack
(except it is passing parameters in $3/$4/$5, which is not MIPS
standard, but I assume that is your doing somehow).
> lui $2,%hi(g.1238)
> addiu $2,$2,%lo(g.1238)
> sw $2,32($16)
Here the compiler fills in the function address, but it apparently
fails to fill in the static chain pointer--not sure what's up with
that, but I again attribute it to your non-standard compiler.
> move $3,$16
> li $4,40 # 0x28
> li $5,3 # 0x3
> jal _flush_cache
> nop
Here the compiler tells the OS that it is using self-modifying code:
the writes have gone out through the data cache and may not be visible
in the instruction cache, depending on the CPU architecture.
Hope this helps.
Ian