diff options
author | Gary Benson <gbenson@redhat.com> | 2014-06-16 12:18:41 +0100 |
---|---|---|
committer | Gary Benson <gbenson@redhat.com> | 2014-06-18 11:46:35 +0100 |
commit | b9228891286aec649c0c53d9b2eff0d5bea7f642 (patch) | |
tree | 68eb2790bd78834fa60278b7437f6cdedcc6f6c2 /gdb | |
parent | a1aa2221cbe340d23c6abf4d68cb509aa16cf8c0 (diff) | |
download | gdb-b9228891286aec649c0c53d9b2eff0d5bea7f642.zip gdb-b9228891286aec649c0c53d9b2eff0d5bea7f642.tar.gz gdb-b9228891286aec649c0c53d9b2eff0d5bea7f642.tar.bz2 |
Create nat/i386-dregs.h
This commit moves code to be shared from i386-{nat,low}.[ch]
into a new file, nat/i386-dregs.h.
gdb/
2014-06-18 Gary Benson <gbenson@redhat.com>
* nat/i386-dregs.h: New file.
* Makefile.in (HFILES_NO_SRCDIR): Add the above.
* i386-nat.h (i386-dregs.h): New include.
(DR_FIRSTADDR): Now in i386-dregs.h.
(DR_LASTADDR): Likewise.
(DR_NADDR): Likewise.
(DR_STATUS): Likewise.
(DR_CONTROL): Likewise.
(i386_debug_reg_state): Likewise.
* i386-nat.c (ALL_DEBUG_REGISTERS): Likewise.
gdb/gdbserver/
2014-06-18 Gary Benson <gbenson@redhat.com>
* i386-low.h (i386-dregs.h): New include.
(DR_FIRSTADDR): Now in i386-dregs.h.
(DR_LASTADDR): Likewise.
(DR_NADDR): Likewise.
(DR_STATUS): Likewise.
(DR_CONTROL): Likewise.
(i386_debug_reg_state): Likewise.
(i386_dr_insert_watchpoint): Likewise.
(i386_dr_remove_watchpoint): Likewise.
(i386_dr_region_ok_for_watchpoint): Likewise.
(i386_dr_stopped_data_address): Likewise.
(i386_dr_stopped_by_watchpoint): Likewise.
* i386-low.c (ALL_DEBUG_REGISTERS): Likewise.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/gdbserver/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/gdbserver/i386-low.c | 3 | ||||
-rw-r--r-- | gdb/gdbserver/i386-low.h | 66 | ||||
-rw-r--r-- | gdb/i386-nat.c | 3 | ||||
-rw-r--r-- | gdb/i386-nat.h | 32 | ||||
-rw-r--r-- | gdb/nat/i386-dregs.h | 138 |
8 files changed, 173 insertions, 100 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 04ee3ef..3abbd16 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2014-06-18 Gary Benson <gbenson@redhat.com> + + * nat/i386-dregs.h: New file. + * Makefile.in (HFILES_NO_SRCDIR): Add the above. + * i386-nat.h (i386-dregs.h): New include. + (DR_FIRSTADDR): Now in i386-dregs.h. + (DR_LASTADDR): Likewise. + (DR_NADDR): Likewise. + (DR_STATUS): Likewise. + (DR_CONTROL): Likewise. + (i386_debug_reg_state): Likewise. + * i386-nat.c (ALL_DEBUG_REGISTERS): Likewise. + 2014-06-18 Don Breazeal <donb@codesourcery.com> * breakpoint.c (set_longjmp_breakpoint): Call diff --git a/gdb/Makefile.in b/gdb/Makefile.in index deb64a1..d17774a 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -934,7 +934,7 @@ common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h \ gdb_bfd.h sparc-ravenscar-thread.h ppc-ravenscar-thread.h common/linux-btrace.h \ ctf.h common/i386-cpuid.h common/i386-gcc-cpuid.h target/resume.h \ target/wait.h target/waitstatus.h nat/linux-nat.h nat/linux-waitpid.h \ -common/print-utils.h common/rsp-low.h +common/print-utils.h common/rsp-low.h nat/i386-dregs.h # Header files that already have srcdir in them, or which are in objdir. diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 3186336..a21dc7d 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,21 @@ 2014-06-18 Gary Benson <gbenson@redhat.com> + * i386-low.h (i386-dregs.h): New include. + (DR_FIRSTADDR): Now in i386-dregs.h. + (DR_LASTADDR): Likewise. + (DR_NADDR): Likewise. + (DR_STATUS): Likewise. + (DR_CONTROL): Likewise. + (i386_debug_reg_state): Likewise. + (i386_dr_insert_watchpoint): Likewise. + (i386_dr_remove_watchpoint): Likewise. + (i386_dr_region_ok_for_watchpoint): Likewise. + (i386_dr_stopped_data_address): Likewise. + (i386_dr_stopped_by_watchpoint): Likewise. + * i386-low.c (ALL_DEBUG_REGISTERS): Likewise. + +2014-06-18 Gary Benson <gbenson@redhat.com> + * i386-low.h (i386_low_insert_watchpoint): Renamed to i386_dr_insert_watchpoint. (i386_low_remove_watchpoint): Renamed to diff --git a/gdb/gdbserver/i386-low.c b/gdb/gdbserver/i386-low.c index 1c9d7aa..bd25694 100644 --- a/gdb/gdbserver/i386-low.c +++ b/gdb/gdbserver/i386-low.c @@ -146,9 +146,6 @@ /* Did the watchpoint whose address is in the I'th register break? */ #define I386_DR_WATCH_HIT(dr6, i) ((dr6) & (1 << (i))) -/* A macro to loop over all debug registers. */ -#define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++) - /* Types of operations supported by i386_handle_nonaligned_watchpoint. */ typedef enum { WP_INSERT, WP_REMOVE, WP_COUNT } i386_wp_op_t; diff --git a/gdb/gdbserver/i386-low.h b/gdb/gdbserver/i386-low.h index 3d3feb3..71f7c32 100644 --- a/gdb/gdbserver/i386-low.h +++ b/gdb/gdbserver/i386-low.h @@ -17,74 +17,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* Support for hardware watchpoints and breakpoints using the i386 - debug registers. - - This provides several functions for inserting and removing - hardware-assisted breakpoints and watchpoints, testing if one or - more of the watchpoints triggered and at what address, checking - whether a given region can be watched, etc. - - The functions below implement debug registers sharing by reference - counts, and allow to watch regions up to 16 bytes long - (32 bytes on 64 bit hosts). */ - -/* 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]; -}; + +#include "nat/i386-dregs.h" /* Initialize STATE. */ extern void i386_low_init_dregs (struct i386_debug_reg_state *state); -/* 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. */ -extern int i386_dr_insert_watchpoint (struct i386_debug_reg_state *state, - enum target_hw_bp_type type, - CORE_ADDR addr, - int 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. */ -extern int i386_dr_remove_watchpoint (struct i386_debug_reg_state *state, - enum target_hw_bp_type type, - CORE_ADDR addr, - int len); - -/* Return non-zero if we can watch a memory region that starts at - address ADDR and whose length is LEN bytes. */ -extern int i386_dr_region_ok_for_watchpoint (struct i386_debug_reg_state *state, - CORE_ADDR addr, int len); - -/* If the inferior has some break/watchpoint that triggered, set the - address associated with that break/watchpoint and return true. - Otherwise, return false. */ -extern int i386_dr_stopped_data_address (struct i386_debug_reg_state *state, - CORE_ADDR *addr_p); - -/* Return true if the inferior has some watchpoint that triggered. - Otherwise return false. */ -extern int i386_dr_stopped_by_watchpoint (struct i386_debug_reg_state *state); /* Each target needs to provide several low-level functions that will be called to insert watchpoints and hardware breakpoints diff --git a/gdb/i386-nat.c b/gdb/i386-nat.c index 86e655f..1dfa9ee 100644 --- a/gdb/i386-nat.c +++ b/gdb/i386-nat.c @@ -171,9 +171,6 @@ struct i386_dr_low_type i386_dr_low; /* Did the watchpoint whose address is in the I'th register break? */ #define I386_DR_WATCH_HIT(dr6, i) ((dr6) & (1 << (i))) -/* A macro to loop over all debug registers. */ -#define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++) - /* Per-process data. We don't bind this to a per-inferior registry because of targets like x86 GNU/Linux that need to keep track of processes that aren't bound to any inferior (e.g., fork children, diff --git a/gdb/i386-nat.h b/gdb/i386-nat.h index ae2f1a7..1f4130c 100644 --- a/gdb/i386-nat.h +++ b/gdb/i386-nat.h @@ -23,6 +23,8 @@ #ifndef I386_NAT_H #define I386_NAT_H 1 +#include "nat/i386-dregs.h" + /* Hardware-assisted breakpoints and watchpoints. */ /* Add watchpoint methods to the provided target_ops. @@ -34,12 +36,7 @@ extern void i386_use_watchpoints (struct target_ops *); /* Support for hardware watchpoints and breakpoints using the i386 debug registers. - This provides several functions for inserting and removing - hardware-assisted breakpoints and watchpoints, testing if one or - more of the watchpoints triggered and at what address, checking - whether a given region can be watched, etc. - - In addition, each target should provide several low-level functions + Each target should provide several low-level 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 @@ -76,29 +73,6 @@ struct i386_dr_low_type 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' diff --git a/gdb/nat/i386-dregs.h b/gdb/nat/i386-dregs.h new file mode 100644 index 0000000..c17c6ae --- /dev/null +++ b/gdb/nat/i386-dregs.h @@ -0,0 +1,138 @@ +/* Debug register code for the i386. + + Copyright (C) 2009-2014 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Support for hardware watchpoints and breakpoints using the i386 + debug registers. + + This provides several functions for inserting and removing + hardware-assisted breakpoints and watchpoints, testing if one or + more of the watchpoints triggered and at what address, checking + whether a given region can be watched, etc. + + The functions below implement debug registers sharing by reference + counts, and allow to watch regions up to 16 bytes long + (32 bytes on 64 bit hosts). */ + +#ifndef I386_DREGS_H +#define I386_DREGS_H 1 + +/* Forward declaration. */ +enum target_hw_bp_type; + +/* 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]; +}; + +/* A macro to loop over all debug registers. */ +#define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++) + +/* High-level functions. */ + +/* 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. */ +extern int i386_dr_insert_watchpoint (struct i386_debug_reg_state *state, + enum target_hw_bp_type type, + CORE_ADDR addr, + int 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. */ +extern int i386_dr_remove_watchpoint (struct i386_debug_reg_state *state, + enum target_hw_bp_type type, + CORE_ADDR addr, + int len); + +/* Return non-zero if we can watch a memory region that starts at + address ADDR and whose length is LEN bytes. */ +extern int i386_dr_region_ok_for_watchpoint (struct i386_debug_reg_state *state, + CORE_ADDR addr, int len); + +/* If the inferior has some break/watchpoint that triggered, set the + address associated with that break/watchpoint and return true. + Otherwise, return false. */ +extern int i386_dr_stopped_data_address (struct i386_debug_reg_state *state, + CORE_ADDR *addr_p); + +/* Return true if the inferior has some watchpoint that triggered. + Otherwise return false. */ +extern int i386_dr_stopped_by_watchpoint (struct i386_debug_reg_state *state); + +/* Low-level functions. */ + +/* Print the values of the mirrored debug registers. */ + +extern void i386_dr_show (struct i386_debug_reg_state *state, + const char *func, CORE_ADDR addr, + int len, enum target_hw_bp_type type); + +/* Return the value of a 4-bit field for DR7 suitable for watching a + region of LEN bytes for accesses of type TYPE. LEN is assumed to + have the value of 1, 2, or 4. */ + +extern unsigned i386_dr_length_and_rw_bits (int len, + enum target_hw_bp_type type); + +/* Insert a watchpoint at address ADDR, which is assumed to be aligned + according to the length of the region to watch. LEN_RW_BITS is the + value of the bits from DR7 which describes the length and access + type of the region to be watched by this watchpoint. Return 0 on + success, -1 on failure. */ + +extern int i386_dr_insert_aligned_watchpoint (struct i386_debug_reg_state *state, + CORE_ADDR addr, + unsigned len_rw_bits); + +/* Remove a watchpoint at address ADDR, which is assumed to be aligned + according to the length of the region to watch. LEN_RW_BITS is the + value of the bits from DR7 which describes the length and access + type of the region watched by this watchpoint. Return 0 on + success, -1 on failure. */ + +extern int i386_dr_remove_aligned_watchpoint (struct i386_debug_reg_state *state, + CORE_ADDR addr, + unsigned len_rw_bits); + +/* Update the inferior debug registers state, in STATE, with the + new debug registers state, in NEW_STATE. */ + +extern void i386_dr_update_inferior_debug_regs (struct i386_debug_reg_state *state, + struct i386_debug_reg_state *new_state); + +#endif /* I386_DREGS_H */ |