Move PTRACE_GETREGSET and PTRACE_SETREGSET to nat/linux-ptrace.h
[binutils-gdb.git] / gdb / ppc-linux-nat.c
index c518f77d3a82cccf55b5444c82bf8221dba6d830..88ca49e3d449fff8b28f6ee310e7232af0a7b6a4 100644 (file)
@@ -1,6 +1,6 @@
 /* PPC GNU/Linux native support.
 
-   Copyright (C) 1988-2013 Free Software Foundation, Inc.
+   Copyright (C) 1988-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_string.h"
 #include "observer.h"
 #include "frame.h"
 #include "inferior.h"
 #include "gdbthread.h"
 #include "gdbcore.h"
 #include "regcache.h"
-#include "gdb_assert.h"
 #include "target.h"
 #include "linux-nat.h"
 
 #include "elf/common.h"
 #include "auxv.h"
 
-/* This sometimes isn't defined.  */
-#ifndef PT_ORIG_R3
-#define PT_ORIG_R3 34
-#endif
-#ifndef PT_TRAP
-#define PT_TRAP 40
-#endif
-
-/* The PPC_FEATURE_* defines should be provided by <asm/cputable.h>.
-   If they aren't, we can provide them ourselves (their values are fixed
-   because they are part of the kernel ABI).  They are used in the AT_HWCAP
-   entry of the AUXV.  */
-#ifndef PPC_FEATURE_CELL
-#define PPC_FEATURE_CELL 0x00010000
-#endif
-#ifndef PPC_FEATURE_BOOKE
-#define PPC_FEATURE_BOOKE 0x00008000
-#endif
-#ifndef PPC_FEATURE_HAS_DFP
-#define PPC_FEATURE_HAS_DFP    0x00000400  /* Decimal Floating Point.  */
-#endif
-
-/* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a
-   configure time check.  Some older glibc's (for instance 2.2.1)
-   don't have a specific powerpc version of ptrace.h, and fall back on
-   a generic one.  In such cases, sys/ptrace.h defines
-   PTRACE_GETFPXREGS and PTRACE_SETFPXREGS to the same numbers that
-   ppc kernel's asm/ptrace.h defines PTRACE_GETVRREGS and
-   PTRACE_SETVRREGS to be.  This also makes a configury check pretty
-   much useless.  */
-
-/* These definitions should really come from the glibc header files,
-   but Glibc doesn't know about the vrregs yet.  */
-#ifndef PTRACE_GETVRREGS
-#define PTRACE_GETVRREGS 18
-#define PTRACE_SETVRREGS 19
-#endif
-
-/* PTRACE requests for POWER7 VSX registers.  */
-#ifndef PTRACE_GETVSXREGS
-#define PTRACE_GETVSXREGS 27
-#define PTRACE_SETVSXREGS 28
-#endif
-
-/* Similarly for the ptrace requests for getting / setting the SPE
-   registers (ev0 -- ev31, acc, and spefscr).  See the description of
-   gdb_evrregset_t for details.  */
-#ifndef PTRACE_GETEVRREGS
-#define PTRACE_GETEVRREGS 20
-#define PTRACE_SETEVRREGS 21
-#endif
+#include "nat/ppc-linux.h"
 
 /* Similarly for the hardware watchpoint support.  These requests are used
    when the PowerPC HWDEBUG ptrace interface is not available.  */
@@ -864,11 +812,11 @@ ppc_linux_fetch_inferior_registers (struct target_ops *ops,
                                    struct regcache *regcache, int regno)
 {
   /* Overload thread id onto process id.  */
-  int tid = TIDGET (inferior_ptid);
+  int tid = ptid_get_lwp (inferior_ptid);
 
   /* No thread id, just use process id.  */
   if (tid == 0)
-    tid = PIDGET (inferior_ptid);
+    tid = ptid_get_pid (inferior_ptid);
 
   if (regno == -1)
     fetch_ppc_registers (regcache, tid);
@@ -1417,9 +1365,9 @@ have_ptrace_hwdebug_interface (void)
     {
       int tid;
 
-      tid = TIDGET (inferior_ptid);
+      tid = ptid_get_lwp (inferior_ptid);
       if (tid == 0)
-       tid = PIDGET (inferior_ptid);
+       tid = ptid_get_pid (inferior_ptid);
 
       /* Check for kernel support for PowerPC HWDEBUG ptrace interface.  */
       if (ptrace (PPC_PTRACE_GETHWDBGINFO, tid, 0, &hwdebug_info) >= 0)
@@ -1444,7 +1392,8 @@ have_ptrace_hwdebug_interface (void)
 }
 
 static int
-ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot)
+ppc_linux_can_use_hw_breakpoint (struct target_ops *self,
+                                int type, int cnt, int ot)
 {
   int total_hw_wp, total_hw_bp;
 
@@ -1472,6 +1421,11 @@ ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot)
     }
   else if (type == bp_hardware_breakpoint)
     {
+      if (total_hw_bp == 0)
+       {
+         /* No hardware breakpoint support. */
+         return 0;
+       }
       if (cnt > total_hw_bp)
        return -1;
     }
