/* Native-dependent code for x86 (i386 and x86-64).
- Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Copyright (C) 2001-2019 Free Software Foundation, Inc.
This file is part of GDB.
The functions below implement debug registers sharing by reference
counts, and allow to watch regions up to 16 bytes long. */
-/* Whether or not to print the mirrored debug registers. */
-int debug_hw_points;
-
/* Low-level function vector. */
struct x86_dr_low_type x86_dr_low;
static struct x86_process_info *
x86_add_process (pid_t pid)
{
- struct x86_process_info *proc;
+ struct x86_process_info *proc = XCNEW (struct x86_process_info);
- proc = xcalloc (1, sizeof (*proc));
proc->pid = pid;
-
proc->next = x86_process_list;
x86_process_list = proc;
return &x86_process_info_get (pid)->state;
}
-/* See declaration in i386-nat.h. */
+/* See declaration in x86-nat.h. */
void
x86_forget_process (pid_t pid)
x86_cleanup_dregs (void)
{
/* Starting from scratch has the same effect. */
- x86_forget_process (ptid_get_pid (inferior_ptid));
+ x86_forget_process (inferior_ptid.pid ());
}
/* Insert a watchpoint to watch a memory region which starts at
address ADDR and whose length is LEN bytes. Watch memory accesses
of the type TYPE. Return 0 on success, -1 on failure. */
-static int
-x86_insert_watchpoint (struct target_ops *self,
- CORE_ADDR addr, int len, int type,
- struct expression *cond)
+int
+x86_insert_watchpoint (CORE_ADDR addr, int len,
+ enum target_hw_bp_type type, struct expression *cond)
{
struct x86_debug_reg_state *state
- = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
+ = x86_debug_reg_state (inferior_ptid.pid ());
return x86_dr_insert_watchpoint (state, type, addr, len);
}
/* Remove a watchpoint that watched the memory region which starts at
address ADDR, whose length is LEN bytes, and for accesses of the
type TYPE. Return 0 on success, -1 on failure. */
-static int
-x86_remove_watchpoint (struct target_ops *self,
- CORE_ADDR addr, int len, int type,
- struct expression *cond)
+int
+x86_remove_watchpoint (CORE_ADDR addr, int len,
+ enum target_hw_bp_type type, struct expression *cond)
{
struct x86_debug_reg_state *state
- = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
+ = x86_debug_reg_state (inferior_ptid.pid ());
return x86_dr_remove_watchpoint (state, type, addr, len);
}
/* Return non-zero if we can watch a memory region that starts at
address ADDR and whose length is LEN bytes. */
-static int
-x86_region_ok_for_watchpoint (struct target_ops *self,
- CORE_ADDR addr, int len)
+int
+x86_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
{
struct x86_debug_reg_state *state
- = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
+ = x86_debug_reg_state (inferior_ptid.pid ());
return x86_dr_region_ok_for_watchpoint (state, addr, len);
}
address associated with that break/watchpoint and return non-zero.
Otherwise, return zero. */
-static int
-x86_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+int
+x86_stopped_data_address (CORE_ADDR *addr_p)
{
struct x86_debug_reg_state *state
- = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
+ = x86_debug_reg_state (inferior_ptid.pid ());
return x86_dr_stopped_data_address (state, addr_p);
}
/* Return non-zero if the inferior has some watchpoint that triggered.
Otherwise return zero. */
-static int
-x86_stopped_by_watchpoint (struct target_ops *ops)
+int
+x86_stopped_by_watchpoint ()
{
struct x86_debug_reg_state *state
- = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
+ = x86_debug_reg_state (inferior_ptid.pid ());
return x86_dr_stopped_by_watchpoint (state);
}
-/* Insert a hardware-assisted breakpoint at BP_TGT->placed_address.
+/* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
Return 0 on success, EBUSY on failure. */
-static int
-x86_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
+int
+x86_insert_hw_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt)
{
struct x86_debug_reg_state *state
- = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
+ = x86_debug_reg_state (inferior_ptid.pid ());
+ bp_tgt->placed_address = bp_tgt->reqstd_address;
return x86_dr_insert_watchpoint (state, hw_execute,
bp_tgt->placed_address, 1) ? EBUSY : 0;
}
/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address.
Return 0 on success, -1 on failure. */
-static int
-x86_remove_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
+int
+x86_remove_hw_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
struct x86_debug_reg_state *state
- = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
+ = x86_debug_reg_state (inferior_ptid.pid ());
return x86_dr_remove_watchpoint (state, hw_execute,
bp_tgt->placed_address, 1);
extreme example, consider the case where all the watchpoints watch
the same address and the same region length: then we can handle a
virtually unlimited number of watchpoints, due to debug register
- sharing implemented via reference counts in i386-nat.c. */
+ sharing implemented via reference counts in x86-nat.c. */
-static int
-x86_can_use_hw_breakpoint (struct target_ops *self,
- int type, int cnt, int othertype)
+int
+x86_can_use_hw_breakpoint (enum bptype type, int cnt, int othertype)
{
return 1;
}
+/* Return non-zero if the inferior has some breakpoint that triggered.
+ Otherwise return zero. */
+
+int
+x86_stopped_by_hw_breakpoint ()
+{
+ struct x86_debug_reg_state *state
+ = x86_debug_reg_state (inferior_ptid.pid ());
+
+ return x86_dr_stopped_by_hw_breakpoint (state);
+}
+
static void
add_show_debug_regs_command (void)
{
/* A maintenance command to enable printing the internal DRi mirror
variables. */
add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
- &debug_hw_points, _("\
+ &show_debug_regs, _("\
Set whether to show variables that mirror the x86 debug registers."), _("\
Show whether to show variables that mirror the x86 debug registers."), _("\
Use \"on\" to enable, \"off\" to disable.\n\
&maintenance_show_cmdlist);
}
-/* There are only two global functions left. */
-
-void
-x86_use_watchpoints (struct target_ops *t)
-{
- /* After a watchpoint trap, the PC points to the instruction after the
- one that caused the trap. Therefore we don't need to step over it.
- But we do need to reset the status register to avoid another trap. */
- t->to_have_continuable_watchpoint = 1;
-
- t->to_can_use_hw_breakpoint = x86_can_use_hw_breakpoint;
- t->to_region_ok_for_hw_watchpoint = x86_region_ok_for_watchpoint;
- t->to_stopped_by_watchpoint = x86_stopped_by_watchpoint;
- t->to_stopped_data_address = x86_stopped_data_address;
- t->to_insert_watchpoint = x86_insert_watchpoint;
- t->to_remove_watchpoint = x86_remove_watchpoint;
- t->to_insert_hw_breakpoint = x86_insert_hw_breakpoint;
- t->to_remove_hw_breakpoint = x86_remove_hw_breakpoint;
-}
+/* See x86-nat.h. */
void
x86_set_debug_register_length (int len)