mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 04:00:07 +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>
|
2020-11-01 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* dbxread.c (dbx_end_psymtab): Update.
|
* 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. */
|
/* We can now calculate the frame base address. */
|
||||||
cache->frame_base
|
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);
|
+ cache->frame_base_offset);
|
||||||
if (riscv_debug_unwinder)
|
if (riscv_debug_unwinder)
|
||||||
fprintf_unfiltered (gdb_stdlog, "Frame base is %s ($%s + 0x%x)\n",
|
fprintf_unfiltered (gdb_stdlog, "Frame base is %s ($%s + 0x%x)\n",
|
||||||
|
Reference in New Issue
Block a user