RISC-V: Don't allow unaligned breakpoints.
Some hardware doesn't support unaligned accesses, and a bare metal target may not have an unaligned access trap handler. So if the PC is 2-byte aligned, then use a 2-byte breakpoint to avoid unaligned accesses. Tested on native RV64GC Linux with gdb testsuite and cross on spike simulator and openocd with riscv-tests/debug. gdb/ * riscv-tdep.c (riscv_breakpoint_kind_from_pc): New local unaligned_p. Set if pcptr if unaligned. Return 2 if unaligned_p true. Update debugging messages.
This commit is contained in:
parent
c175004a53
commit
3ba2ee38a6
|
@ -1,3 +1,9 @@
|
||||||
|
2018-11-01 Jim Wilson <jimw@sifive.com>
|
||||||
|
|
||||||
|
* riscv-tdep.c (riscv_breakpoint_kind_from_pc): New local unaligned_p.
|
||||||
|
Set if pcptr if unaligned. Return 2 if unaligned_p true. Update
|
||||||
|
debugging messages.
|
||||||
|
|
||||||
2018-11-01 Joel Brobecker <brobecker@adacore.com>
|
2018-11-01 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
* ada-lang.c (ada_watch_location_expression): New function.
|
* ada-lang.c (ada_watch_location_expression): New function.
|
||||||
|
|
|
@ -415,18 +415,34 @@ riscv_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
|
||||||
{
|
{
|
||||||
if (use_compressed_breakpoints == AUTO_BOOLEAN_AUTO)
|
if (use_compressed_breakpoints == AUTO_BOOLEAN_AUTO)
|
||||||
{
|
{
|
||||||
|
bool unaligned_p = false;
|
||||||
gdb_byte buf[1];
|
gdb_byte buf[1];
|
||||||
|
|
||||||
/* Read the opcode byte to determine the instruction length. */
|
/* Some targets don't support unaligned reads. The address can only
|
||||||
read_code (*pcptr, buf, 1);
|
be unaligned if the C extension is supported. So it is safe to
|
||||||
|
use a compressed breakpoint in this case. */
|
||||||
|
if (*pcptr & 0x2)
|
||||||
|
unaligned_p = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Read the opcode byte to determine the instruction length. */
|
||||||
|
read_code (*pcptr, buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (riscv_debug_breakpoints)
|
if (riscv_debug_breakpoints)
|
||||||
fprintf_unfiltered
|
{
|
||||||
(gdb_stdlog,
|
const char *bp = (unaligned_p || riscv_insn_length (buf[0]) == 2
|
||||||
"Using %s for breakpoint at %s (instruction length %d)\n",
|
? "C.EBREAK" : "EBREAK");
|
||||||
riscv_insn_length (buf[0]) == 2 ? "C.EBREAK" : "EBREAK",
|
|
||||||
paddress (gdbarch, *pcptr), riscv_insn_length (buf[0]));
|
fprintf_unfiltered (gdb_stdlog, "Using %s for breakpoint at %s ",
|
||||||
if (riscv_insn_length (buf[0]) == 2)
|
bp, paddress (gdbarch, *pcptr));
|
||||||
|
if (unaligned_p)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "(unaligned address)\n");
|
||||||
|
else
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "(instruction length %d)\n",
|
||||||
|
riscv_insn_length (buf[0]));
|
||||||
|
}
|
||||||
|
if (unaligned_p || riscv_insn_length (buf[0]) == 2)
|
||||||
return 2;
|
return 2;
|
||||||
else
|
else
|
||||||
return 4;
|
return 4;
|
||||||
|
|
Loading…
Reference in New Issue