mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +08:00
gdb/riscv: read frame base register as unsigned in the unwinder
I noticed an issue with the RISC-V prologue scanning stack unwinder. We currently read the frame base register (either $sp or $fp) as a signed value. This means that the frame_id's stack_addr field will be a signed value. In other contexts though these registers are data pointers, and so are unsigned. There's not many places where this mismatch actually shows though, but I did find one place. Consider this GDB session: (gdb) maintenance set dwarf unwinders off (gdb) set backtrace past-main on ... (gdb) b main Breakpoint 1 at 0x20400344: file main.c, line 86. (gdb) run ... (gdb) bt #0 main () at main.c:86 #1 0x2040005c in _start () at start.S:59 Backtrace stopped: frame did not save the PC (gdb) info frame 1 Stack frame at 0x80000a1c: pc = 0x2040005c in _start (start.S:59); saved pc = <not saved> Outermost frame: frame did not save the PC caller of frame at 0x80000a1c source language asm. Arglist at 0x80000a1c, args: Locals at 0x80000a1c, Previous frame's sp is 0x80000a1c (gdb) frame address 0x80000a1c No frame at address 0x80000a1c. (gdb) frame address 0xffffffff80000a1c #1 0x2040005c in _start () at start.S:59 59 call main Notice that the 'info frame 1' reports that the frame is at '0x80000a1c', this is the unsigned frame base value, but when I try to select a frame using this address I can't. The reason is that the frame_id for frame #1 actually has the unsigned (and hence sign-extended) stack_addr value. When I use the sign extended address I can correctly select the frame. I propose changing the prologue scanning unwinder to read the frame base as unsigned. After this in the above case I can now do this: (gdb) frame address 0x80000a1c #1 0x2040005c in _start () at start.S:59 59 call main (gdb) frame address 0xffffffff80000a1c No frame at address 0xffffffff80000a1c. Which I think makes more sense. This issue causes failures in gdb.base/frame-selection.exp if you compile for RV32 with a linker script that places the stack in the correct location, which are resolved by this patch. gdb/ChangeLog: * riscv-tdep.c (riscv_frame_cache): Read the frame base register as an unsigned value.
This commit is contained in:
@ -1,3 +1,9 @@
|
||||
2020-11-02 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
Craig Blackmore <craig.blackmore@embecosm.com>
|
||||
|
||||
* riscv-tdep.c (riscv_frame_cache): Read the frame base register
|
||||
as an unsigned value.
|
||||
|
||||
2020-11-01 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* dbxread.c (dbx_end_psymtab): Update.
|
||||
|
@ -2942,7 +2942,7 @@ riscv_frame_cache (struct frame_info *this_frame, void **this_cache)
|
||||
|
||||
/* We can now calculate the frame base address. */
|
||||
cache->frame_base
|
||||
= (get_frame_register_signed (this_frame, cache->frame_base_reg)
|
||||
= (get_frame_register_unsigned (this_frame, cache->frame_base_reg)
|
||||
+ cache->frame_base_offset);
|
||||
if (riscv_debug_unwinder)
|
||||
fprintf_unfiltered (gdb_stdlog, "Frame base is %s ($%s + 0x%x)\n",
|
||||
|
Reference in New Issue
Block a user