Adjust Value.location for lval_register
[deliverable/binutils-gdb.git] / gdb / ppc-linux-nat.c
index 6e8994e9852d839ee28787647684cad4b395b4a0..84c14a1ae9efdd381748e704404d84e8afb93108 100644 (file)
@@ -1,6 +1,6 @@
 /* PPC GNU/Linux native support.
 
-   Copyright (C) 1988-2014 Free Software Foundation, Inc.
+   Copyright (C) 1988-2016 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 <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 <stdint.h>
 #include <sys/types.h>
 #include <signal.h>
 #include <sys/user.h>
@@ -37,7 +33,7 @@
 #include "gdb_wait.h"
 #include <fcntl.h>
 #include <sys/procfs.h>
-#include <sys/ptrace.h>
+#include "nat/gdb_ptrace.h"
 
 /* Prototypes for supply_gregset etc.  */
 #include "gregset.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.  */
@@ -1445,7 +1391,7 @@ have_ptrace_hwdebug_interface (void)
 
 static int
 ppc_linux_can_use_hw_breakpoint (struct target_ops *self,
-                                int type, int cnt, int ot)
+                                enum bptype type, int cnt, int ot)
 {
   int total_hw_wp, total_hw_bp;
 
@@ -1582,9 +1528,8 @@ hwdebug_find_thread_points_by_tid (int tid, int alloc_new)
      if the wanted one does not exist?  */
   if (alloc_new)
     {
-      t = xmalloc (sizeof (struct thread_points));
-      t->hw_breaks
-       = xzalloc (max_slots_number * sizeof (struct hw_break_tuple));
+      t = XNEW (struct thread_points);
+      t->hw_breaks = XCNEWVEC (struct hw_break_tuple, max_slots_number);
       t->tid = tid;
       VEC_safe_push (thread_points_p, ppc_threads, t);
     }
@@ -1600,7 +1545,7 @@ hwdebug_insert_point (struct ppc_hw_breakpoint *b, int tid)
 {
   int i;
   long slot;
-  struct ppc_hw_breakpoint *p = xmalloc (sizeof (struct ppc_hw_breakpoint));
+  struct ppc_hw_breakpoint *p = XNEW (struct ppc_hw_breakpoint);
   struct hw_break_tuple *hw_breaks;
   struct cleanup *c = make_cleanup (xfree, p);
   struct thread_points *t;
@@ -1692,7 +1637,7 @@ ppc_linux_insert_hw_breakpoint (struct target_ops *self,
   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)
@@ -1753,13 +1698,13 @@ ppc_linux_remove_hw_breakpoint (struct target_ops *self,
 }
 
 static int
-get_trigger_type (int rw)
+get_trigger_type (enum target_hw_bp_type type)
 {
   int t;
 
-  if (rw == hw_read)
+  if (type == hw_read)
     t = PPC_BREAKPOINT_TRIGGER_READ;
-  else if (rw == hw_write)
+  else if (type == hw_write)
     t = PPC_BREAKPOINT_TRIGGER_WRITE;
   else
     t = PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE;
@@ -1774,7 +1719,7 @@ get_trigger_type (int rw)
 
 static int
 ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
-                                 CORE_ADDR mask, int rw)
+                                 CORE_ADDR mask, enum target_hw_bp_type rw)
 {
   struct lwp_info *lp;
   struct ppc_hw_breakpoint p;
@@ -1802,7 +1747,7 @@ ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
 
 static int
 ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
-                                 CORE_ADDR mask, int rw)
+                                 CORE_ADDR mask, enum target_hw_bp_type rw)
 {
   struct lwp_info *lp;
   struct ppc_hw_breakpoint p;
@@ -2038,8 +1983,8 @@ ppc_linux_can_accel_watchpoint_condition (struct target_ops *self,
 
 static void
 create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr,
-                          int len, int rw, struct expression *cond,
-                          int insert)
+                          int len, enum target_hw_bp_type type,
+                          struct expression *cond, int insert)
 {
   if (len == 1
       || !(hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE))
@@ -2078,13 +2023,13 @@ create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr,
     }
 
   p->version = PPC_DEBUG_CURRENT_VERSION;
-  p->trigger_type = get_trigger_type (rw);
+  p->trigger_type = get_trigger_type (type);
   p->addr = (uint64_t) addr;
 }
 
 static int
-ppc_linux_insert_watchpoint (struct target_ops *self,
-                            CORE_ADDR addr, int len, int rw,
+ppc_linux_insert_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
+                            enum target_hw_bp_type type,
                             struct expression *cond)
 {
   struct lwp_info *lp;
@@ -2094,7 +2039,7 @@ ppc_linux_insert_watchpoint (struct target_ops *self,
     {
       struct ppc_hw_breakpoint p;
 
-      create_watchpoint_request (&p, addr, len, rw, cond, 1);
+      create_watchpoint_request (&p, addr, len, type, cond, 1);
 
       ALL_LWPS (lp)
        hwdebug_insert_point (&p, ptid_get_lwp (lp->ptid));
@@ -2122,7 +2067,7 @@ ppc_linux_insert_watchpoint (struct target_ops *self,
        }
 
       dabr_value = addr & ~(read_mode | write_mode);
-      switch (rw)
+      switch (type)
        {
          case hw_read:
            /* Set read and translate bits.  */
@@ -2152,8 +2097,8 @@ ppc_linux_insert_watchpoint (struct target_ops *self,
 }
 
 static int
-ppc_linux_remove_watchpoint (struct target_ops *self,
-                            CORE_ADDR addr, int len, int rw,
+ppc_linux_remove_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
+                            enum target_hw_bp_type type,
                             struct expression *cond)
 {
   struct lwp_info *lp;
@@ -2163,7 +2108,7 @@ ppc_linux_remove_watchpoint (struct target_ops *self,
     {
       struct ppc_hw_breakpoint p;
 
-      create_watchpoint_request (&p, addr, len, rw, cond, 0);
+      create_watchpoint_request (&p, addr, len, type, cond, 0);
 
       ALL_LWPS (lp)
        hwdebug_remove_point (&p, ptid_get_lwp (lp->ptid));
@@ -2419,7 +2364,7 @@ ppc_linux_target_wordsize (void)
 
   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
 
@@ -2474,7 +2419,8 @@ ppc_linux_read_description (struct target_ops *ops)
        perror_with_name (_("Unable to fetch SPE registers"));
     }
 
-  if (have_ptrace_getsetvsxregs)
+  if (have_ptrace_getsetvsxregs
+      && (ppc_linux_get_hwcap () & PPC_FEATURE_HAS_VSX))
     {
       gdb_vsxregset_t vsxregset;
 
@@ -2487,7 +2433,8 @@ ppc_linux_read_description (struct target_ops *ops)
        perror_with_name (_("Unable to fetch VSX registers"));
     }
 
-  if (have_ptrace_getvrregs)
+  if (have_ptrace_getvrregs
+      && (ppc_linux_get_hwcap () & PPC_FEATURE_HAS_ALTIVEC))
     {
       gdb_vrregset_t vrregset;
 
This page took 0.035222 seconds and 4 git commands to generate.