From: Jim Wilson Date: Fri, 2 Nov 2018 00:25:15 +0000 (-0700) Subject: RISC-V: Don't allow unaligned breakpoints. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3ba2ee38a648b7f52e77700325b26137f6332fe2;p=binutils-gdb.git 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a3271cccc05..8e40537aaf0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2018-11-01 Jim Wilson + + * 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 * ada-lang.c (ada_watch_location_expression): New function. diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 4b5f38a8779..db372e21632 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;