gdb: Use std::min and std::max throughout
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 5176fa056c97540c441e62fc946e4d8975aafc66..5f15780820344ddc5b8623831df72a9fe9468aef 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2015 Free Software Foundation, Inc.
+   Copyright (C) 1986-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -43,7 +43,6 @@
 #include "record-full.h"
 #include "auxv.h"
 
-#include "libbfd.h"            /* for bfd_default_set_arch_mach */
 #include "coff/internal.h"     /* for libcoff.h */
 #include "libcoff.h"           /* for xcoff_data */
 #include "coff/xcoff.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
 
+#include "ax.h"
+#include "ax-gdb.h"
+#include <algorithm>
+
 #include "features/rs6000/powerpc-32.c"
 #include "features/rs6000/powerpc-altivec32.c"
 #include "features/rs6000/powerpc-vsx32.c"
@@ -328,7 +331,7 @@ init_sim_regno_table (struct gdbarch *arch)
     set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum);
   /* spefscr is a special-purpose register, so the code below handles it.  */
 
-#ifdef WITH_SIM
+#ifdef WITH_PPC_SIM
   /* Now handle all special-purpose registers.  Verify that they
      haven't mistakenly been assigned numbers by any of the above
      code.  */
@@ -507,7 +510,8 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  const struct ppc_reg_offsets *offsets = regset->regmap;
+  const struct ppc_reg_offsets *offsets
+    = (const struct ppc_reg_offsets *) regset->regmap;
   size_t offset;
   int regsize;
 
@@ -519,27 +523,31 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
       for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
           i < tdep->ppc_gp0_regnum + ppc_num_gprs;
           i++, offset += gpr_size)
-       ppc_supply_reg (regcache, i, gregs, offset, gpr_size);
+       ppc_supply_reg (regcache, i, (const gdb_byte *) gregs, offset,
+                       gpr_size);
 
       ppc_supply_reg (regcache, gdbarch_pc_regnum (gdbarch),
-                     gregs, offsets->pc_offset, gpr_size);
+                     (const gdb_byte *) gregs, offsets->pc_offset, gpr_size);
       ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
-                     gregs, offsets->ps_offset, gpr_size);
+                     (const gdb_byte *) gregs, offsets->ps_offset, gpr_size);
       ppc_supply_reg (regcache, tdep->ppc_lr_regnum,
-                     gregs, offsets->lr_offset, gpr_size);
+                     (const gdb_byte *) gregs, offsets->lr_offset, gpr_size);
       ppc_supply_reg (regcache, tdep->ppc_ctr_regnum,
-                     gregs, offsets->ctr_offset, gpr_size);
+                     (const gdb_byte *) gregs, offsets->ctr_offset, gpr_size);
       ppc_supply_reg (regcache, tdep->ppc_cr_regnum,
-                     gregs, offsets->cr_offset, offsets->xr_size);
+                     (const gdb_byte *) gregs, offsets->cr_offset,
+                     offsets->xr_size);
       ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
-                     gregs, offsets->xer_offset, offsets->xr_size);
+                     (const gdb_byte *) gregs, offsets->xer_offset,
+                     offsets->xr_size);
       ppc_supply_reg (regcache, tdep->ppc_mq_regnum,
-                     gregs, offsets->mq_offset, offsets->xr_size);
+                     (const gdb_byte *) gregs, offsets->mq_offset,
+                     offsets->xr_size);
       return;
     }
 
   offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, &regsize);
