This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] GDB patches for hw watchpoints


I am submitting this patch on behalf of  Ben Elliston <bje@au1.ibm.com>,
this patch implements hardware watchpoints on PPC platform. Please review
and comment, so I can commit.

2005-05-04  Ben Elliston  <bje@au.ibm.com>

        * config/powerpc/nm-linux.h
        (HAVE_NONSTEPPABLE_WATCHPOINT): Define.
        (TARGET_REGION_OK_FOR_HW_WATCHPOINT): Likewise.
        (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Likewise.
        (STOPPED_BY_WATCHPOINT): Likewise.
        (target_insert_watchpoint): Likewise.
        (target_remove_watchpoint): Likewise.
        (ppc_linux_insert_watchpoint): Declare.
        (ppc_linux_remove_watchpoint): Likewise.
        * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Define, if not already.
        (PTRACE_SET_DEBUGREG): Likewise.
        (PTRACE_GETSINGOINFO): Likewise.
        (ppc_linux_insert_watchpoint): New.
        (ppc_linux_remove_watchpoint): Likewise.
        (ppc_linux_stopped_by_watchpoint): Likewise.
        (ppc_linux_check_watch_resources): Likewise.

Index: config/powerpc/nm-linux.h
===================================================================
RCS file: /home/bje/src-cvs/src/gdb/config/powerpc/nm-linux.h,v
retrieving revision 1.12
diff -u -p -r1.12 nm-linux.h
--- config/powerpc/nm-linux.h   29 Jul 2004 20:22:50 -0000      1.12
+++ config/powerpc/nm-linux.h   16 Aug 2005 01:53:56 -0000
@@ -34,4 +34,26 @@ extern int kernel_u_size (void);

 #define FETCH_INFERIOR_REGISTERS

+/* Hardware watchpoints */
+
+#define HAVE_NONSTEPPABLE_WATCHPOINT 1
+#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(addr, len) 1
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+       ppc_linux_check_watch_resources (type, cnt, ot)
+
+#define STOPPED_BY_WATCHPOINT(w) \
+       ppc_linux_stopped_by_watchpoint (w)
+
+#define target_insert_watchpoint(addr, len, type) \
+         ppc_linux_insert_watchpoint (inferior_ptid, addr, len, type)
+#define target_remove_watchpoint(addr, len, type) \
+         ppc_linux_remove_watchpoint (inferior_ptid, addr, len)
+
+extern long ppc_linux_insert_watchpoint (ptid_t ptid, CORE_ADDR addr,
+                                        int len, int rw);
+
+extern long ppc_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr,
+                                        int len);
+
 #endif /* #ifndef NM_LINUX_H */Index: ppc-linux-nat.c
===================================================================
RCS file: /home/bje/src-cvs/src/gdb/ppc-linux-nat.c,v
retrieving revision 1.54
diff -u -p -r1.54 ppc-linux-nat.c
--- ppc-linux-nat.c     11 Feb 2005 18:13:51 -0000      1.54
+++ ppc-linux-nat.c     16 Aug 2005 01:53:56 -0000
@@ -79,6 +79,16 @@
 #define PTRACE_SETEVRREGS 21
 #endif

+/* Similarly for the hardware watchpoint support.  */
+#ifndef PTRACE_GET_DEBUGREG
+#define PTRACE_GET_DEBUGREG    25
+#endif
+#ifndef PTRACE_SET_DEBUGREG
+#define PTRACE_SET_DEBUGREG    26
+#endif
+#ifndef PTRACE_GETSIGINFO
+#define PTRACE_GETSIGINFO    0x4202
+#endif

 /* This oddity is because the Linux kernel defines elf_vrregset_t as
    an array of 33 16 bytes long elements.  I.e. it leaves out vrsave.
@@ -883,3 +893,82 @@ fill_fpregset (gdb_fpregset_t *fpregsetp
         right_fill_reg (tdep->ppc_fpscr_regnum, (fpp + 8 * 32));
     }
 }
+
+/* Set a watchpoint of type TYPE at address ADDR.  */
+long
+ppc_linux_insert_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rw)
+{
+  int tid;
+  long dabr_value;
+
+  /* Handle sub-8-byte quantities.  */
+  if (len <= 0)
+    return -1;
+
+  /* addr+len must fall in the 8 byte watchable region.  */
+  if ((addr + len) > (addr & ~7) + 8)
+    return -1;
+
+  dabr_value = addr & ~7;
+  switch (rw)
+    {
+    case hw_read:
+      /* Set read and translate bits.  */
+      dabr_value |= 5;
+      break;
+    case hw_write:
+      /* Set write and translate bits.  */
+      dabr_value |= 6;
+      break;
+    case hw_access:
+      /* Set read, write and translate bits.  */
+      dabr_value |= 7;
+      break;
+    }
+
+  tid = TIDGET (ptid);
+  if (tid == 0)
+    tid = PIDGET (ptid);
+
+  return ptrace (PTRACE_SET_DEBUGREG, tid, 0, dabr_value);
+}
+
+long
+ppc_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr, int len)
+{
+  int tid;
+
+  tid = TIDGET (ptid);
+  if (tid == 0)
+    tid = PIDGET (ptid);
+
+  return ptrace (PTRACE_SET_DEBUGREG, tid, 0, 0);
+}
+
+int
+ppc_linux_stopped_by_watchpoint (void)
+{
+  int tid;
+  struct siginfo siginfo;
+  ptid_t ptid = inferior_ptid;
+
+  tid = TIDGET(ptid);
+  if (tid == 0)
+    tid = PIDGET (ptid);
+
+  errno = 0;
+  ptrace (PTRACE_GETSIGINFO, tid, (PTRACE_TYPE_ARG3) 0, &siginfo);
+
+  if (errno != 0 || siginfo.si_signo != SIGTRAP ||
+      (siginfo.si_code & 0xffff) != 0x0004)
+    return 0;
+
+  return 1;
+}
+
+int
+ppc_linux_check_watch_resources (int type, int cnt, int ot)
+{
+  /* PPC has one DABR (hardware watchpoint) register.  */
+  return (cnt <= 1);
+}



----------
Manoj Iyer
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Cogito ergo sum                                                          +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]