Low level functions to implement Oeprating System specific
code to manipulate I386 debug registers.
- Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#include "defs.h"
-
#ifndef I386_NAT_H
#define I386_NAT_H 1
whether a given region can be watched, etc.
In addition, each target should provide several low-level functions
- regrouped into i386_dr_low_type struct below. These functions
+ regrouped into i386_dr_low_type struct below. These functions
that will be called to insert watchpoints and hardware breakpoints
into the inferior, remove them, and check their status. These
functions are:
set_addr -- put an address into one debug
register for all LWPs
- reset_addr -- reset the address stored in
- one debug register for all LWPs
+ get_addr -- return the address in a given debug
+ register of the current LWP
get_status -- return the value of the debug
status (DR6) register for current LWP
- unset_status -- unset the specified bits of the debug
- status (DR6) register for all LWPs
+ get_control -- return the value of the debug
+ control (DR7) register for current LWP
Additionally, the native file should set the debug_register_length
field to 4 or 8 depending on the number of bytes used for
deubg registers. */
-struct i386_dr_low_type
+struct i386_dr_low_type
{
void (*set_control) (unsigned long);
void (*set_addr) (int, CORE_ADDR);
- void (*reset_addr) (int);
+ CORE_ADDR (*get_addr) (int);
unsigned long (*get_status) (void);
- void (*unset_status) (unsigned long);
+ unsigned long (*get_control) (void);
int debug_register_length;
};
extern struct i386_dr_low_type i386_dr_low;
+/* Debug registers' indices. */
+#define DR_FIRSTADDR 0
+#define DR_LASTADDR 3
+#define DR_NADDR 4 /* The number of debug address registers. */
+#define DR_STATUS 6 /* Index of debug status register (DR6). */
+#define DR_CONTROL 7 /* Index of debug control register (DR7). */
+
+/* Global state needed to track h/w watchpoints. */
+
+struct i386_debug_reg_state
+{
+ /* Mirror the inferior's DRi registers. We keep the status and
+ control registers separated because they don't hold addresses.
+ Note that since we can change these mirrors while threads are
+ running, we never trust them to explain a cause of a trap.
+ For that, we need to peek directly in the inferior registers. */
+ CORE_ADDR dr_mirror[DR_NADDR];
+ unsigned dr_status_mirror, dr_control_mirror;
+
+ /* Reference counts for each debug register. */
+ int dr_ref_count[DR_NADDR];
+};
+
/* Use this function to set i386_dr_low debug_register_length field
rather than setting it directly to check that the length is only
set once. It also enables the 'maint set/show show-debug-regs'
extern void i386_cleanup_dregs (void);
+/* Return a pointer to the local mirror of the debug registers of
+ process PID. */
+
+extern struct i386_debug_reg_state *i386_debug_reg_state (pid_t pid);
+
+/* Called whenever GDB is no longer debugging process PID. It deletes
+ data structures that keep track of debug register state. */
+
+extern void i386_forget_process (pid_t pid);
+
#endif /* I386_NAT_H */