-  ppc_supply_reg (regcache, regnum, gregs, offset, regsize);
+  ppc_supply_reg (regcache, regnum, (const gdb_byte *) gregs, offset, regsize);
 }
 
 /* Supply register REGNUM in the floating-point register set REGSET
@@ -559,7 +567,7 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
     return;
 
   tdep = gdbarch_tdep (gdbarch);
-  offsets = regset->regmap;
+  offsets = (const struct ppc_reg_offsets *) regset->regmap;
   if (regnum == -1)
     {
       int i;
@@ -567,15 +575,16 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
       for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
           i < tdep->ppc_fp0_regnum + ppc_num_fprs;
           i++, offset += 8)
-       ppc_supply_reg (regcache, i, fpregs, offset, 8);
+       ppc_supply_reg (regcache, i, (const gdb_byte *) fpregs, offset, 8);
 
       ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum,
-                     fpregs, offsets->fpscr_offset, offsets->fpscr_size);
+                     (const gdb_byte *) fpregs, offsets->fpscr_offset,
+                     offsets->fpscr_size);
       return;
     }
 
   offset = ppc_fpreg_offset (tdep, offsets, regnum);
-  ppc_supply_reg (regcache, regnum, fpregs, offset,
+  ppc_supply_reg (regcache, regnum, (const gdb_byte *) fpregs, offset,
                  regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
 }
 
@@ -602,12 +611,12 @@ ppc_supply_vsxregset (const struct regset *regset, struct regcache *regcache,
       for (i = tdep->ppc_vsr0_upper_regnum;
           i < tdep->ppc_vsr0_upper_regnum + 32;
           i++)
-       ppc_supply_reg (regcache, i, vsxregs, 0, 8);
+       ppc_supply_reg (regcache, i, (const gdb_byte *) vsxregs, 0, 8);
 
       return;
     }
   else
-    ppc_supply_reg (regcache, regnum, vsxregs, 0, 8);
+    ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 8);
 }
 
 /* Supply register REGNUM in the Altivec register set REGSET
@@ -627,7 +636,7 @@ ppc_supply_vrregset (const struct regset *regset, struct regcache *regcache,
     return;
 
   tdep = gdbarch_tdep (gdbarch);
-  offsets = regset->regmap;
+  offsets = (const struct ppc_reg_offsets *) regset->regmap;
   if (regnum == -1)
     {
       int i;
@@ -635,23 +644,23 @@ ppc_supply_vrregset (const struct regset *regset, struct regcache *regcache,
       for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
           i < tdep->ppc_vr0_regnum + ppc_num_vrs;
           i++, offset += 16)
-        ppc_supply_reg (regcache, i, vrregs, offset, 16);
+        ppc_supply_reg (regcache, i, (const gdb_byte *) vrregs, offset, 16);
 
       ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
-                     vrregs, offsets->vscr_offset, 4);
+                     (const gdb_byte *) vrregs, offsets->vscr_offset, 4);
 
       ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
-                     vrregs, offsets->vrsave_offset, 4);
+                     (const gdb_byte *) vrregs, offsets->vrsave_offset, 4);
       return;
     }
 
   offset = ppc_vrreg_offset (tdep, offsets, regnum);
   if (regnum != tdep->ppc_vrsave_regnum
       && regnum != tdep->ppc_vrsave_regnum - 1)
-    ppc_supply_reg (regcache, regnum, vrregs, offset, 16);
+    ppc_supply_reg (regcache, regnum, (const gdb_byte *) vrregs, offset, 16);
   else
     ppc_supply_reg (regcache, regnum,
-                   vrregs, offset, 4);
+                   (const gdb_byte *) vrregs, offset, 4);
 }
 
 /* Collect register REGNUM in the general-purpose register set
@@ -666,7 +675,8 @@ ppc_collect_gregset (const struct regset *regset,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  const struct ppc_reg_offsets *offsets = regset->regmap;
+  const struct ppc_reg_offsets *offsets
+    = (const struct ppc_reg_offsets *) regset->regmap;
   size_t offset;
   int regsize;
 
@@ -678,27 +688,30 @@ ppc_collect_gregset (const struct regset *regset,
       for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
           i < tdep->ppc_gp0_regnum + ppc_num_gprs;
           i++, offset += gpr_size)
-       ppc_collect_reg (regcache, i, gregs, offset, gpr_size);
+       ppc_collect_reg (regcache, i, (gdb_byte *) gregs, offset, gpr_size);
 
       ppc_collect_reg (regcache, gdbarch_pc_regnum (gdbarch),
-                      gregs, offsets->pc_offset, gpr_size);
+                      (gdb_byte *) gregs, offsets->pc_offset, gpr_size);
       ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
-                      gregs, offsets->ps_offset, gpr_size);
+                      (gdb_byte *) gregs, offsets->ps_offset, gpr_size);
       ppc_collect_reg (regcache, tdep->ppc_lr_regnum,
-                      gregs, offsets->lr_offset, gpr_size);
+                      (gdb_byte *) gregs, offsets->lr_offset, gpr_size);
       ppc_collect_reg (regcache, tdep->ppc_ctr_regnum,
-                      gregs, offsets->ctr_offset, gpr_size);
+                      (gdb_byte *) gregs, offsets->ctr_offset, gpr_size);
       ppc_collect_reg (regcache, tdep->ppc_cr_regnum,
-                      gregs, offsets->cr_offset, offsets->xr_size);
+                      (gdb_byte *) gregs, offsets->cr_offset,
+                      offsets->xr_size);
       ppc_collect_reg (regcache, tdep->ppc_xer_regnum,
-                      gregs, offsets->xer_offset, offsets->xr_size);
+                      (gdb_byte *) gregs, offsets->xer_offset,
+                      offsets->xr_size);
       ppc_collect_reg (regcache, tdep->ppc_mq_regnum,
-                      gregs, offsets->mq_offset, offsets->xr_size);
+                      (gdb_byte *) gregs, offsets->mq_offset,
+                      offsets->xr_size);
       return;
     }
 
   offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, &regsize);
-  ppc_collect_reg (regcache, regnum, gregs, offset, regsize);
+  ppc_collect_reg (regcache, regnum, (gdb_byte *) gregs, offset, regsize);
 }
 
 /* Collect register REGNUM in the floating-point register set
@@ -720,7 +733,7 @@ ppc_collect_fpregset (const struct regset *regset,
     return;
 
   tdep = gdbarch_tdep (gdbarch);
-  offsets = regset->regmap;
+  offsets = (const struct ppc_reg_offsets *) regset->regmap;
   if (regnum == -1)
     {
       int i;
@@ -728,15 +741,16 @@ ppc_collect_fpregset (const struct regset *regset,
       for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
           i < tdep->ppc_fp0_regnum + ppc_num_fprs;
           i++, offset += 8)
-       ppc_collect_reg (regcache, i, fpregs, offset, 8);
+       ppc_collect_reg (regcache, i, (gdb_byte *) fpregs, offset, 8);
 
       ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum,
-                      fpregs, offsets->fpscr_offset, offsets->fpscr_size);
+                      (gdb_byte *) fpregs, offsets->fpscr_offset,
+                      offsets->fpscr_size);
       return;
     }
 
   offset = ppc_fpreg_offset (tdep, offsets, regnum);
-  ppc_collect_reg (regcache, regnum, fpregs, offset,
+  ppc_collect_reg (regcache, regnum, (gdb_byte *) fpregs, offset,
                   regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
 }
 
@@ -765,12 +779,12 @@ ppc_collect_vsxregset (const struct regset *regset,
       for (i = tdep->ppc_vsr0_upper_regnum;
           i < tdep->ppc_vsr0_upper_regnum + 32;
           i++)
-       ppc_collect_reg (regcache, i, vsxregs, 0, 8);
+       ppc_collect_reg (regcache, i, (gdb_byte *) vsxregs, 0, 8);
 
       return;
     }
   else
-    ppc_collect_reg (regcache, regnum, vsxregs, 0, 8);
+    ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 8);
 }
 
 
@@ -793,7 +807,7 @@ ppc_collect_vrregset (const struct regset *regset,
     return;
 
   tdep = gdbarch_tdep (gdbarch);
-  offsets = regset->regmap;
+  offsets = (const struct ppc_reg_offsets *) regset->regmap;
   if (regnum == -1)
     {
       int i;
@@ -801,23 +815,23 @@ ppc_collect_vrregset (const struct regset *regset,
       for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
           i < tdep->ppc_vr0_regnum + ppc_num_vrs;
           i++, offset += 16)
-       ppc_collect_reg (regcache, i, vrregs, offset, 16);
+       ppc_collect_reg (regcache, i, (gdb_byte *) vrregs, offset, 16);
 
       ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
-                      vrregs, offsets->vscr_offset, 4);
+                      (gdb_byte *) vrregs, offsets->vscr_offset, 4);
 
       ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
-                      vrregs, offsets->vrsave_offset, 4);
+                      (gdb_byte *) vrregs, offsets->vrsave_offset, 4);
       return;
     }
 
   offset = ppc_vrreg_offset (tdep, offsets, regnum);
   if (regnum != tdep->ppc_vrsave_regnum
       && regnum != tdep->ppc_vrsave_regnum - 1)
-    ppc_collect_reg (regcache, regnum, vrregs, offset, 16);
+    ppc_collect_reg (regcache, regnum, (gdb_byte *) vrregs, offset, 16);
   else
     ppc_collect_reg (regcache, regnum,
-                   vrregs, offset, 4);
+                   (gdb_byte *) vrregs, offset, 4);
 }
 \f
 
@@ -974,6 +988,61 @@ rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
 #define BXL_INSN 0x4c000000
 #define BP_INSN 0x7C000008
 
+/* Instruction masks used during single-stepping of atomic
+   sequences.  */
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7c000028
+#define LDARX_INSTRUCTION 0x7c0000A8
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+
+/* We can't displaced step atomic sequences.  Otherwise this is just
+   like simple_displaced_step_copy_insn.  */
+
+static struct displaced_step_closure *
+ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
+                             CORE_ADDR from, CORE_ADDR to,
+                             struct regcache *regs)
+{
+  size_t len = gdbarch_max_insn_length (gdbarch);
+  gdb_byte *buf = (gdb_byte *) xmalloc (len);
+  struct cleanup *old_chain = make_cleanup (xfree, buf);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int insn;
+
+  read_memory (from, buf, len);
+
+  insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
+
+  /* Assume all atomic sequences start with a lwarx/ldarx instruction.  */
+  if ((insn & LWARX_MASK) == LWARX_INSTRUCTION
+      || (insn & LWARX_MASK) == LDARX_INSTRUCTION)
+    {
+      if (debug_displaced)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "displaced: can't displaced step "
+                             "atomic sequence at %s\n",
+                             paddress (gdbarch, from));
+       }
+      do_cleanups (old_chain);
+      return NULL;
+    }
+
+  write_memory (to, buf, len);
+
+  if (debug_displaced)
+    {
+      fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
+                          paddress (gdbarch, from), paddress (gdbarch, to));
+      displaced_step_dump_bytes (gdb_stdlog, buf, len);
+    }
+
+  discard_cleanups (old_chain);
+  return (struct displaced_step_closure *) buf;
+}
+
 /* Fix up the state of registers and memory after having single-stepped
    a displaced instruction.  */
 static void
