aboutsummaryrefslogtreecommitdiff
path: root/gdb/nat/loongarch-hw-point.c
diff options
context:
space:
mode:
authorHui Li <lihui@loongson.cn>2024-06-11 19:21:26 +0800
committerTiezhu Yang <yangtiezhu@loongson.cn>2024-06-25 05:50:29 +0800
commit6ced1278fc0078022f73d623702cf4582750f783 (patch)
treed6cf7eb15ee11a375fac83a29e1ddc20c845577a /gdb/nat/loongarch-hw-point.c
parentc1cdee0e2c1715718c1e6224038096142ccabe40 (diff)
downloadgdb-6ced1278fc0078022f73d623702cf4582750f783.zip
gdb-6ced1278fc0078022f73d623702cf4582750f783.tar.gz
gdb-6ced1278fc0078022f73d623702cf4582750f783.tar.bz2
gdb: LoongArch: Add support for hardware breakpoint
LoongArch defines hardware watchpoint functions for fetch operations. After the software configures the watchpoints for fetch, the processor hardware will monitor the access addresses of the fetch operations and trigger a watchpoint exception when the watchpoint setting conditions are met. Hardware watchpoints for fetch operations is used to implement hardware breakpoint function on LoongArch. Refer to the following document for hardware breakpoint. https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#control-and-status-registers-related-to-watchpoints A simple test is as follows: lihui@bogon:~$ cat test.c #include <stdio.h> int a = 0; int main() { printf("start test\n"); a = 1; printf("a = %d\n", a); printf("end test\n"); return 0; } lihui@bogon:~$ gcc -g test.c -o test without this patch: lihui@bogon:~$ gdb test ... (gdb) start ... Temporary breakpoint 1, main () at test.c:5 5 printf("start test\n"); (gdb) hbreak 8 No hardware breakpoint support in the target. with this patch: lihui@bogon:~$ gdb test ... (gdb) start ... Temporary breakpoint 1, main () at test.c:5 5 printf("start test\n"); (gdb) hbreak 8 Hardware assisted breakpoint 2 at 0x1200006ec: file test.c, line 8. (gdb) c Continuing. start test a = 1 Breakpoint 2, main () at test.c:8 8 printf("end test\n"); (gdb) c Continuing. end test [Inferior 1 (process 25378) exited normally] Signed-off-by: Hui Li <lihui@loongson.cn> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Diffstat (limited to 'gdb/nat/loongarch-hw-point.c')
-rw-r--r--gdb/nat/loongarch-hw-point.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/gdb/nat/loongarch-hw-point.c b/gdb/nat/loongarch-hw-point.c
index 44af61a..089f3bd 100644
--- a/gdb/nat/loongarch-hw-point.c
+++ b/gdb/nat/loongarch-hw-point.c
@@ -27,6 +27,7 @@
/* Number of hardware breakpoints/watchpoints the target supports.
They are initialized with values obtained via ptrace. */
+int loongarch_num_bp_regs;
int loongarch_num_wp_regs;
/* Given the hardware breakpoint or watchpoint type TYPE and its
@@ -112,7 +113,10 @@ loongarch_dr_state_insert_one_point (ptid_t ptid,
}
else
{
- return -1;
+ num_regs = loongarch_num_bp_regs;
+ dr_addr_p = state->dr_addr_bp;
+ dr_ctrl_p = state->dr_ctrl_bp;
+ dr_ref_count = state->dr_ref_count_bp;
}
ctrl = loongarch_point_encode_ctrl_reg (type, len);
@@ -184,7 +188,10 @@ loongarch_dr_state_remove_one_point (ptid_t ptid,
}
else
{
- return -1;
+ num_regs = loongarch_num_bp_regs;
+ dr_addr_p = state->dr_addr_bp;
+ dr_ctrl_p = state->dr_ctrl_bp;
+ dr_ref_count = state->dr_ref_count_bp;
}
ctrl = loongarch_point_encode_ctrl_reg (type, len);
@@ -215,6 +222,20 @@ loongarch_dr_state_remove_one_point (ptid_t ptid,
}
int
+loongarch_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr,
+ int len, int is_insert, ptid_t ptid,
+ struct loongarch_debug_reg_state *state)
+{
+ if (is_insert)
+ return loongarch_dr_state_insert_one_point (ptid, state, type, addr,
+ len, -1);
+ else
+ return loongarch_dr_state_remove_one_point (ptid, state, type, addr,
+ len, -1);
+}
+
+
+int
loongarch_handle_watchpoint (enum target_hw_bp_type type, CORE_ADDR addr,
int len, int is_insert, ptid_t ptid,
struct loongarch_debug_reg_state *state)
@@ -234,12 +255,12 @@ bool
loongarch_any_set_debug_regs_state (loongarch_debug_reg_state *state,
bool watchpoint)
{
- int count = watchpoint ? loongarch_num_wp_regs : 0;
+ int count = watchpoint ? loongarch_num_wp_regs : loongarch_num_bp_regs;
if (count == 0)
return false;
- const CORE_ADDR *addr = watchpoint ? state->dr_addr_wp : 0;
- const unsigned int *ctrl = watchpoint ? state->dr_ctrl_wp : 0;
+ const CORE_ADDR *addr = watchpoint ? state->dr_addr_wp : state->dr_addr_bp;
+ const unsigned int *ctrl = watchpoint ? state->dr_ctrl_wp : state->dr_ctrl_bp;
for (int i = 0; i < count; i++)
if (addr[i] != 0 || ctrl[i] != 0)
@@ -268,6 +289,12 @@ loongarch_show_debug_reg_state (struct loongarch_debug_reg_state *state,
: "??unknown??"))));
debug_printf (":\n");
+ debug_printf ("\tBREAKPOINTs:\n");
+ for (i = 0; i < loongarch_num_bp_regs; i++)
+ debug_printf ("\tBP%d: addr=%s, ctrl=0x%08x, ref.count=%d\n",
+ i, core_addr_to_string_nz (state->dr_addr_bp[i]),
+ state->dr_ctrl_bp[i], state->dr_ref_count_bp[i]);
+
debug_printf ("\tWATCHPOINTs:\n");
for (i = 0; i < loongarch_num_wp_regs; i++)
debug_printf ("\tWP%d: addr=%s, ctrl=0x%08x, ref.count=%d\n",