@@ -1484,9 +1438,9 @@ ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot)
       /* We need to know whether ptrace supports PTRACE_SET_DEBUGREG
         and whether the target has DABR.  If either answer is no, the
         ptrace call will return -1.  Fail in that case.  */
-      tid = TIDGET (ptid);
+      tid = ptid_get_lwp (ptid);
       if (tid == 0)
-       tid = PIDGET (ptid);
+       tid = ptid_get_pid (ptid);
 
       if (ptrace (PTRACE_SET_DEBUGREG, tid, 0, 0) == -1)
        return 0;
@@ -1496,7 +1450,8 @@ ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot)
 }
 
 static int
-ppc_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
+ppc_linux_region_ok_for_hw_watchpoint (struct target_ops *self,
+                                      CORE_ADDR addr, int len)
 {
   /* Handle sub-8-byte quantities.  */
   if (len <= 0)
@@ -1672,7 +1627,8 @@ ppc_linux_ranged_break_num_registers (struct target_ops *target)
    success, 1 if hardware breakpoints are not supported or -1 for failure.  */
 
 static int
-ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
+ppc_linux_insert_hw_breakpoint (struct target_ops *self,
+                               struct gdbarch *gdbarch,
                                  struct bp_target_info *bp_tgt)
 {
   struct lwp_info *lp;
@@ -1684,7 +1640,7 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
   p.version = PPC_DEBUG_CURRENT_VERSION;
   p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
   p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
-  p.addr = (uint64_t) bp_tgt->placed_address;
+  p.addr = (uint64_t) (bp_tgt->placed_address = bp_tgt->reqstd_address);
   p.condition_value = 0;
 
   if (bp_tgt->length)
@@ -1702,13 +1658,14 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
     }
 
   ALL_LWPS (lp)
-    hwdebug_insert_point (&p, TIDGET (lp->ptid));
+    hwdebug_insert_point (&p, ptid_get_lwp (lp->ptid));
 
   return 0;
 }
 
 static int
-ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
+ppc_linux_remove_hw_breakpoint (struct target_ops *self,
+                               struct gdbarch *gdbarch,
                                  struct bp_target_info *bp_tgt)
 {
   struct lwp_info *lp;
@@ -1738,7 +1695,7 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
     }
 
   ALL_LWPS (lp)
-    hwdebug_remove_point (&p, TIDGET (lp->ptid));
+    hwdebug_remove_point (&p, ptid_get_lwp (lp->ptid));
 
   return 0;
 }
@@ -1781,7 +1738,7 @@ ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
   p.condition_value = 0;
 
   ALL_LWPS (lp)
-    hwdebug_insert_point (&p, TIDGET (lp->ptid));
+    hwdebug_insert_point (&p, ptid_get_lwp (lp->ptid));
 
   return 0;
 }
@@ -1809,7 +1766,7 @@ ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
   p.condition_value = 0;
 
   ALL_LWPS (lp)
-    hwdebug_remove_point (&p, TIDGET (lp->ptid));
+    hwdebug_remove_point (&p, ptid_get_lwp (lp->ptid));
 
   return 0;
 }
@@ -1819,7 +1776,7 @@ static int
 can_use_watchpoint_cond_accel (void)
 {
   struct thread_points *p;
-  int tid = TIDGET (inferior_ptid);
+  int tid = ptid_get_lwp (inferior_ptid);
   int cnt = hwdebug_info.num_condition_regs, i;
   CORE_ADDR tmp_value;
 
@@ -2011,7 +1968,8 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond,
    the condition expression, thus only triggering the watchpoint when it is
    true.  */
 static int
-ppc_linux_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw,
+ppc_linux_can_accel_watchpoint_condition (struct target_ops *self,
+                                         CORE_ADDR addr, int len, int rw,
                                          struct expression *cond)
 {
   CORE_ADDR data_value;
@@ -2073,7 +2031,8 @@ create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr,
 }
 
 static int
-ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
+ppc_linux_insert_watchpoint (struct target_ops *self,
+                            CORE_ADDR addr, int len, int rw,
                             struct expression *cond)
 {
   struct lwp_info *lp;
@@ -2086,7 +2045,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
       create_watchpoint_request (&p, addr, len, rw, cond, 1);
 
       ALL_LWPS (lp)
-       hwdebug_insert_point (&p, TIDGET (lp->ptid));
+       hwdebug_insert_point (&p, ptid_get_lwp (lp->ptid));
 
       ret = 0;
     }
@@ -2130,7 +2089,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
       saved_dabr_value = dabr_value;
 
       ALL_LWPS (lp)
-       if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (lp->ptid), 0,
+       if (ptrace (PTRACE_SET_DEBUGREG, ptid_get_lwp (lp->ptid), 0,
                    saved_dabr_value) < 0)
          return -1;
 
@@ -2141,7 +2100,8 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
 }
 
 static int
-ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
+ppc_linux_remove_watchpoint (struct target_ops *self,
+                            CORE_ADDR addr, int len, int rw,
                             struct expression *cond)
 {
   struct lwp_info *lp;
@@ -2154,7 +2114,7 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
       create_watchpoint_request (&p, addr, len, rw, cond, 0);
 
       ALL_LWPS (lp)
-       hwdebug_remove_point (&p, TIDGET (lp->ptid));
+       hwdebug_remove_point (&p, ptid_get_lwp (lp->ptid));
 
       ret = 0;
     }
@@ -2162,7 +2122,7 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
     {
       saved_dabr_value = 0;
       ALL_LWPS (lp)
-       if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (lp->ptid), 0,
+       if (ptrace (PTRACE_SET_DEBUGREG, ptid_get_lwp (lp->ptid), 0,
                    saved_dabr_value) < 0)
          return -1;
 
@@ -2175,7 +2135,7 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
 static void
 ppc_linux_new_thread (struct lwp_info *lp)
 {
-  int tid = TIDGET (lp->ptid);
+  int tid = ptid_get_lwp (lp->ptid);
 
   if (have_ptrace_hwdebug_interface ())
     {
@@ -2214,7 +2174,7 @@ static void
 ppc_linux_thread_exit (struct thread_info *tp, int silent)
 {
   int i;
-  int tid = TIDGET (tp->ptid);
+  int tid = ptid_get_lwp (tp->ptid);
   struct hw_break_tuple *hw_breaks;
   struct thread_points *t = NULL, *p;
 
@@ -2263,7 +2223,7 @@ ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
       /* The index (or slot) of the *point is passed in the si_errno field.  */
       int slot = siginfo.si_errno;
 
-      t = hwdebug_find_thread_points_by_tid (TIDGET (inferior_ptid), 0);
+      t = hwdebug_find_thread_points_by_tid (ptid_get_lwp (inferior_ptid), 0);
 
       /* Find out if this *point is a hardware breakpoint.
         If so, we should return 0.  */
@@ -2283,10 +2243,10 @@ ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
 }
 
 static int
-ppc_linux_stopped_by_watchpoint (void)
+ppc_linux_stopped_by_watchpoint (struct target_ops *ops)
 {
   CORE_ADDR addr;
-  return ppc_linux_stopped_data_address (&current_target, &addr);
+  return ppc_linux_stopped_data_address (ops, &addr);
 }
 
 static int
@@ -2335,11 +2295,11 @@ ppc_linux_store_inferior_registers (struct target_ops *ops,
                                    struct regcache *regcache, int regno)
 {
   /* Overload thread id onto process id.  */
-  int tid = TIDGET (inferior_ptid);
+  int tid = ptid_get_lwp (inferior_ptid);
 
   /* No thread id, just use process id.  */
   if (tid == 0)
-    tid = PIDGET (inferior_ptid);
+    tid = ptid_get_pid (inferior_ptid);
 
   if (regno >= 0)
     store_register (regcache, tid, regno);
@@ -2401,13 +2361,13 @@ ppc_linux_target_wordsize (void)
 #ifdef __powerpc64__
   long msr;
 
-  int tid = TIDGET (inferior_ptid);
+  int tid = ptid_get_lwp (inferior_ptid);
   if (tid == 0)
-    tid = PIDGET (inferior_ptid);
+    tid = ptid_get_pid (inferior_ptid);
 
   errno = 0;
   msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0);
-  if (errno == 0 && msr < 0)
+  if (errno == 0 && ppc64_64bit_inferior_p (msr))
     wordsize = 8;
 #endif
 
@@ -2445,9 +2405,9 @@ ppc_linux_read_description (struct target_ops *ops)
   int isa205 = 0;
   int cell = 0;
 
-  int tid = TIDGET (inferior_ptid);
+  int tid = ptid_get_lwp (inferior_ptid);
   if (tid == 0)
-    tid = PIDGET (inferior_ptid);
+    tid = ptid_get_pid (inferior_ptid);
 
   if (have_ptrace_getsetevrregs)
     {