@@ -983,8 +1052,7 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
                          struct regcache *regs)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  /* Since we use simple_displaced_step_copy_insn, our closure is a
-     copy of the instruction.  */
+  /* Our closure is a copy of the instruction.  */
   ULONGEST insn  = extract_unsigned_integer ((gdb_byte *) closure,
                                              PPC_INSN_SIZE, byte_order);
   ULONGEST opcode = 0;
@@ -1077,14 +1145,6 @@ ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
   return 1;
 }
 
-/* Instruction masks used during single-stepping of atomic sequences.  */
-#define LWARX_MASK 0xfc0007fe
-#define LWARX_INSTRUCTION 0x7c000028
-#define LDARX_INSTRUCTION 0x7c0000A8
-#define STWCX_MASK 0xfc0007ff
-#define STWCX_INSTRUCTION 0x7c00012d
-#define STDCX_INSTRUCTION 0x7c0001ad
-
 /* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
    instruction and ending with a STWCX/STDCX instruction.  If such a sequence
    is found, attempt to step through it.  A breakpoint is placed at the end of 
@@ -1105,7 +1165,6 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
   int index;
   int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */  
   const int atomic_sequence_length = 16; /* Instruction sequence length.  */
-  int opcode; /* Branch instruction's OPcode.  */
   int bc_insn_count = 0; /* Conditional branch instruction count.  */
 
   /* Assume all atomic sequences start with a lwarx/ldarx instruction.  */
