Skip to content

Commit d81b8cc

Browse files
committed
riscv/crt0: Add .cfi_* annotations to allow GDB to unwind out of _trap
We have to tell GDB about the correct "return" address (mepc) as well as the saved stack pointer to continue unwinding beyond the current frame. With this change and a __builtin_trap added to fclose(), I get the following mostly-sensible (unwinding fails one frame up) backtrace when breaking at the end of _trap: ``` $ gdb -q test/test-fopen '-ex=b crt0.c:169' '-ex=target remote :1234' -ex=c -ex=bt Reading symbols from test/test-fopen... Breakpoint 1 at 0x800001c0: file ../../picolibc/picocrt/machine/riscv/crt0.c, line 169. Remote debugging using :1234 0x0000000000001000 in ?? () Continuing. Breakpoint 1, _trap () at ../../picolibc/picocrt/machine/riscv/crt0.c:169 169 __asm__("j _ctrap"); #0 _trap () at ../../picolibc/picocrt/machine/riscv/crt0.c:169 #1 0x00000000800013d0 in fclose (f=0x0) at ../../picolibc/newlib/libc/tinystdio/fclose.c:39 #2 0x0000000000000000 in ?? () Backtrace stopped: frame did not save the PC ```
1 parent 7fbc428 commit d81b8cc

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

picocrt/machine/riscv/crt0.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ _trap(void)
108108
".option pop");
109109

110110
/* Make space for saved registers */
111-
__asm__("addi sp,sp,%0" :: "i" (-sizeof(struct fault)));
111+
__asm__("addi sp, sp, %0\n"
112+
".cfi_def_cfa sp, 0\n"
113+
:: "i"(-sizeof(struct fault)));
112114

113115
/* Save registers on stack */
114116
#define SAVE_REG(num) \
@@ -130,11 +132,18 @@ _trap(void)
130132
__asm__("csrr t0, "PASTE(name));\
131133
__asm__(SD" t0, %0(sp)" :: "i" (offsetof(struct fault, name)))
132134

133-
/* Save the trapping frame's stack pointer stashed in mscratch. */
134-
__asm__("csrrw t0, mscratch, zero\n"
135+
/*
136+
* Save the trapping frame's stack pointer that was stashed in mscratch
137+
* and tell the unwinder where we can find the return address (mepc).
138+
*/
139+
__asm__("csrr ra, mepc\n"
140+
SD " ra, %0(sp)\n"
141+
".cfi_offset ra, %0\n"
142+
"csrrw t0, mscratch, zero\n"
135143
SD " t0, %1(sp)\n"
136-
:: "i"(offsetof(struct fault, r[2])));
137-
SAVE_CSR(mepc);
144+
".cfi_offset sp, %1\n"
145+
:: "i"(offsetof(struct fault, mepc)),
146+
"i"(offsetof(struct fault, r[2])));
138147
SAVE_CSR(mcause);
139148
SAVE_CSR(mtval);
140149

0 commit comments

Comments
 (0)