Vectorize gdbserver x86 debug register accessors
authorGary Benson <gbenson@redhat.com>
Thu, 19 Jun 2014 10:55:26 +0000 (11:55 +0100)
committerGary Benson <gbenson@redhat.com>
Fri, 20 Jun 2014 12:05:50 +0000 (13:05 +0100)
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  <gbenson@redhat.com>

* 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  <gbenson@redhat.com>

* 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/ChangeLog
gdb/gdbserver/ChangeLog
gdb/gdbserver/i386-low.h
gdb/gdbserver/linux-x86-low.c
gdb/gdbserver/win32-i386-low.c
gdb/i386-nat.h
gdb/nat/i386-dregs.c
gdb/nat/i386-dregs.h

index 5d0502a..c389988 100644 (file)
@@ -1,3 +1,31 @@
+2014-06-20  Gary Benson  <gbenson@redhat.com>
+
+       * 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  <ibuclaw@gdcproject.org>
 
        * Makefile.in (SFILES): Add d-exp.y.
index 54556f8..cde9c0a 100644 (file)
@@ -1,3 +1,28 @@
+2014-06-20  Gary Benson  <gbenson@redhat.com>
+
+       * 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  <marcus.shawcroft@arm.com>
 
        * configure.ac: Invoke. AC_CHECK_TOOL(AR, ar).
index bad03b9..e726038 100644 (file)
 
 /* Initialize STATE.  */
 extern void i386_low_init_dregs (struct i386_debug_reg_state *state);
-
-\f
-/* 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 *))
index b8a0006..94451da 100644 (file)
@@ -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 *),
+  };
 \f
 /* Breakpoint/Watchpoint support.  */
 
index 09160dd..e894677 100644 (file)
@@ -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
index 4a213b3..acac71a 100644 (file)
 
 /* 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' 
index 0067a90..e7d1620 100644 (file)
 
 #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.
    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)
 
 /* 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
index 58029ef..16edf63 100644 (file)
 /* 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