Implement "to_stopped_by_hw_breakpoint" for x86 debug registers.
Report that a thread is stopped by a hardware breakpoint if a non-data watchpoint is set in DR6. This change should be a no-op since a target still needs to implement the "to_supports_stopped_by_hw_breakpoint" method before this function is used. gdb/ChangeLog: * nat/x86-dregs.c (x86_dr_stopped_by_hw_breakpoint): New function. * nat/x86-dregs.h (x86_dr_stopped_by_hw_breakpoint): New prototype. * x86-nat.c (x86_stopped_by_hw_breakpoint): New function. (x86_use_watchpoints): Set "stopped_by_hw_breakpoint" target method.
This commit is contained in:
parent
72f53f22df
commit
12279366d7
|
@ -1,3 +1,12 @@
|
|||
2018-03-04 John Baldwin <jhb@FreeBSD.org>
|
||||
|
||||
* nat/x86-dregs.c (x86_dr_stopped_by_hw_breakpoint): New function.
|
||||
* nat/x86-dregs.h (x86_dr_stopped_by_hw_breakpoint): New
|
||||
prototype.
|
||||
* x86-nat.c (x86_stopped_by_hw_breakpoint): New function.
|
||||
(x86_use_watchpoints): Set "stopped_by_hw_breakpoint" target
|
||||
method.
|
||||
|
||||
2018-03-02 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
* common/gdb_vecs.c (free_char_ptr_vec): Remove.
|
||||
|
|
|
@ -649,3 +649,48 @@ x86_dr_stopped_by_watchpoint (struct x86_debug_reg_state *state)
|
|||
CORE_ADDR addr = 0;
|
||||
return x86_dr_stopped_data_address (state, &addr);
|
||||
}
|
||||
|
||||
/* Return non-zero if the inferior has some hardware breakpoint that
|
||||
triggered. Otherwise return zero. */
|
||||
|
||||
int
|
||||
x86_dr_stopped_by_hw_breakpoint (struct x86_debug_reg_state *state)
|
||||
{
|
||||
CORE_ADDR addr = 0;
|
||||
int i;
|
||||
int rc = 0;
|
||||
/* The current thread's DR_STATUS. We always need to read this to
|
||||
check whether some watchpoint caused the trap. */
|
||||
unsigned status;
|
||||
/* We need DR_CONTROL as well, but only iff DR_STATUS indicates a
|
||||
breakpoint trap. Only fetch it when necessary, to avoid an
|
||||
unnecessary extra syscall when no watchpoint triggered. */
|
||||
int control_p = 0;
|
||||
unsigned control = 0;
|
||||
|
||||
/* As above, always read the current thread's debug registers rather
|
||||
than trusting dr_mirror. */
|
||||
status = x86_dr_low_get_status ();
|
||||
|
||||
ALL_DEBUG_ADDRESS_REGISTERS (i)
|
||||
{
|
||||
if (!X86_DR_WATCH_HIT (status, i))
|
||||
continue;
|
||||
|
||||
if (!control_p)
|
||||
{
|
||||
control = x86_dr_low_get_control ();
|
||||
control_p = 1;
|
||||
}
|
||||
|
||||
if (X86_DR_GET_RW_LEN (control, i) == 0)
|
||||
{
|
||||
addr = x86_dr_low_get_addr (i);
|
||||
rc = 1;
|
||||
if (show_debug_regs)
|
||||
x86_show_dr (state, "watchpoint_hit", addr, -1, hw_execute);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -128,4 +128,8 @@ extern int x86_dr_stopped_data_address (struct x86_debug_reg_state *state,
|
|||
Otherwise return false. */
|
||||
extern int x86_dr_stopped_by_watchpoint (struct x86_debug_reg_state *state);
|
||||
|
||||
/* Return true if the inferior has some hardware breakpoint that
|
||||
triggered. Otherwise return false. */
|
||||
extern int x86_dr_stopped_by_hw_breakpoint (struct x86_debug_reg_state *state);
|
||||
|
||||
#endif /* X86_DREGS_H */
|
||||
|
|
|
@ -260,6 +260,18 @@ x86_can_use_hw_breakpoint (struct target_ops *self,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Return non-zero if the inferior has some breakpoint that triggered.
|
||||
Otherwise return zero. */
|
||||
|
||||
static int
|
||||
x86_stopped_by_hw_breakpoint (struct target_ops *ops)
|
||||
{
|
||||
struct x86_debug_reg_state *state
|
||||
= x86_debug_reg_state (ptid_get_pid (inferior_ptid));
|
||||
|
||||
return x86_dr_stopped_by_hw_breakpoint (state);
|
||||
}
|
||||
|
||||
static void
|
||||
add_show_debug_regs_command (void)
|
||||
{
|
||||
|
@ -297,6 +309,11 @@ x86_use_watchpoints (struct target_ops *t)
|
|||
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;
|
||||
|
||||
/* A target must provide an implementation of the
|
||||
"to_supports_stopped_by_hw_breakpoint" target method before this
|
||||
callback will be used. */
|
||||
t->to_stopped_by_hw_breakpoint = x86_stopped_by_hw_breakpoint;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue