"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

Reply via email to