Why do LLVM and GCC differ in the position of the frame pointer for ARM?

I have been looking at the function prologue code for ARM which uses frame
pointers and comparing the code that LLVM generates with that produced by
GCC. In the examples below the frame pointer register is R11.

I used this simple C code (frame.c):

    extern int func2(int i);
    int func(int i) {
  return func2(i);
    }

If I compile (clang -c -target armv7-arm-none-eabi frame.c) this source LLVM
produced the following code in the function prologue to set up the frame
pointer:

    PUSH {r11,lr}
    MOV r11,sp

However compiling the same source with GCC (arm-none-eabi-gcc -c -O0
--no-omit-frame-pointer frame.c) produced the following code:

    PUSH {r11,lr}
    ADD r11,sp,#4

So the LLVM code results in the frame pointer pointing to just after the
pushed R11 register on the stack, while the GCC code results in the frame
pointer pointing to just after the pushed LR register on the stack.

So my question is whether there a reason for this difference in where the
frame pointer points between code generated by LLVM and GCC, or have I
missed something obvious?

This difference will make it difficult, without additional information, for
a generic stack walker to use the frame pointer to walk up the stack that
can handle both GCC and LLVM compiled code.

Keith

Hi Keith,

I've come across this problem when comparing GCC and LLVM generated code,
but I hadn't thought about the implications on a stack walker. I wouldn't
trust prologue code to tell me that, as you may not have it at all, or have
different functions compiled by different compilers in the same object, so
I get your point on the difficulty on producing an efficient walker.

I don't know what's the source of this preference in either LLVM or GCC,
but I'd have a look in what LLDB does, as it probably had the same problem
to solve.

cheers,
--renato

Hi Keith,

So my question is whether there a reason for this difference in where the
frame pointer points between code generated by LLVM and GCC, or have I
missed something obvious?

Looks like a bug somewhere to me. Have you checked that the GCC folks
consider it a feature, because their choice is truly ridiculous:
aarch64 (in the AAPCS!), iOS and gnueabi all make fp point to the
first of the two parts of the frame record.

Cheers.

Tim.