Fix illegal memory accesses trigeered when linking corrupt input files.
[deliverable/binutils-gdb.git] / gdb / ppc-linux-nat.c
index 4b3c78c7ac047e08fa871f4dbff85a61be6ccca8..2cd8792d30c0d01ddfd177d05659f5fa94e1540c 100644 (file)
@@ -1,6 +1,6 @@
 /* PPC GNU/Linux native support.
 
-   Copyright (C) 1988-2013 Free Software Foundation, Inc.
+   Copyright (C) 1988-2018 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 "observable.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,8 @@
 #include "gdb_wait.h"
 #include <fcntl.h>
 #include <sys/procfs.h>
-#include <sys/ptrace.h>
+#include "nat/gdb_ptrace.h"
+#include "inf-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.  */
@@ -177,7 +124,11 @@ struct ppc_hw_breakpoint
         (1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
 #endif /* PPC_PTRACE_GETHWDBGINFO */
 
-
+/* Feature defined on Linux kernel v3.9: DAWR interface, that enables wider
+   watchpoint (up to 512 bytes).  */
+#ifndef PPC_DEBUG_FEATURE_DATA_BP_DAWR
+#define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10
+#endif /* PPC_DEBUG_FEATURE_DATA_BP_DAWR */
 
 /* Similarly for the general-purpose (gp0 -- gp31)
    and floating-point registers (fp0 -- fp31).  */
@@ -408,7 +359,7 @@ fetch_vsx_register (struct regcache *regcache, int tid, int regno)
 {
   int ret;
   gdb_vsxregset_t regs;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
 
@@ -437,7 +388,7 @@ fetch_altivec_register (struct regcache *regcache, int tid, int regno)
   int ret;
   int offset = 0;
   gdb_vrregset_t regs;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
 
@@ -501,7 +452,7 @@ get_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
 static void
 fetch_spe_register (struct regcache *regcache, int tid, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   struct gdb_evrregset_t evrregs;
 
@@ -540,13 +491,13 @@ fetch_spe_register (struct regcache *regcache, int tid, int regno)
 static void
 fetch_register (struct regcache *regcache, int tid, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   /* This isn't really an address.  But ptrace thinks of it as one.  */
   CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
   int bytes_transferred;
   unsigned int offset;         /* Offset of registers within the u area.  */
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[PPC_MAX_REGISTER_SIZE];
 
   if (altivec_register_p (gdbarch, regno))
     {
@@ -632,7 +583,7 @@ static void
 supply_vsxregset (struct regcache *regcache, gdb_vsxregset_t *vsxregsetp)
 {
   int i;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
 
@@ -647,7 +598,7 @@ static void
 supply_vrregset (struct regcache *regcache, gdb_vrregset_t *vrregsetp)
 {
   int i;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
   int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
@@ -717,7 +668,7 @@ fetch_altivec_registers (struct regcache *regcache, int tid)
 static int
 fetch_all_gp_regs (struct regcache *regcache, int tid)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   gdb_gregset_t gregset;
 
@@ -745,7 +696,7 @@ fetch_all_gp_regs (struct regcache *regcache, int tid)
 static void
 fetch_gp_regs (struct regcache *regcache, int tid)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int i;
 
@@ -797,7 +748,7 @@ fetch_all_fp_regs (struct regcache *regcache, int tid)
 static void
 fetch_fp_regs (struct regcache *regcache, int tid)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int i;
 
@@ -816,7 +767,7 @@ static void
 fetch_ppc_registers (struct regcache *regcache, int tid)
 {
   int i;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   fetch_gp_regs (regcache, tid);
@@ -859,12 +810,7 @@ static void
 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);
-
-  /* No thread id, just use process id.  */
-  if (tid == 0)
-    tid = PIDGET (inferior_ptid);
+  pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
 
   if (regno == -1)
     fetch_ppc_registers (regcache, tid);
@@ -878,7 +824,7 @@ store_vsx_register (const struct regcache *regcache, int tid, int regno)
 {
   int ret;
   gdb_vsxregset_t regs;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
 
@@ -908,7 +854,7 @@ store_altivec_register (const struct regcache *regcache, int tid, int regno)
   int ret;
   int offset = 0;
   gdb_vrregset_t regs;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
 
@@ -972,7 +918,7 @@ set_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
 static void
 store_spe_register (const struct regcache *regcache, int tid, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   struct gdb_evrregset_t evrregs;
 
@@ -1027,13 +973,13 @@ store_spe_register (const struct regcache *regcache, int tid, int regno)
 static void
 store_register (const struct regcache *regcache, int tid, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   /* This isn't really an address.  But ptrace thinks of it as one.  */
   CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
   int i;
   size_t bytes_to_transfer;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[PPC_MAX_REGISTER_SIZE];
 
   if (altivec_register_p (gdbarch, regno))
     {
@@ -1104,7 +1050,7 @@ static void
 fill_vsxregset (const struct regcache *regcache, gdb_vsxregset_t *vsxregsetp)
 {
   int i;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
 
@@ -1117,7 +1063,7 @@ static void
 fill_vrregset (const struct regcache *regcache, gdb_vrregset_t *vrregsetp)
 {
   int i;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
   int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
@@ -1193,7 +1139,7 @@ store_altivec_registers (const struct regcache *regcache, int tid)
 static int
 store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   gdb_gregset_t gregset;
 
@@ -1231,7 +1177,7 @@ store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
 static void
 store_gp_regs (const struct regcache *regcache, int tid, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int i;
 
@@ -1293,7 +1239,7 @@ store_all_fp_regs (const struct regcache *regcache, int tid, int regno)
 static void
 store_fp_regs (const struct regcache *regcache, int tid, int regno)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int i;
 
@@ -1312,7 +1258,7 @@ static void
 store_ppc_registers (const struct regcache *regcache, int tid)
 {
   int i;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  
   store_gp_regs (regcache, tid, -1);
@@ -1413,9 +1359,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)
@@ -1440,7 +1386,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,
+                                enum bptype type, int cnt, int ot)
 {
   int total_hw_wp, total_hw_bp;
 
@@ -1468,6 +1415,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;
     }
@@ -1480,9 +1432,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;
@@ -1492,7 +1444,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)
@@ -1504,6 +1457,7 @@ ppc_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
      watchpoints.  */
   if (have_ptrace_hwdebug_interface ())
     {
+      int region_size;
       /* Embedded DAC-based processors, like the PowerPC 440 have ranged
         watchpoints and can watch any access within an arbitrary memory
         region. This is useful to watch arrays and structs, for instance.  It
@@ -1512,11 +1466,17 @@ ppc_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
          && hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE
          && ppc_linux_get_hwcap () & PPC_FEATURE_BOOKE)
        return 2;
+      /* Check if the processor provides DAWR interface.  */
+      if (hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_DAWR)
+       /* DAWR interface allows to watch up to 512 byte wide ranges which
+          can't cross a 512 byte boundary.  */
+       region_size = 512;
+      else
+       region_size = hwdebug_info.data_bp_alignment;
       /* Server processors provide one hardware watchpoint and addr+len should
          fall in the watchable region provided by the ptrace interface.  */
-      if (hwdebug_info.data_bp_alignment
-         && (addr + len > (addr & ~(hwdebug_info.data_bp_alignment - 1))
-             + hwdebug_info.data_bp_alignment))
+      if (region_size
+         && (addr + len > (addr & ~(region_size - 1)) + region_size))
        return 0;
     }
   /* addr+len must fall in the 8 byte watchable region for DABR-based
@@ -1564,9 +1524,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);
     }
@@ -1582,16 +1541,13 @@ 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));
+  gdb::unique_xmalloc_ptr<ppc_hw_breakpoint> p (XDUP (ppc_hw_breakpoint, b));
   struct hw_break_tuple *hw_breaks;
-  struct cleanup *c = make_cleanup (xfree, p);
   struct thread_points *t;
   struct hw_break_tuple *tuple;
 
-  memcpy (p, b, sizeof (struct ppc_hw_breakpoint));
-
   errno = 0;
-  slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p);
+  slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p.get ());
   if (slot < 0)
     perror_with_name (_("Unexpected error setting breakpoint or watchpoint"));
 
@@ -1605,13 +1561,11 @@ hwdebug_insert_point (struct ppc_hw_breakpoint *b, int tid)
     if (hw_breaks[i].hw_break == NULL)
       {
        hw_breaks[i].slot = slot;
-       hw_breaks[i].hw_break = p;
+       hw_breaks[i].hw_break = p.release ();
        break;
       }
 
   gdb_assert (i != max_slots_number);
-
-  discard_cleanups (c);
 }
 
 /* This function is a generic wrapper that is responsible for removing a
@@ -1661,7 +1615,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;
@@ -1673,7 +1628,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)
@@ -1691,13 +1646,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;
@@ -1727,19 +1683,19 @@ 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;
 }
 
 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;
@@ -1754,7 +1710,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;
@@ -1770,7 +1726,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;
 }
@@ -1782,7 +1738,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;
@@ -1798,7 +1754,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;
 }
@@ -1808,7 +1764,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;
 
@@ -1884,10 +1840,9 @@ calculate_dvc (CORE_ADDR addr, int len, CORE_ADDR data_value,
    other kinds of values which are not acceptable in a condition
    expression (e.g., lval_computed or lval_internalvar).  */
 static int
-num_memory_accesses (struct value *v)
+num_memory_accesses (const std::vector<value_ref_ptr> &chain)
 {
   int found_memory_cnt = 0;
-  struct value *head = v;
 
   /* The idea here is that evaluating an expression generates a series
      of values, one holding the value of every subexpression.  (The
@@ -1904,8 +1859,10 @@ num_memory_accesses (struct value *v)
      notice that an expression contains an inferior function call.
      FIXME.  */
 
-  for (; v; v = value_next (v))
+  for (const value_ref_ptr &iter : chain)
     {
+      struct value *v = iter.get ();
+
       /* Constants and values from the history are fine.  */
       if (VALUE_LVAL (v) == not_lval || deprecated_value_modifiable (v) == 0)
        continue;
@@ -1936,31 +1893,23 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond,
                 CORE_ADDR *data_value, int *len)
 {
   int pc = 1, num_accesses_left, num_accesses_right;
-  struct value *left_val, *right_val, *left_chain, *right_chain;
+  struct value *left_val, *right_val;
+  std::vector<value_ref_ptr> left_chain, right_chain;
 
   if (cond->elts[0].opcode != BINOP_EQUAL)
     return 0;
 
-  fetch_subexp_value (cond, &pc, &left_val, NULL, &left_chain);
+  fetch_subexp_value (cond, &pc, &left_val, NULL, &left_chain, 0);
   num_accesses_left = num_memory_accesses (left_chain);
 
   if (left_val == NULL || num_accesses_left < 0)
-    {
-      free_value_chain (left_chain);
-
-      return 0;
-    }
+    return 0;
 
-  fetch_subexp_value (cond, &pc, &right_val, NULL, &right_chain);
+  fetch_subexp_value (cond, &pc, &right_val, NULL, &right_chain, 0);
   num_accesses_right = num_memory_accesses (right_chain);
 
   if (right_val == NULL || num_accesses_right < 0)
-    {
-      free_value_chain (left_chain);
-      free_value_chain (right_chain);
-
-      return 0;
-    }
+    return 0;
 
   if (num_accesses_left == 1 && num_accesses_right == 0
       && VALUE_LVAL (left_val) == lval_memory
@@ -1983,15 +1932,7 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond,
       *len = TYPE_LENGTH (check_typedef (value_type (right_val)));
     }
   else
-    {
-      free_value_chain (left_chain);
-      free_value_chain (right_chain);
-
-      return 0;
-    }
-
-  free_value_chain (left_chain);
-  free_value_chain (right_chain);
+    return 0;
 
   return 1;
 }
@@ -2000,7 +1941,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;
@@ -2017,8 +1959,8 @@ ppc_linux_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw,
 
 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))
@@ -2057,12 +1999,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 (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;
@@ -2072,10 +2015,10 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
     {
       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, TIDGET (lp->ptid));
+       hwdebug_insert_point (&p, ptid_get_lwp (lp->ptid));
 
       ret = 0;
     }
@@ -2100,7 +2043,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
        }
 
       dabr_value = addr & ~(read_mode | write_mode);
-      switch (rw)
+      switch (type)
        {
          case hw_read:
            /* Set read and translate bits.  */
@@ -2119,7 +2062,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;
 
@@ -2130,7 +2073,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,
+                            enum target_hw_bp_type type,
                             struct expression *cond)
 {
   struct lwp_info *lp;
@@ -2140,10 +2084,10 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
     {
       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, TIDGET (lp->ptid));
+       hwdebug_remove_point (&p, ptid_get_lwp (lp->ptid));
 
       ret = 0;
     }
@@ -2151,7 +2095,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;
 
@@ -2164,7 +2108,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 ())
     {
@@ -2203,7 +2147,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;
 
@@ -2252,7 +2196,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.  */
@@ -2272,10 +2216,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
@@ -2323,12 +2267,7 @@ static void
 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);
-
-  /* No thread id, just use process id.  */
-  if (tid == 0)
-    tid = PIDGET (inferior_ptid);
+  pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
 
   if (regno >= 0)
     store_register (regcache, tid, regno);
@@ -2390,13 +2329,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
 
@@ -2434,9 +2373,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)
     {
@@ -2451,7 +2390,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;
 
@@ -2464,7 +2404,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;
 
@@ -2512,8 +2453,6 @@ ppc_linux_read_description (struct target_ops *ops)
   return isa205? tdesc_powerpc_isa205_32l : tdesc_powerpc_32l;
 }
 
-void _initialize_ppc_linux_nat (void);
-
 void
 _initialize_ppc_linux_nat (void)
 {
@@ -2546,7 +2485,7 @@ _initialize_ppc_linux_nat (void)
   t->to_read_description = ppc_linux_read_description;
   t->to_auxv_parse = ppc_linux_auxv_parse;
 
-  observer_attach_thread_exit (ppc_linux_thread_exit);
+  gdb::observers::thread_exit.attach (ppc_linux_thread_exit);
 
   /* Register the target.  */
   linux_nat_add_target (t);
This page took 0.036503 seconds and 4 git commands to generate.