18#include "gdbsupport/common-defs.h"
19#include "gdbsupport/break-common.h"
20#include "gdbsupport/common-regcache.h"
27#define kernel_supports_any_contiguous_range true
45 for (retval = 0; mask && (mask & 1) == 0; ++retval)
66 for (retval = 0; (mask & 1) != 0; ++retval)
70 error (_(
"Unexpected hardware watchpoint length register value 0x%x"),
83 unsigned int ctrl, ttype;
104 perror_with_name (_(
"Unrecognized breakpoint/watchpoint type"));
110 ctrl |= ((1 << len) - 1) << (5 + offset);
112 ctrl |= (2 << 1) | 1;
134 unsigned int alignment = 0;
140 struct regcache *regcache
141 = get_thread_regcache_for_ptid (ptid);
146 if (regcache_register_size (regcache, 0) == 8)
152 if (addr & (alignment - 1))
156 && len != 8 && len != 4 && len != 2 && len != 1)
158 && (len < 1 || len > 8)))
208 int *aligned_offset_p,
int *aligned_len_p,
209 CORE_ADDR *next_addr_p,
int *next_len_p,
210 CORE_ADDR *next_addr_orig_p)
213 unsigned int offset, aligned_offset;
214 CORE_ADDR aligned_addr;
219 gdb_assert (alignment == max_wp_len);
226 offset = addr & (alignment - 1);
227 aligned_addr = addr - offset;
231 gdb_assert (offset >= 0 && offset < alignment);
232 gdb_assert (aligned_addr >= 0 && aligned_addr <= addr);
233 gdb_assert (offset + len > 0);
235 if (offset + len >= max_wp_len)
241 len -= (max_wp_len - offset);
242 addr += (max_wp_len - offset);
243 gdb_assert ((addr & (alignment - 1)) == 0);
249 static const unsigned char
251 { 1, 2, 4, 4, 8, 8, 8, 8 };
254 ? len : aligned_len_array[offset + len - 1]);
260 *aligned_addr_p = aligned_addr;
261 if (aligned_offset_p)
262 *aligned_offset_p = aligned_offset;
264 *aligned_len_p = aligned_len;
269 if (next_addr_orig_p)
270 *next_addr_orig_p = align_down (*next_addr_orig_p + alignment, alignment);
279 enum target_hw_bp_type type,
280 CORE_ADDR addr,
int offset,
int len,
283 int i, idx, num_regs, is_watchpoint;
284 unsigned int ctrl, *dr_ctrl_p, *dr_ref_count;
285 CORE_ADDR *dr_addr_p, *dr_addr_orig_p;
288 is_watchpoint = (type != hw_execute);
302 dr_addr_orig_p =
nullptr;
311 for (i = 0; i < num_regs; ++i)
313 if ((dr_ctrl_p[i] & 1) == 0)
315 gdb_assert (dr_ref_count[i] == 0);
319 else if (dr_addr_p[i] == addr
320 && (dr_addr_orig_p ==
nullptr || dr_addr_orig_p[i] == addr_orig)
321 && dr_ctrl_p[i] == ctrl)
323 gdb_assert (dr_ref_count[i] != 0);
334 if ((dr_ctrl_p[idx] & 1) == 0)
337 dr_addr_p[idx] = addr;
338 if (dr_addr_orig_p !=
nullptr)
339 dr_addr_orig_p[idx] = addr_orig;
340 dr_ctrl_p[idx] = ctrl;
341 dr_ref_count[idx] = 1;
360 enum target_hw_bp_type type,
361 CORE_ADDR addr,
int offset,
int len,
364 int i, num_regs, is_watchpoint;
365 unsigned int ctrl, *dr_ctrl_p, *dr_ref_count;
366 CORE_ADDR *dr_addr_p, *dr_addr_orig_p;
369 is_watchpoint = (type != hw_execute);
382 dr_addr_orig_p =
nullptr;
390 for (i = 0; i < num_regs; ++i)
391 if (dr_addr_p[i] == addr
392 && (dr_addr_orig_p ==
nullptr || dr_addr_orig_p[i] == addr_orig)
393 && dr_ctrl_p[i] == ctrl)
395 gdb_assert (dr_ref_count[i] != 0);
404 if (--dr_ref_count[i] == 0)
409 if (dr_addr_orig_p !=
nullptr)
410 dr_addr_orig_p[i] = 0;
421 int len,
int is_insert, ptid_t ptid,
450 CORE_ADDR addr,
int len,
int is_insert,
471 CORE_ADDR addr,
int len,
int is_insert,
475 CORE_ADDR addr_orig = addr;
479 CORE_ADDR aligned_addr;
480 int aligned_offset, aligned_len, ret;
481 CORE_ADDR addr_orig_next = addr_orig;
484 &aligned_len, &addr, &len, &addr_orig_next);
488 aligned_addr, aligned_offset,
489 aligned_len, addr_orig);
492 aligned_addr, aligned_offset,
493 aligned_len, addr_orig);
496 debug_printf (
"handle_unaligned_watchpoint: is_insert: %d\n"
498 "aligned_addr: %s, aligned_len: %d\n"
502 "next_addr: %s, next_len: %d\n"
504 "addr_orig_next: %s\n",
505 is_insert, core_addr_to_string_nz (aligned_addr),
506 aligned_len, core_addr_to_string_nz (addr_orig),
507 core_addr_to_string_nz (addr), len,
508 core_addr_to_string_nz (addr_orig_next));
510 addr_orig = addr_orig_next;
521 int len,
int is_insert, ptid_t ptid,
545 for (
int i = 0; i < count; i++)
546 if (addr[i] != 0 || ctrl[i] != 0)
556 const char *func, CORE_ADDR addr,
557 int len,
enum target_hw_bp_type type)
561 debug_printf (
"%s", func);
563 debug_printf (
" (addr=0x%08lx, len=%d, type=%s)",
564 (
unsigned long) addr, len,
565 type == hw_write ?
"hw-write-watchpoint"
566 : (type == hw_read ?
"hw-read-watchpoint"
567 : (type == hw_access ?
"hw-access-watchpoint"
568 : (type == hw_execute ?
"hw-breakpoint"
570 debug_printf (
":\n");
572 debug_printf (
"\tBREAKPOINTs:\n");
574 debug_printf (
"\tBP%d: addr=%s, ctrl=0x%08x, ref.count=%d\n",
575 i, core_addr_to_string_nz (state->
dr_addr_bp[i]),
578 debug_printf (
"\tWATCHPOINTs:\n");
580 debug_printf (
"\tWP%d: addr=%s (orig=%s), ctrl=0x%08x, ref.count=%d\n",
581 i, core_addr_to_string_nz (state->
dr_addr_wp[i]),
592 CORE_ADDR aligned_addr;
void aarch64_show_debug_reg_state(struct aarch64_debug_reg_state *state, const char *func, CORE_ADDR addr, int len, enum target_hw_bp_type type)
#define kernel_supports_any_contiguous_range
static int aarch64_handle_aligned_watchpoint(enum target_hw_bp_type type, CORE_ADDR addr, int len, int is_insert, ptid_t ptid, struct aarch64_debug_reg_state *state)
int aarch64_region_ok_for_watchpoint(CORE_ADDR addr, int len)
unsigned int aarch64_watchpoint_length(unsigned int ctrl)
int aarch64_handle_breakpoint(enum target_hw_bp_type type, CORE_ADDR addr, int len, int is_insert, ptid_t ptid, struct aarch64_debug_reg_state *state)
static int aarch64_dr_state_insert_one_point(ptid_t ptid, struct aarch64_debug_reg_state *state, enum target_hw_bp_type type, CORE_ADDR addr, int offset, int len, CORE_ADDR addr_orig)
int aarch64_handle_watchpoint(enum target_hw_bp_type type, CORE_ADDR addr, int len, int is_insert, ptid_t ptid, struct aarch64_debug_reg_state *state)
bool aarch64_any_set_debug_regs_state(aarch64_debug_reg_state *state, bool watchpoint)
static void aarch64_align_watchpoint(CORE_ADDR addr, int len, CORE_ADDR *aligned_addr_p, int *aligned_offset_p, int *aligned_len_p, CORE_ADDR *next_addr_p, int *next_len_p, CORE_ADDR *next_addr_orig_p)
static unsigned int aarch64_point_encode_ctrl_reg(enum target_hw_bp_type type, int offset, int len)
static int aarch64_point_is_aligned(ptid_t ptid, int is_watchpoint, CORE_ADDR addr, int len)
unsigned int aarch64_watchpoint_offset(unsigned int ctrl)
static int aarch64_handle_unaligned_watchpoint(enum target_hw_bp_type type, CORE_ADDR addr, int len, int is_insert, ptid_t ptid, struct aarch64_debug_reg_state *state)
static int aarch64_dr_state_remove_one_point(ptid_t ptid, struct aarch64_debug_reg_state *state, enum target_hw_bp_type type, CORE_ADDR addr, int offset, int len, CORE_ADDR addr_orig)
#define AARCH64_HWP_MAX_LEN_PER_REG
#define DR_CONTROL_MASK(ctrl)
#define AARCH64_HWP_ALIGNMENT
void aarch64_notify_debug_reg_change(ptid_t ptid, int is_watchpoint, unsigned int idx)
#define AARCH64_HBP_ALIGNMENT
unsigned int dr_ref_count_wp[AARCH64_HWP_MAX_NUM]
CORE_ADDR dr_addr_bp[AARCH64_HBP_MAX_NUM]
unsigned int dr_ctrl_wp[AARCH64_HWP_MAX_NUM]
unsigned int dr_ref_count_bp[AARCH64_HBP_MAX_NUM]
CORE_ADDR dr_addr_wp[AARCH64_HWP_MAX_NUM]
unsigned int dr_ctrl_bp[AARCH64_HBP_MAX_NUM]
CORE_ADDR dr_addr_orig_wp[AARCH64_HWP_MAX_NUM]