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 5d0502afa0e770bf6ebfbe78f81500d1af1fa5d1..c38998849f8b861c1c0910b1e12a25becf73e214 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 54556f827d1c83e0a2c1a86e74e0eeaf5d37cb9e..cde9c0af70b1e36bf6b7bf1f2f8b7e7c13b74086 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 bad03b9bbc35d4e79b2402965f42229b2eb84862..e726038072c57e9051dce5e0ccba1ea3b387575f 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 b8a000616386cc8e0e1e780a8d0da7f3ff88c0c2..94451da43f1b60aac38c9c84f3c54c254b377a03 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 09160dd99d78be2a46983c523dfc361a63f8c8b9..e89467766f37a2ba21c34d905475fc5c09815bb0 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 4a213b320b9f425b90584d50c176d5510290f1c6..acac71a6afac083110d2563adbd7f1ceb6d78cf8 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 0067a90359b8d272b0c5f1b2350d46e65cf6ddaf..e7d1620e8e7b4cede80363eb252c6ed50994a917 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 58029ef7fd70859c6fa40b51c069777fad6735fb..16edf63e19bd4d162edebf8856f2a2e5023c716f 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