This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Trampoline implementation for MIPS


"kernel coder" <lhrkernelcoder@gmail.com> 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]