Skip to content
This repository was archived by the owner on Aug 17, 2022. It is now read-only.

Commit 9e35c5d

Browse files
timsifivepalmer-dabbelt
authored andcommitted
Use cbreak software breakpoint if supported.
This makes debugging code that uses the compressed ISA work.
1 parent 64d6efe commit 9e35c5d

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

gdb/riscv-tdep.c

+31-22
Original file line numberDiff line numberDiff line change
@@ -158,35 +158,44 @@ static const struct register_alias riscv_register_aliases[] =
158158
#undef DECLARE_CSR
159159
};
160160

161-
static const gdb_byte *
162-
riscv_breakpoint_from_pc (struct gdbarch *gdbarch,
163-
CORE_ADDR *bp_addr,
164-
int *bp_size)
165-
{
166-
/* TODO: Support C.EBREAK for compressed (16-bit) insns. */
167-
/* TODO: Support NOPs for >=6 byte insns. */
168-
static const gdb_byte sbreak_insn[] = { 0x73, 0x00, 0x10, 0x00, };
169-
170-
*bp_size = 4;
171-
172-
return sbreak_insn;
173-
}
174-
175161
static int
176162
riscv_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
177163
{
178-
/* TODO: Support C.EBREAK for compressed (16-bit) insns. */
179-
/* TODO: Support NOPs for >=6 byte insns. */
180-
return 4;
164+
if (gdbarch_tdep (gdbarch)->supports_compressed_isa == SUP_UNKNOWN)
165+
{
166+
/* TODO: Because we try to read misa, it is not possible to set a
167+
breakpoint before connecting to a live target. A suggested workaround is
168+
to look at the ELF file in this case. */
169+
struct frame_info *frame = get_current_frame ();
170+
uint32_t misa = get_frame_register_unsigned (frame, RISCV_CSR_MISA_REGNUM);
171+
if (misa & (1<<2))
172+
gdbarch_tdep (gdbarch)->supports_compressed_isa = SUP_YES;
173+
else
174+
gdbarch_tdep (gdbarch)->supports_compressed_isa = SUP_NO;
175+
}
176+
177+
if (gdbarch_tdep (gdbarch)->supports_compressed_isa == SUP_YES)
178+
return 2;
179+
else
180+
return 4;
181181
}
182182

183183
static const gdb_byte *
184184
riscv_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
185185
{
186-
/* TODO: Support C.EBREAK for compressed (16-bit) insns. */
187-
/* TODO: Support NOPs for >=6 byte insns. */
188-
gdb_assert(kind == 4);
189-
return riscv_breakpoint_from_pc(gdbarch, NULL, size);
186+
static const gdb_byte ebreak[] = { 0x73, 0x00, 0x10, 0x00, };
187+
static const gdb_byte c_ebreak[] = { 0x02, 0x90 };
188+
189+
*size = kind;
190+
switch (kind)
191+
{
192+
case 2:
193+
return c_ebreak;
194+
case 4:
195+
return ebreak;
196+
default:
197+
gdb_assert(0);
198+
}
190199
}
191200

192201
static struct value *
@@ -1219,6 +1228,7 @@ riscv_gdbarch_init (struct gdbarch_info info,
12191228
gdbarch = gdbarch_alloc (&info, tdep);
12201229

12211230
tdep->riscv_abi = abi;
1231+
tdep->supports_compressed_isa = SUP_UNKNOWN;
12221232

12231233
/* Target data types. */
12241234
set_gdbarch_short_bit (gdbarch, 16);
@@ -1232,7 +1242,6 @@ riscv_gdbarch_init (struct gdbarch_info info,
12321242

12331243
/* Information about the target architecture. */
12341244
set_gdbarch_return_value (gdbarch, riscv_return_value);
1235-
set_gdbarch_breakpoint_from_pc (gdbarch, riscv_breakpoint_from_pc);
12361245
set_gdbarch_breakpoint_kind_from_pc (gdbarch, riscv_breakpoint_kind_from_pc);
12371246
set_gdbarch_sw_breakpoint_from_kind (gdbarch, riscv_sw_breakpoint_from_kind);
12381247
set_gdbarch_print_insn (gdbarch, print_insn_riscv);

gdb/riscv-tdep.h

+3
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,13 @@ enum {
6969

7070
#define RISCV_LAST_REGNUM (RISCV_NUM_REGS - 1)
7171

72+
typedef enum { SUP_UNKNOWN, SUP_YES, SUP_NO } supported_t;
73+
7274
/* RISC-V specific per-architecture information. */
7375
struct gdbarch_tdep
7476
{
7577
int riscv_abi;
78+
supported_t supports_compressed_isa;
7679
};
7780

7881
static inline int

0 commit comments

Comments
 (0)