@@ -2127,7 +2186,7 @@ rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
       CORE_ADDR post_prologue_pc
        = skip_prologue_using_sal (gdbarch, func_addr);
       if (post_prologue_pc != 0)
-       return max (pc, post_prologue_pc);
+       return std::max (pc, post_prologue_pc);
     }
 
   /* Can't determine prologue from the symbol table, need to examine
@@ -2606,7 +2665,7 @@ e500_move_ev_register (move_ev_register_func move,
   struct gdbarch *arch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (arch); 
   int reg_index;
-  gdb_byte *byte_buffer = buffer;
+  gdb_byte *byte_buffer = (gdb_byte *) buffer;
   enum register_status status;
 
   gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
@@ -2635,13 +2694,13 @@ e500_move_ev_register (move_ev_register_func move,
 static enum register_status
 do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
 {
-  return regcache_raw_read (regcache, regnum, buffer);
+  return regcache_raw_read (regcache, regnum, (gdb_byte *) buffer);
 }
 
 static enum register_status
 do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
 {
-  regcache_raw_write (regcache, regnum, buffer);
+  regcache_raw_write (regcache, regnum, (const gdb_byte *) buffer);
 
   return REG_VALID;
 }
@@ -2862,6 +2921,62 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch,
                    gdbarch_register_name (gdbarch, reg_nr), reg_nr);
 }
 
+static int
+rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+                                  struct agent_expr *ax, int reg_nr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+    {
+      int reg_index = reg_nr - tdep->ppc_ev0_regnum;
+      ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index);
+      ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index);
+    }
+  else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+    {
+      int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+      ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index);
+      ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1);
+    }
+  else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+    {
+      int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+      if (reg_index > 31)
+        {
+          ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32);
+       }
+      else
+        {
+          ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index);
+          ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index);
+        }
+    }
+  else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+    {
+      int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+      ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index);
+    }
+  else
+    internal_error (__FILE__, __LINE__,
+                   _("rs6000_pseudo_register_collect: "
+                   "called on unexpected register '%s' (%d)"),
+                   gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+  return 0;
+}
+
+
+static void
+rs6000_gen_return_address (struct gdbarch *gdbarch,
+                          struct agent_expr *ax, struct axs_value *value,
+                          CORE_ADDR scope)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  value->type = register_type (gdbarch, tdep->ppc_lr_regnum);
+  value->kind = axs_lvalue_register;
+  value->u.reg = tdep->ppc_lr_regnum;
+}
+
+
 /* Convert a DBX STABS register number to a GDB register number.  */
 static int
 rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
@@ -3087,7 +3202,7 @@ static struct variant variants[] =
   {"rs2", "IBM POWER RS2", bfd_arch_rs6000,
    bfd_mach_rs6k_rs2, &tdesc_rs6000},
 
-  {0, 0, 0, 0, 0}
+  {0, 0, (enum bfd_architecture) 0, 0, 0}
 };
 
 /* Return the variant corresponding to architecture ARCH and machine number
@@ -3134,6 +3249,13 @@ struct rs6000_frame_cache
   CORE_ADDR base;
   CORE_ADDR initial_sp;
   struct trad_frame_saved_reg *saved_regs;
+
+  /* Set BASE_P to true if this frame cache is properly initialized.
+     Otherwise set to false because some registers or memory cannot
+     collected.  */
+  int base_p;
+  /* Cache PC for building unavailable frame.  */
+  CORE_ADDR pc;
 };
 
 static struct rs6000_frame_cache *
@@ -3145,27 +3267,39 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct rs6000_framedata fdata;
   int wordsize = tdep->wordsize;
-  CORE_ADDR func, pc;
+  CORE_ADDR func = 0, pc = 0;
 
   if ((*this_cache) != NULL)
-    return (*this_cache);
+    return (struct rs6000_frame_cache *) (*this_cache);
   cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
   (*this_cache) = cache;
+  cache->pc = 0;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  func = get_frame_func (this_frame);
-  pc = get_frame_pc (this_frame);
-  skip_prologue (gdbarch, func, pc, &fdata);
-
-  /* Figure out the parent's stack pointer.  */
-
-  /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
-     address of the current frame.  Things might be easier if the
-     ->frame pointed to the outer-most address of the frame.  In
-     the mean time, the address of the prev frame is used as the
-     base address of this frame.  */
-  cache->base = get_frame_register_unsigned
-               (this_frame, gdbarch_sp_regnum (gdbarch));
+  TRY
+    {
+      func = get_frame_func (this_frame);
+      cache->pc = func;
+      pc = get_frame_pc (this_frame);
+      skip_prologue (gdbarch, func, pc, &fdata);
+
+      /* Figure out the parent's stack pointer.  */
+
+      /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
+        address of the current frame.  Things might be easier if the
+        ->frame pointed to the outer-most address of the frame.  In
+        the mean time, the address of the prev frame is used as the
+        base address of this frame.  */
+      cache->base = get_frame_register_unsigned
+       (this_frame, gdbarch_sp_regnum (gdbarch));
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      if (ex.error != NOT_AVAILABLE_ERROR)
+       throw_exception (ex);
+      return (struct rs6000_frame_cache *) (*this_cache);
+    }
+  END_CATCH
 
   /* If the function appears to be frameless, check a couple of likely
      indicators that we have simply failed to find the frame setup.
@@ -3201,10 +3335,10 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   if (!fdata.frameless)
     {
       /* Frameless really means stackless.  */
-      LONGEST backchain;
+      ULONGEST backchain;
 
-      if (safe_read_memory_integer (cache->base, wordsize,
-                                   byte_order, &backchain))
+      if (safe_read_memory_unsigned_integer (cache->base, wordsize,
+                                            byte_order, &backchain))
         cache->base = (CORE_ADDR) backchain;
     }
 
@@ -3314,6 +3448,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
     cache->initial_sp
       = get_frame_register_unsigned (this_frame, fdata.alloca_reg);
 
+  cache->base_p = 1;
   return cache;
 }
 
@@ -3323,6 +3458,13 @@ rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache,
 {
   struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
                                                        this_cache);
+
+  if (!info->base_p)
+    {
+      (*this_id) = frame_id_build_unavailable_stack (info->pc);
+      return;
+    }
+
   /* This marks the outermost frame.  */
   if (info->base == 0)
     return;
@@ -3360,7 +3502,7 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (*this_cache)
-    return *this_cache;
+    return (struct rs6000_frame_cache *) *this_cache;
 
   cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
   (*this_cache) = cache;
@@ -3567,7 +3709,7 @@ bfd_uses_spe_extensions (bfd *abfd)
     return 0;
 
   size = bfd_get_section_size (sect);
-  contents = xmalloc (size);
+  contents = (gdb_byte *) xmalloc (size);
   if (!bfd_get_section_contents (abfd, sect, contents, 0, size))
     {
       xfree (contents);
@@ -4472,23 +4614,24 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     case 654:          /* Transaction Begin */
     case 686:          /* Transaction End */
-    case 718:          /* Transaction Check */
     case 750:          /* Transaction Suspend or Resume */
     case 782:          /* Transaction Abort Word Conditional */
     case 814:          /* Transaction Abort Doubleword Conditional */
     case 846:          /* Transaction Abort Word Conditional Immediate */
     case 878:          /* Transaction Abort Doubleword Conditional Immediate */
     case 910:          /* Transaction Abort */
-      fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
-                         "%08x at %s, 31-%d.\n",
-                         insn, paddress (gdbarch, addr), ext);
-      return -1;
+      record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
+      /* FALL-THROUGH */
+    case 718:          /* Transaction Check */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
 
     case 1014:         /* Data Cache Block set to Zero */
       if (target_auxv_search (&current_target, AT_DCACHEBSIZE, &at_dcsz) <= 0
          || at_dcsz == 0)
        at_dcsz = 128; /* Assume 128-byte cache line size (POWER8)  */
 
+      ra = 0;
       if (PPC_RA (insn) != 0)
        regcache_raw_read_unsigned (regcache,
                                    tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
@@ -5815,7 +5958,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
   set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
-  set_gdbarch_deprecated_fp_regnum (gdbarch, PPC_R0_REGNUM + 1);
   set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum);
   set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno);
 
@@ -5840,8 +5982,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
       set_gdbarch_pseudo_register_write (gdbarch,
                                         rs6000_pseudo_register_write);
+      set_gdbarch_ax_pseudo_register_collect (gdbarch,
+             rs6000_ax_pseudo_register_collect);
     }
 
+  set_gdbarch_gen_return_address (gdbarch, rs6000_gen_return_address);
+
   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
 
   /* Select instruction printer.  */
@@ -5923,7 +6069,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Setup displaced stepping.  */
   set_gdbarch_displaced_step_copy_insn (gdbarch,
-                                       simple_displaced_step_copy_insn);
+                                       ppc_displaced_step_copy_insn);
   set_gdbarch_displaced_step_hw_singlestep (gdbarch,
                                            ppc_displaced_step_hw_singlestep);
   set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
@@ -5936,7 +6082,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
-  info.tdep_info = (void *) tdesc_data;
+  info.tdep_info = tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
   switch (info.osabi)
This page took 0.048183 seconds and 4 git commands to generate.