tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] [PATCH] arm: Handle __builtin_frame_address(1) correc


From: Daniel Glöckner
Subject: Re: [Tinycc-devel] [PATCH] arm: Handle __builtin_frame_address(1) correctly
Date: Fri, 30 Nov 2012 00:43:07 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

On Thu, Nov 29, 2012 at 09:43:33PM +0400, Kirill Smelkov wrote:
> tcc first saves r0 & r1, and only then fp:
> 
>     $ ./arm-eabi-tcc -c y.c
>     $ arm-linux-gnueabi-objdump -d y.o
> 
>     00000000 <f>:
>        0:   e1a0c00d        mov     ip, sp
>        4:   e92d0003        push    {r0, r1}
>        8:   e92d5800        push    {fp, ip, lr}
>        c:   e28db00c        add     fp, sp, #12
>       10:   e1a00000        nop                     ; (mov r0, r0)
>       14:   e91ba800        ldmdb   fp, {fp, sp, pc}

I chose this stack frame format because it simplifies access to the
arguments from within tinycc. At that time I didn't think of trying to
be compatible to anything just to allow stack traces.

> gcc does not, but it will save r5,r6,etc. before fp(=r13 iirc) ...
> 
>     $ arm-linux-gnueabihf-gcc-4.7 -marm -c y.c 
>     $ arm-linux-gnueabihf-objdump  -d y.o
>     
>     00000000 <f>:
>        0:   e52db004        push    {fp}            ; (str fp, [sp, #-4]!)
>        4:   e28db000        add     fp, sp, #0
>        8:   e24dd00c        sub     sp, sp, #12
>        c:   e50b0008        str     r0, [fp, #-8]
>       10:   e50b100c        str     r1, [fp, #-12]
>       14:   e28bd000        add     sp, fp, #0
>       18:   e8bd0800        pop     {fp}
>       1c:   e12fff1e        bx      lr

You should not look at a leaf function to derive the GCC stack frame.
It is probably different from the generic stack frame because GCC
knows this function will never be part of a stack trace done by
another function of the final program.

Take a look at arch/arm/kernel/stacktrace.c inside the Linux kernel.
They assume that every function pushes {fp, sp, lr, pc} and that
fp points to the address where pc is stored. I don't know why
GCC pushes pc. I can only imagine this being done to keep the
stack aligned to 8 bytes. Or maybe it is for exception handling
or association of stack frame debug info..

>        8:   e92d0870        push    {r4, r5, r6, fp}        ; NOTE r4... go 
> before fp

>       14:   e28db00c        add     fp, sp, #12

>       5c:   e59b0000        ldr     r0, [fp]                ; BUG here!

Why is this a bug in GCC? It will load the old value of fp to r0.

> ... as probably required by arm calling convention (not looked at the spec
> yet, but it seems reasanoble, given how push is really a block str and
> that str stores register in ascending order).

I have once seen a page in MSDN describing the ARM stack frame of
Windows CE. I don't know if ARM specified how stack frames should look
like.

Best regards,

  Daniel



reply via email to

[Prev in Thread] Current Thread [Next in Thread]