From: Gary Benson Date: Thu, 19 Jun 2014 10:55:26 +0000 (+0100) Subject: Vectorize gdbserver x86 debug register accessors X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=42995dbda646ff0291a36f83a7f1a9f45e3fda8a;p=binutils-gdb.git 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5d0502afa0e..c38998849f8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,31 @@ +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. + 2014-06-19 Iain Buclaw * Makefile.in (SFILES): Add d-exp.y. diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 54556f827d1..cde9c0af70b 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,28 @@ +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. + 2014-06-20 Marcus Shawcroft * configure.ac: Invoke. AC_CHECK_TOOL(AR, ar). diff --git a/gdb/gdbserver/i386-low.h b/gdb/gdbserver/i386-low.h index bad03b9bbc3..e726038072c 100644 --- a/gdb/gdbserver/i386-low.h +++ b/gdb/gdbserver/i386-low.h @@ -22,44 +22,3 @@ /* Initialize STATE. */ extern void i386_low_init_dregs (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 - into the inferior, remove them, and check their status. These - functions are: - - i386_dr_low_set_control -- set the debug control (DR7) - register to a given value - - i386_dr_low_set_addr -- put an address into one debug register - - i386_dr_low_get_status -- return the value of the debug - status (DR6) register. -*/ - -/* Can we update the inferior's debug registers? */ -#define i386_dr_low_can_set_addr() 1 - -/* Update the inferior's debug register REGNUM from STATE. */ -extern void i386_dr_low_set_addr (const struct i386_debug_reg_state *state, - int regnum); - -/* Return the inferior's debug register REGNUM. */ -extern CORE_ADDR i386_dr_low_get_addr (int regnum); - -/* Can we update the inferior's DR7 control register? */ -#define i386_dr_low_can_set_control() 1 - -/* Update the inferior's DR7 debug control register from STATE. */ -extern void i386_dr_low_set_control (const struct i386_debug_reg_state *state); - -/* Return the value of the inferior's DR7 debug control register. */ -extern unsigned i386_dr_low_get_control (void); - -/* Return the value of the inferior's DR6 debug status register. */ -extern unsigned i386_dr_low_get_status (void); - -/* Return the debug register size, in bytes. */ -/* Note that sizeof (long) == 4 on win64. */ -#define i386_get_debug_register_length() (sizeof (void *)) diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index b8a00061638..94451da43f1 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -587,8 +587,8 @@ update_debug_registers_callback (struct inferior_list_entry *entry, /* Update the inferior's debug register REGNUM from STATE. */ -void -i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum) +static void +i386_dr_low_set_addr (int regnum, CORE_ADDR addr) { /* Only update the threads of this process. */ int pid = pid_of (current_inferior); @@ -601,7 +601,7 @@ i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum) /* Return the inferior's debug register REGNUM. */ -CORE_ADDR +static CORE_ADDR i386_dr_low_get_addr (int regnum) { ptid_t ptid = ptid_of (current_inferior); @@ -614,8 +614,8 @@ i386_dr_low_get_addr (int regnum) /* Update the inferior's DR7 debug control register from STATE. */ -void -i386_dr_low_set_control (const struct i386_debug_reg_state *state) +static void +i386_dr_low_set_control (unsigned long control) { /* Only update the threads of this process. */ int pid = pid_of (current_inferior); @@ -625,7 +625,7 @@ i386_dr_low_set_control (const struct i386_debug_reg_state *state) /* Return the inferior's DR7 debug control register. */ -unsigned +static unsigned long i386_dr_low_get_control (void) { ptid_t ptid = ptid_of (current_inferior); @@ -636,13 +636,24 @@ i386_dr_low_get_control (void) /* Get the value of the DR6 debug status register from the inferior and record it in STATE. */ -unsigned +static unsigned long i386_dr_low_get_status (void) { ptid_t ptid = ptid_of (current_inferior); return x86_linux_dr_get (ptid, DR_STATUS); } + +/* Low-level function vector. */ +struct i386_dr_low_type i386_dr_low = + { + i386_dr_low_set_control, + i386_dr_low_set_addr, + i386_dr_low_get_addr, + i386_dr_low_get_status, + i386_dr_low_get_control, + sizeof (void *), + }; /* Breakpoint/Watchpoint support. */ diff --git a/gdb/gdbserver/win32-i386-low.c b/gdb/gdbserver/win32-i386-low.c index 09160dd99d7..e89467766f3 100644 --- a/gdb/gdbserver/win32-i386-low.c +++ b/gdb/gdbserver/win32-i386-low.c @@ -45,8 +45,8 @@ static int debug_registers_used = 0; /* Update the inferior's debug register REGNUM from STATE. */ -void -i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum) +static void +i386_dr_low_set_addr (int regnum, CORE_ADDR addr) { if (! (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR)) fatal ("Invalid debug register %d", regnum); @@ -58,7 +58,7 @@ i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum) debug_registers_used = 1; } -CORE_ADDR +static CORE_ADDR i386_dr_low_get_addr (int regnum) { gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR); @@ -68,8 +68,8 @@ i386_dr_low_get_addr (int regnum) /* Update the inferior's DR7 debug control register from STATE. */ -void -i386_dr_low_set_control (const struct i386_debug_reg_state *state) +static void +i386_dr_low_set_control (unsigned long control) { /* debug_reg_state.dr_control_mirror is already set. Just notify i386_set_thread_context, i386_thread_added @@ -78,7 +78,7 @@ i386_dr_low_set_control (const struct i386_debug_reg_state *state) debug_registers_used = 1; } -unsigned +static unsigned long i386_dr_low_get_control (void) { return debug_reg_state.dr_control_mirror; @@ -87,7 +87,7 @@ i386_dr_low_get_control (void) /* Get the value of the DR6 debug status register from the inferior and record it in STATE. */ -unsigned +static unsigned long i386_dr_low_get_status (void) { /* We don't need to do anything here, the last call to thread_rec for @@ -95,6 +95,17 @@ i386_dr_low_get_status (void) return debug_reg_state.dr_status_mirror; } +/* Low-level function vector. */ +struct i386_dr_low_type i386_dr_low = + { + i386_dr_low_set_control, + i386_dr_low_set_addr, + i386_dr_low_get_addr, + i386_dr_low_get_status, + i386_dr_low_get_control, + sizeof (void *), + }; + /* Breakpoint/watchpoint support. */ static int diff --git a/gdb/i386-nat.h b/gdb/i386-nat.h index 4a213b320b9..acac71a6afa 100644 --- a/gdb/i386-nat.h +++ b/gdb/i386-nat.h @@ -27,82 +27,12 @@ /* Hardware-assisted breakpoints and watchpoints. */ -/* Whether or not to print the mirrored debug registers. */ -extern int debug_hw_points; - /* Add watchpoint methods to the provided target_ops. Targets using i386 family debug registers for watchpoints should call this. */ struct target_ops; extern void i386_use_watchpoints (struct target_ops *); -/* Support for hardware watchpoints and breakpoints using the i386 - debug registers. - - 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 - functions are: - - set_control -- set the debug control (DR7) - register to a given value for all LWPs - - set_addr -- put an address into 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 - - 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 - { - void (*set_control) (unsigned long); - void (*set_addr) (int, CORE_ADDR); - CORE_ADDR (*get_addr) (int); - unsigned long (*get_status) (void); - unsigned long (*get_control) (void); - int debug_register_length; - }; - -extern struct i386_dr_low_type i386_dr_low; - -/* 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) - /* 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.c b/gdb/nat/i386-dregs.c index 0067a90359b..e7d1620e8e7 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 58029ef7fd7..16edf63e19b 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