riscv-software-src / riscv-tools

RISC-V Tools (ISA Simulator and Tests)
1.14k stars 447 forks source link

Return from a procedure - GCC flag #136

Closed ChristianPalmiero closed 6 years ago

ChristianPalmiero commented 6 years ago

Hello everyone, I have a question about the RISC-V return from a procedure convention. Analysing the assembly code generated from several C programs, I observed that, in order to return from a procedure call, the return address is stored in the return address register through a load instruction that uses the stack pointer register as source address.

Here it is an example:

<main>: addi sp,sp,-48 sw ra,44(sp) sw s0,40(sp) ... ... lw ra,44(sp) lw s0,40(sp) addi sp,sp,48 ret

Is there any option to force the GCC RISC-V compiler to use the "frame pointer" register instead of the "stack pointer" register when calculating the source address of the LOAD instruction that affects the return address?

Many thanks.

palmer-dabbelt commented 6 years ago

By default we don't even have a frame pointer on RISC-V, but you can ask for one via the "fno-omit-frame-pointer" argument. That's platform-independent and IIRC should work on RISC-V. Of course, there's no guarantee as to which register GCC will choose to use as the base address of the RA load.

If you're trying to compute a backtrace then you should really be looking at the supplementary info (IIRC ".eh_info" will do it).

ChristianPalmiero commented 6 years ago

Thank you for your answer. I was referring at the "frame pointer" register as the X8/S0/FP register. Btw, I tried with the "fno-omit-frame-pointer" argument but the generated assembly code remains the same. The base address of the RA load is still the SP register content.

aswaterman commented 6 years ago

I'm not aware of any way to force this behavior.

alexfanqi commented 2 years ago

Hi, I am wondering if gcc respects -fno-omit-frame-pointer for riscv now. If it is not, I'd like to learn why it is the case. Is there any mechanism or design consideration that disallows it?

btw, on a somewhat related question, can-i-force-gcc-to-emit-ra-fp-handling-in-a-fixed-sequence. This question seems to show fp and ra are not always pushed into stack in same order. What is the recommended approach to unwind a stack in this case. Thanks in advance for any suggesions.

jim-wilson commented 2 years ago

Yes, it works. Trivial to prove by compiling a small testcase with -S.

The only supported way to do stack unwinding is to use the dwarf cfi info, aka the unwind info, which is put in the eh_frame section. The eh_frame section is effectively the same as the DWARF5 unwind info, except that there is extra alignment for old targets that don't support unaligned relocations. See the DWARF5 standard. You may also want to look at the HP libunwind project. GCC has a libbacktrace library that can use the unwind info, but historically it wasn't easy to use outside gcc, but I think that has been fixed, so you might want to try that also.

The different order of s0/ra saves is probably just instruction scheduling noise.