aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorJim Wilson <jimw@sifive.com>2018-11-01 17:25:15 -0700
committerJim Wilson <jimw@sifive.com>2018-11-01 17:25:15 -0700
commit3ba2ee38a648b7f52e77700325b26137f6332fe2 (patch)
treefb04918d8e7684a2fece7df6366ad238c7d0527b /gdb
parentc175004a5380168cf16b489d58c9402ff3d75039 (diff)
downloadbinutils-3ba2ee38a648b7f52e77700325b26137f6332fe2.zip
binutils-3ba2ee38a648b7f52e77700325b26137f6332fe2.tar.gz
binutils-3ba2ee38a648b7f52e77700325b26137f6332fe2.tar.bz2
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.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/riscv-tdep.c32
2 files changed, 30 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a3271cc..8e40537 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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>
* ada-lang.c (ada_watch_location_expression): New function.
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 4b5f38a..db372e2 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -415,18 +415,34 @@ riscv_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
if (use_compressed_breakpoints == AUTO_BOOLEAN_AUTO)
{
+ bool unaligned_p = false;
gdb_byte buf[1];
- /* Read the opcode byte to determine the instruction length. */
- read_code (*pcptr, buf, 1);
+ /* Some targets don't support unaligned reads. The address can only
+ 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)
- fprintf_unfiltered
- (gdb_stdlog,
- "Using %s for breakpoint at %s (instruction length %d)\n",
- riscv_insn_length (buf[0]) == 2 ? "C.EBREAK" : "EBREAK",
- paddress (gdbarch, *pcptr), riscv_insn_length (buf[0]));
- if (riscv_insn_length (buf[0]) == 2)
+ {
+ const char *bp = (unaligned_p || riscv_insn_length (buf[0]) == 2
+ ? "C.EBREAK" : "EBREAK");
+
+ fprintf_unfiltered (gdb_stdlog, "Using %s for breakpoint at %s ",
+ 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;
else
return 4;