diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-10-27 15:31:53 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-11-02 09:07:05 +0000 |
commit | e1f57067b162cba9f39e087726c7a2f2cfaae96f (patch) | |
tree | 713c49148ef348592b6b7999c64b318567e5db58 /gdb/python | |
parent | 8807d3127cb4b9199a3d5a16aa2851cc28e9826c (diff) | |
download | binutils-e1f57067b162cba9f39e087726c7a2f2cfaae96f.zip binutils-e1f57067b162cba9f39e087726c7a2f2cfaae96f.tar.gz binutils-e1f57067b162cba9f39e087726c7a2f2cfaae96f.tar.bz2 |
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.
Diffstat (limited to 'gdb/python')
0 files changed, 0 insertions, 0 deletions