daily update
[deliverable/binutils-gdb.git] / gdb / ppc-linux-nat.c
index f7c5bf55eb0b131a545ce1c8f2a0225d56b0c6ce..0c5563ee3987fa5693b8bfb0bea38e62bb9c11e9 100644 (file)
@@ -1,7 +1,8 @@
 /* PPC GNU/Linux native support.
 
    Copyright (C) 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -41,7 +42,7 @@
 #include <sys/procfs.h>
 #include <sys/ptrace.h>
 
-/* Prototypes for supply_gregset etc. */
+/* Prototypes for supply_gregset etc.  */
 #include "gregset.h"
 #include "ppc-tdep.h"
 #include "ppc-linux-tdep.h"
 
 struct ppc_debug_info
 {
-        uint32_t version;               /* Only version 1 exists to date */
+        uint32_t version;               /* Only version 1 exists to date */
         uint32_t num_instruction_bps;
         uint32_t num_data_bps;
         uint32_t num_condition_regs;
         uint32_t data_bp_alignment;
-        uint32_t sizeof_condition;      /* size of the DVC register */
+        uint32_t sizeof_condition;      /* size of the DVC register */
         uint64_t features;
 };
 
@@ -204,7 +205,7 @@ struct ppc_hw_breakpoint
 
    There are 32 vector registers 16 bytes longs, plus a VSCR register
    which is only 4 bytes long, but is fetched as a 16 bytes
-   quantity. Up to here we have the elf_vrregset_t structure.
+   quantity.  Up to here we have the elf_vrregset_t structure.
    Appended to this there is space for the VRSAVE register: 4 bytes.
    Even though this vrsave register is not included in the regset
    typedef, it is handled by the ptrace requests.
@@ -324,10 +325,14 @@ PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
 PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_R13, PT_R14, PT_R15,
 PT_R16, PT_R17, PT_R18, PT_R19, PT_R20, PT_R21, PT_R22, PT_R23,
 PT_R24, PT_R25, PT_R26, PT_R27, PT_R28, PT_R29, PT_R30, PT_R31,
-PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6, PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14,
-PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22, PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30,
-PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38, PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46,
-PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54, PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
+PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6,
+PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14,
+PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22,
+PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30,
+PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38,
+PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46,
+PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54,
+PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
 PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */
 /* *INDENT_ON * */
 
@@ -340,7 +345,7 @@ ppc_register_u_addr (struct gdbarch *gdbarch, int regno)
      interface, and not the wordsize of the program's ABI.  */
   int wordsize = sizeof (long);
 
-  /* General purpose registers occupy 1 slot each in the buffer */
+  /* General purpose registers occupy 1 slot each in the buffer */
   if (regno >= tdep->ppc_gp0_regnum 
       && regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
     u_addr = ((regno - tdep->ppc_gp0_regnum + PT_R0) * wordsize);
@@ -353,7 +358,7 @@ ppc_register_u_addr (struct gdbarch *gdbarch, int regno)
       && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
     u_addr = (PT_FPR0 * wordsize) + ((regno - tdep->ppc_fp0_regnum) * 8);
 
-  /* UISA special purpose registers: 1 slot each */
+  /* UISA special purpose registers: 1 slot each */
   if (regno == gdbarch_pc_regnum (gdbarch))
     u_addr = PT_NIP * wordsize;
   if (regno == tdep->ppc_lr_regnum)
@@ -458,7 +463,8 @@ fetch_altivec_register (struct regcache *regcache, int tid, int regno)
     offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
   
   regcache_raw_supply (regcache, regno,
-                      regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset);
+                      regs + (regno
+                              - tdep->ppc_vr0_regnum) * vrregsize + offset);
 }
 
 /* Fetch the top 32 bits of TID's general-purpose registers and the
@@ -542,7 +548,7 @@ fetch_register (struct regcache *regcache, int tid, int regno)
   /* 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. */
+  unsigned int offset;         /* Offset of registers within the u area.  */
   char buf[MAX_REGISTER_SIZE];
 
   if (altivec_register_p (gdbarch, regno))
@@ -854,10 +860,10 @@ static void
 ppc_linux_fetch_inferior_registers (struct target_ops *ops,
                                    struct regcache *regcache, int regno)
 {
-  /* Overload thread id onto process id */
+  /* Overload thread id onto process id */
   int tid = TIDGET (inferior_ptid);
 
-  /* No thread id, just use process id */
+  /* No thread id, just use process id */
   if (tid == 0)
     tid = PIDGET (inferior_ptid);
 
@@ -867,7 +873,7 @@ ppc_linux_fetch_inferior_registers (struct target_ops *ops,
     fetch_register (regcache, tid, regno);
 }
 
-/* Store one VSX register. */
+/* Store one VSX register.  */
 static void
 store_vsx_register (const struct regcache *regcache, int tid, int regno)
 {
@@ -877,7 +883,7 @@ store_vsx_register (const struct regcache *regcache, int tid, int regno)
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
 
-  ret = ptrace (PTRACE_SETVSXREGS, tid, 0, &regs);
+  ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
   if (ret < 0)
     {
       if (errno == EIO)
@@ -896,7 +902,7 @@ store_vsx_register (const struct regcache *regcache, int tid, int regno)
     perror_with_name (_("Unable to store VSX register"));
 }
 
-/* Store one register. */
+/* Store one register.  */
 static void
 store_altivec_register (const struct regcache *regcache, int tid, int regno)
 {
@@ -924,7 +930,8 @@ store_altivec_register (const struct regcache *regcache, int tid, int regno)
     offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
 
   regcache_raw_collect (regcache, regno,
-                       regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset);
+                       regs + (regno
+                               - tdep->ppc_vr0_regnum) * vrregsize + offset);
 
   ret = ptrace (PTRACE_SETVRREGS, tid, 0, &regs);
   if (ret < 0)
@@ -1412,7 +1419,8 @@ have_ptrace_booke_interface (void)
        {
          have_ptrace_booke_interface = 1;
          max_slots_number = booke_debug_info.num_instruction_bps
-           + booke_debug_info.num_data_bps + booke_debug_info.num_condition_regs;
+           + booke_debug_info.num_data_bps
+           + booke_debug_info.num_condition_regs;
        }
       else
        {
@@ -1463,9 +1471,9 @@ ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot)
       int tid;
       ptid_t ptid = inferior_ptid;
 
-      /* 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.  */
+      /* 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);
       if (tid == 0)
        tid = PIDGET (ptid);
@@ -1489,10 +1497,17 @@ ppc_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
      to determine the hardcoded watchable region for watchpoints.  */
   if (have_ptrace_booke_interface ())
     {
-      if (booke_debug_info.data_bp_alignment
-         && (addr + len > (addr & ~(booke_debug_info.data_bp_alignment - 1))
-             + booke_debug_info.data_bp_alignment))
-         return 0;
+      /* DAC-based processors (i.e., embedded 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 takes two hardware watchpoints though.  */
+      if (len > 1
+         && booke_debug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE)
+       return 2;
+      else if (booke_debug_info.data_bp_alignment
+              && (addr + len > (addr & ~(booke_debug_info.data_bp_alignment - 1))
+                  + booke_debug_info.data_bp_alignment))
+       return 0;
     }
   /* addr+len must fall in the 8 byte watchable region for DABR-based
      processors (i.e., server processors).  Without the new BookE ptrace
@@ -1508,14 +1523,14 @@ ppc_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 }
 
 /* This function compares two ppc_hw_breakpoint structs field-by-field.  */
-static inline int
+static int
 booke_cmp_hw_point (struct ppc_hw_breakpoint *a, struct ppc_hw_breakpoint *b)
 {
-  return (a->trigger_type       == b->trigger_type
-         && a->addr_mode       == b->addr_mode
-         && a->condition_mode  == b->condition_mode
-         && a->addr            == b->addr
-         && a->addr2           == b->addr2
+  return (a->trigger_type == b->trigger_type
+         && a->addr_mode == b->addr_mode
+         && a->condition_mode == b->condition_mode
+         && a->addr == b->addr
+         && a->addr2 == b->addr2
          && a->condition_value == b->condition_value);
 }
 
@@ -1540,7 +1555,8 @@ booke_find_thread_points_by_tid (int tid, int alloc_new)
   if (alloc_new)
     {
       t = xmalloc (sizeof (struct thread_points));
-      t->hw_breaks = xzalloc (max_slots_number * sizeof (struct hw_break_tuple));
+      t->hw_breaks
+       = xzalloc (max_slots_number * sizeof (struct hw_break_tuple));
       t->tid = tid;
       VEC_safe_push (thread_points_p, ppc_threads, t);
     }
@@ -1614,7 +1630,8 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid)
   errno = 0;
   if (ptrace (PPC_PTRACE_DELHWDEBUG, tid, 0, hw_breaks[i].slot) < 0)
     if (errno != ENOENT)
-      perror_with_name (_("Unexpected error deleting breakpoint or watchpoint"));
+      perror_with_name (_("Unexpected error deleting "
+                         "breakpoint or watchpoint"));
 
   xfree (hw_breaks[i].hw_break);
   hw_breaks[i].hw_break = NULL;
@@ -1631,12 +1648,12 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
   if (!have_ptrace_booke_interface ())
     return -1;
 
-  p.version         = PPC_DEBUG_CURRENT_VERSION;
-  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
-  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
-  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
-  p.addr            = (uint64_t) bp_tgt->placed_address;
-  p.addr2           = 0;
+  p.version = PPC_DEBUG_CURRENT_VERSION;
+  p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
+  p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+  p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr = (uint64_t) bp_tgt->placed_address;
+  p.addr2 = 0;
   p.condition_value = 0;
 
   ALL_LWPS (lp, ptid)
@@ -1656,12 +1673,12 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
   if (!have_ptrace_booke_interface ())
     return -1;
 
-  p.version         = PPC_DEBUG_CURRENT_VERSION;
-  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
-  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
-  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
-  p.addr            = (uint64_t) bp_tgt->placed_address;
-  p.addr2           = 0;
+  p.version = PPC_DEBUG_CURRENT_VERSION;
+  p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
+  p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+  p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr = (uint64_t) bp_tgt->placed_address;
+  p.addr2 = 0;
   p.condition_value = 0;
 
   ALL_LWPS (lp, ptid)
@@ -1685,8 +1702,252 @@ get_trigger_type (int rw)
   return t;
 }
 
+/* Check whether we have at least one free DVC register.  */
+static int
+can_use_watchpoint_cond_accel (void)
+{
+  struct thread_points *p;
+  int tid = TIDGET (inferior_ptid);
+  int cnt = booke_debug_info.num_condition_regs, i;
+  CORE_ADDR tmp_value;
+
+  if (!have_ptrace_booke_interface () || cnt == 0)
+    return 0;
+
+  p = booke_find_thread_points_by_tid (tid, 0);
+
+  if (p)
+    {
+      for (i = 0; i < max_slots_number; i++)
+       if (p->hw_breaks[i].hw_break != NULL
+           && (p->hw_breaks[i].hw_break->condition_mode
+               != PPC_BREAKPOINT_CONDITION_NONE))
+         cnt--;
+
+      /* There are no available slots now.  */
+      if (cnt <= 0)
+       return 0;
+    }
+
+  return 1;
+}
+
+/* Calculate the enable bits and the contents of the Data Value Compare
+   debug register present in BookE processors.
+
+   ADDR is the address to be watched, LEN is the length of watched data
+   and DATA_VALUE is the value which will trigger the watchpoint.
+   On exit, CONDITION_MODE will hold the enable bits for the DVC, and
+   CONDITION_VALUE will hold the value which should be put in the
+   DVC register.  */
+static void
+calculate_dvc (CORE_ADDR addr, int len, CORE_ADDR data_value,
+              uint32_t *condition_mode, uint64_t *condition_value)
+{
+  int i, num_byte_enable, align_offset, num_bytes_off_dvc,
+      rightmost_enabled_byte;
+  CORE_ADDR addr_end_data, addr_end_dvc;
+
+  /* The DVC register compares bytes within fixed-length windows which
+     are word-aligned, with length equal to that of the DVC register.
+     We need to calculate where our watch region is relative to that
+     window and enable comparison of the bytes which fall within it.  */
+
+  align_offset = addr % booke_debug_info.sizeof_condition;
+  addr_end_data = addr + len;
+  addr_end_dvc = (addr - align_offset
+                 + booke_debug_info.sizeof_condition);
+  num_bytes_off_dvc = (addr_end_data > addr_end_dvc)?
+                        addr_end_data - addr_end_dvc : 0;
+  num_byte_enable = len - num_bytes_off_dvc;
+  /* Here, bytes are numbered from right to left.  */
+  rightmost_enabled_byte = (addr_end_data < addr_end_dvc)?
+                             addr_end_dvc - addr_end_data : 0;
+
+  *condition_mode = PPC_BREAKPOINT_CONDITION_AND;
+  for (i = 0; i < num_byte_enable; i++)
+    *condition_mode
+      |= PPC_BREAKPOINT_CONDITION_BE (i + rightmost_enabled_byte);
+
+  /* Now we need to match the position within the DVC of the comparison
+     value with where the watch region is relative to the window
+     (i.e., the ALIGN_OFFSET).  */
+
+  *condition_value = ((uint64_t) data_value >> num_bytes_off_dvc * 8
+                     << rightmost_enabled_byte * 8);
+}
+
+/* Return the number of memory locations that need to be accessed to
+   evaluate the expression which generated the given value chain.
+   Returns -1 if there's any register access involved, or if there are
+   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)
+{
+  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
+     expression a*b+c has five subexpressions: a, b, a*b, c, and
+     a*b+c.)  GDB's values hold almost enough information to establish
+     the criteria given above --- they identify memory lvalues,
+     register lvalues, computed values, etcetera.  So we can evaluate
+     the expression, and then scan the chain of values that leaves
+     behind to determine the memory locations involved in the evaluation
+     of an expression.
+
+     However, I don't think that the values returned by inferior
+     function calls are special in any way.  So this function may not
+     notice that an expression contains an inferior function call.
+     FIXME.  */
+
+  for (; v; v = value_next (v))
+    {
+      /* Constants and values from the history are fine.  */
+      if (VALUE_LVAL (v) == not_lval || deprecated_value_modifiable (v) == 0)
+       continue;
+      else if (VALUE_LVAL (v) == lval_memory)
+       {
+         /* A lazy memory lvalue is one that GDB never needed to fetch;
+            we either just used its address (e.g., `a' in `a.b') or
+            we never needed it at all (e.g., `a' in `a,b').  */
+         if (!value_lazy (v))
+           found_memory_cnt++;
+       }
+      /* Other kinds of values are not fine.  */
+      else
+       return -1;
+    }
+
+  return found_memory_cnt;
+}
+
+/* Verifies whether the expression COND can be implemented using the
+   DVC (Data Value Compare) register in BookE processors.  The expression
+   must test the watch value for equality with a constant expression.
+   If the function returns 1, DATA_VALUE will contain the constant against
+   which the watch value should be compared.  */
+static int
+check_condition (CORE_ADDR watch_addr, struct expression *cond,
+                CORE_ADDR *data_value)
+{
+  int pc = 1, num_accesses_left, num_accesses_right;
+  struct value *left_val, *right_val, *left_chain, *right_chain;
+
+  if (cond->elts[0].opcode != BINOP_EQUAL)
+    return 0;
+
+  fetch_subexp_value (cond, &pc, &left_val, NULL, &left_chain);
+  num_accesses_left = num_memory_accesses (left_chain);
+
+  if (left_val == NULL || num_accesses_left < 0)
+    {
+      free_value_chain (left_chain);
+
+      return 0;
+    }
+
+  fetch_subexp_value (cond, &pc, &right_val, NULL, &right_chain);
+  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;
+    }
+
+  if (num_accesses_left == 1 && num_accesses_right == 0
+      && VALUE_LVAL (left_val) == lval_memory
+      && value_address (left_val) == watch_addr)
+    *data_value = value_as_long (right_val);
+  else if (num_accesses_left == 0 && num_accesses_right == 1
+          && VALUE_LVAL (right_val) == lval_memory
+          && value_address (right_val) == watch_addr)
+    *data_value = value_as_long (left_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 1;
+}
+
+/* Return non-zero if the target is capable of using hardware to evaluate
+   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,
+                                         struct expression *cond)
+{
+  CORE_ADDR data_value;
+
+  return (have_ptrace_booke_interface ()
+         && booke_debug_info.num_condition_regs > 0
+         && check_condition (addr, cond, &data_value));
+}
+
+/* Set up P with the parameters necessary to request a watchpoint covering
+   LEN bytes starting at ADDR and if possible with condition expression COND
+   evaluated by hardware.  INSERT tells if we are creating a request for
+   inserting or removing the watchpoint.  */
+
+static void
+create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr,
+                          int len, int rw, struct expression *cond,
+                          int insert)
+{
+  if (len == 1)
+    {
+      int use_condition;
+      CORE_ADDR data_value;
+
+      use_condition = (insert? can_use_watchpoint_cond_accel ()
+                       : booke_debug_info.num_condition_regs > 0);
+      if (cond && use_condition && check_condition (addr, cond, &data_value))
+       calculate_dvc (addr, len, data_value, &p->condition_mode,
+                      &p->condition_value);
+      else
+       {
+         p->condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+         p->condition_value = 0;
+       }
+
+      p->addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+      p->addr2 = 0;
+    }
+  else
+    {
+      p->addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+      p->condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+      p->condition_value = 0;
+
+      /* The watchpoint will trigger if the address of the memory access is
+        within the defined range, as follows: p->addr <= address < p->addr2.
+
+        Note that the above sentence just documents how ptrace interprets
+        its arguments; the watchpoint is set to watch the range defined by
+        the user _inclusively_, as specified by the user interface.  */
+      p->addr2 = (uint64_t) addr + len;
+    }
+
+  p->version = PPC_DEBUG_CURRENT_VERSION;
+  p->trigger_type = get_trigger_type (rw);
+  p->addr = (uint64_t) addr;
+}
+
 static int
-ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw)
+ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
+                            struct expression *cond)
 {
   struct lwp_info *lp;
   ptid_t ptid;
@@ -1696,13 +1957,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw)
     {
       struct ppc_hw_breakpoint p;
 
-      p.version         = PPC_DEBUG_CURRENT_VERSION;
-      p.trigger_type    = get_trigger_type (rw);
-      p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
-      p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
-      p.addr            = (uint64_t) addr;
-      p.addr2           = 0;
-      p.condition_value = 0;
+      create_watchpoint_request (&p, addr, len, rw, cond, 1);
 
       ALL_LWPS (lp, ptid)
        booke_insert_point (&p, TIDGET (ptid));
@@ -1718,14 +1973,14 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw)
        {
          /* PowerPC 440 requires only the read/write flags to be passed
             to the kernel.  */
-         read_mode  = 1;
+         read_mode = 1;
          write_mode = 2;
        }
       else
        {
          /* PowerPC 970 and other DABR-based processors are required to pass
             the Breakpoint Translation bit together with the flags.  */
-         read_mode  = 5;
+         read_mode = 5;
          write_mode = 6;
        }
 
@@ -1749,7 +2004,8 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw)
       saved_dabr_value = dabr_value;
 
       ALL_LWPS (lp, ptid)
-       if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0, saved_dabr_value) < 0)
+       if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0,
+                   saved_dabr_value) < 0)
          return -1;
 
       ret = 0;
@@ -1759,7 +2015,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 (CORE_ADDR addr, int len, int rw,
+                            struct expression *cond)
 {
   struct lwp_info *lp;
   ptid_t ptid;
@@ -1769,13 +2026,7 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw)
     {
       struct ppc_hw_breakpoint p;
 
-      p.version         = PPC_DEBUG_CURRENT_VERSION;
-      p.trigger_type    = get_trigger_type (rw);
-      p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
-      p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
-      p.addr            = (uint64_t) addr;
-      p.addr2           = 0;
-      p.condition_value = 0;
+      create_watchpoint_request (&p, addr, len, rw, cond, 0);
 
       ALL_LWPS (lp, ptid)
        booke_remove_point (&p, TIDGET (ptid));
@@ -1786,7 +2037,8 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw)
     {
       saved_dabr_value = 0;
       ALL_LWPS (lp, ptid)
-       if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0, saved_dabr_value) < 0)
+       if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0,
+                   saved_dabr_value) < 0)
          return -1;
 
       ret = 0;
@@ -1809,11 +2061,11 @@ ppc_linux_new_thread (ptid_t ptid)
       if (VEC_empty (thread_points_p, ppc_threads))
        return;
 
-      /* Get a list of breakpoints from any thread. */
+      /* Get a list of breakpoints from any thread.  */
       p = VEC_last (thread_points_p, ppc_threads);
       hw_breaks = p->hw_breaks;
 
-      /* Copy that thread's breakpoints and watchpoints to the new thread. */
+      /* Copy that thread's breakpoints and watchpoints to the new thread.  */
       for (i = 0; i < max_slots_number; i++)
        if (hw_breaks[i].hw_break)
          booke_insert_point (hw_breaks[i].hw_break, tid);
@@ -1917,7 +2169,7 @@ ppc_linux_watchpoint_addr_within_range (struct target_ops *target,
 
   addr &= ~mask;
 
-  /* Check whether [start, start+length-1] intersects [addr, addr+mask]. */
+  /* Check whether [start, start+length-1] intersects [addr, addr+mask].  */
   return start <= addr + mask && start + length - 1 >= addr;
 }
 
@@ -1925,10 +2177,10 @@ static void
 ppc_linux_store_inferior_registers (struct target_ops *ops,
                                    struct regcache *regcache, int regno)
 {
-  /* Overload thread id onto process id */
+  /* Overload thread id onto process id */
   int tid = TIDGET (inferior_ptid);
 
-  /* No thread id, just use process id */
+  /* No thread id, just use process id */
   if (tid == 0)
     tid = PIDGET (inferior_ptid);
 
@@ -1940,7 +2192,7 @@ ppc_linux_store_inferior_registers (struct target_ops *ops,
 
 /* Functions for transferring registers between a gregset_t or fpregset_t
    (see sys/ucontext.h) and gdb's regcache.  The word size is that used
-   by the ptrace interface, not the current program's ABI.  eg. If a
+   by the ptrace interface, not the current program's ABI.  Eg. if a
    powerpc64-linux gdb is being used to debug a powerpc32-linux app, we
    read or write 64-bit gregsets.  This is to suit the host libthread_db.  */
 
@@ -2080,7 +2332,7 @@ ppc_linux_read_description (struct target_ops *ops)
     }
 
   /* Power ISA 2.05 (implemented by Power 6 and newer processors) increases
-     the FPSCR from 32 bits to 64 bits. Even though Power 7 supports this
+     the FPSCR from 32 bits to 64 bits.  Even though Power 7 supports this
      ISA version, it doesn't have PPC_FEATURE_ARCH_2_05 set, only
      PPC_FEATURE_ARCH_2_06.  Since for now the only bits used in the higher
      half of the register are for Decimal Floating Point, we check if that
@@ -2098,7 +2350,8 @@ ppc_linux_read_description (struct target_ops *ops)
       else if (vsx)
        return isa205? tdesc_powerpc_isa205_vsx64l : tdesc_powerpc_vsx64l;
       else if (altivec)
-       return isa205? tdesc_powerpc_isa205_altivec64l : tdesc_powerpc_altivec64l;
+       return isa205
+         ? tdesc_powerpc_isa205_altivec64l : tdesc_powerpc_altivec64l;
 
       return isa205? tdesc_powerpc_isa205_64l : tdesc_powerpc_64l;
     }
@@ -2137,6 +2390,8 @@ _initialize_ppc_linux_nat (void)
   t->to_stopped_by_watchpoint = ppc_linux_stopped_by_watchpoint;
   t->to_stopped_data_address = ppc_linux_stopped_data_address;
   t->to_watchpoint_addr_within_range = ppc_linux_watchpoint_addr_within_range;
+  t->to_can_accel_watchpoint_condition
+    = ppc_linux_can_accel_watchpoint_condition;
 
   t->to_read_description = ppc_linux_read_description;
   t->to_auxv_parse = ppc_linux_auxv_parse;
This page took 0.031238 seconds and 4 git commands to generate.