From 42995dbda646ff0291a36f83a7f1a9f45e3fda8a Mon Sep 17 00:00:00 2001 From: Gary Benson Date: Thu, 19 Jun 2014 11:55:26 +0100 Subject: Vectorize gdbserver x86 debug register accessors This commit makes gdbserver access the x86 debug register accessor functions via the same function vector as GDB proper. This removes a chunk of conditional code that was previously in i386-{nat,low}.h and leaves a single macro as the only GDB/gdbserver difference in nat/i386-dregs.c. gdb/ 2014-06-20 Gary Benson * i386-nat.h (debug_hw_points): Moved to nat/i386-dregs.c. (i386_dr_low_type): Moved to nat/i386-dregs.h. (i386_dr_low): Likewise. (i386_dr_low_can_set_addr): Moved to nat/i386-dregs.c. (i386_dr_low_set_addr): Likewise. (i386_dr_low_get_addr): Likewise. (i386_dr_low_can_set_control): Likewise. (i386_dr_low_set_control): Likewise. (i386_dr_low_get_control): Likewise. (i386_dr_low_get_status): Likewise. (i386_get_debug_register_length): Likewise. * nat/i386-dregs.h (i386_dr_low_type): Moved from i386-nat.h. (i386_dr_low): Likewise. * nat/i386-dregs.c (i386-low.h): Remove include. (i386-nat.h): Likewise. (nat/i386-dregs.h): New include. (i386_dr_low_can_set_addr): Moved from i386-nat.h. (i386_dr_low_set_addr): Likewise. (i386_dr_low_get_addr): Likewise. (i386_dr_low_can_set_control): Likewise. (i386_dr_low_set_control): Likewise. (i386_dr_low_get_control): Likewise. (i386_dr_low_get_status): Likewise. (i386_get_debug_register_length): Likewise. (debug_hw_points): Likewise. gdb/gdbserver/ 2014-06-20 Gary Benson * i386-low.h (i386_dr_low_can_set_addr): Removed. (i386_dr_low_set_addr): Likewise. (i386_dr_low_get_addr): Likewise. (i386_dr_low_can_set_control): Likewise. (i386_dr_low_set_control): Likewise. (i386_dr_low_get_control): Likewise. (i386_dr_low_get_status): Likewise. (i386_get_debug_register_length): Likewise. * linux-x86-low.c (i386_dr_low_set_addr): Changed signature. Made static. (i386_dr_low_get_addr): Likewise. (i386_dr_low_set_control): Likewise. (i386_dr_low_get_control): Likewise. (i386_dr_low_get_status): Likewise. (i386_dr_low): New global variable. * win32-i386-low.c (i386_dr_low_set_addr): Changed signature. Made static. (i386_dr_low_get_addr): Likewise. (i386_dr_low_set_control): Likewise. (i386_dr_low_get_control): Likewise. (i386_dr_low_get_status): Likewise. (i386_dr_low): New global variable. --- gdb/nat/i386-dregs.c | 37 ++++++++++++++++++++++++++++++++++--- gdb/nat/i386-dregs.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) (limited to 'gdb/nat') diff --git a/gdb/nat/i386-dregs.c b/gdb/nat/i386-dregs.c index 0067a90..e7d1620 100644 --- a/gdb/nat/i386-dregs.c +++ b/gdb/nat/i386-dregs.c @@ -19,12 +19,11 @@ #ifdef GDBSERVER #include "server.h" -#include "i386-low.h" #else #include "defs.h" -#include "i386-nat.h" #include "inferior.h" #endif +#include "nat/i386-dregs.h" /* Support for hardware watchpoints and breakpoints using the i386 debug registers. @@ -37,6 +36,35 @@ The functions below implement debug registers sharing by reference counts, and allow to watch regions up to 16 bytes long. */ +/* Accessor macros for low-level function vector. */ + +/* Can we update the inferior's debug registers? */ +#define i386_dr_low_can_set_addr() (i386_dr_low.set_addr != NULL) + +/* Update the inferior's debug register REGNUM from STATE. */ +#define i386_dr_low_set_addr(new_state, i) \ + (i386_dr_low.set_addr ((i), (new_state)->dr_mirror[(i)])) + +/* Return the inferior's debug register REGNUM. */ +#define i386_dr_low_get_addr(i) (i386_dr_low.get_addr ((i))) + +/* Can we update the inferior's DR7 control register? */ +#define i386_dr_low_can_set_control() (i386_dr_low.set_control != NULL) + +/* Update the inferior's DR7 debug control register from STATE. */ +#define i386_dr_low_set_control(new_state) \ + (i386_dr_low.set_control ((new_state)->dr_control_mirror)) + +/* Return the value of the inferior's DR7 debug control register. */ +#define i386_dr_low_get_control() (i386_dr_low.get_control ()) + +/* Return the value of the inferior's DR6 debug status register. */ +#define i386_dr_low_get_status() (i386_dr_low.get_status ()) + +/* Return the debug register size, in bytes. */ +#define i386_get_debug_register_length() \ + (i386_dr_low.debug_register_length) + /* Support for 8-byte wide hw watchpoints. */ #define TARGET_HAS_DR_LEN_8 (i386_get_debug_register_length () == 8) @@ -147,8 +175,11 @@ /* Types of operations supported by i386_handle_nonaligned_watchpoint. */ typedef enum { WP_INSERT, WP_REMOVE, WP_COUNT } i386_wp_op_t; -/* Print debugging messages. */ #ifndef GDBSERVER +/* Whether or not to print the mirrored debug registers. */ +extern int debug_hw_points; + +/* Print debugging messages. */ #define debug_printf(fmt, args...) \ fprintf_unfiltered (gdb_stdlog, fmt, ##args); #endif diff --git a/gdb/nat/i386-dregs.h b/gdb/nat/i386-dregs.h index 58029ef..16edf63 100644 --- a/gdb/nat/i386-dregs.h +++ b/gdb/nat/i386-dregs.h @@ -35,6 +35,37 @@ /* Forward declaration. */ enum target_hw_bp_type; +/* Low-level function vector. */ + +struct i386_dr_low_type + { + /* Set the debug control (DR7) register to a given value for + all LWPs. May be NULL if the debug control register cannot + be set. */ + void (*set_control) (unsigned long); + + /* Put an address into one debug register for all LWPs. May + be NULL if debug registers cannot be set*/ + void (*set_addr) (int, CORE_ADDR); + + /* Return the address in a given debug register of the current + LWP. */ + CORE_ADDR (*get_addr) (int); + + /* Return the value of the debug status (DR6) register for + current LWP. */ + unsigned long (*get_status) (void); + + /* Return the value of the debug control (DR7) register for + current LWP. */ + unsigned long (*get_control) (void); + + /* Number of bytes used for debug registers (4 or 8). */ + int debug_register_length; + }; + +extern struct i386_dr_low_type i386_dr_low; + /* Debug registers' indices. */ #define DR_FIRSTADDR 0 #define DR_LASTADDR 3 -- cgit v1.1