[PATCH] Process record support for PowerPC

Wei-cheng, Wang cole945@gmail.com
Tue Nov 18 16:27:00 GMT 2014


Hi,

This patch is process record support for PowerPC
* Tested with Advance Toolchain 8.0 ppc64 - 2326 pass, no fail
* 26 fails if tested with ppc64le, due to local entry optimization.
   Breakpoints set on the very beginning of functions may
   not be hit when reverse-continue.
* Support reverse-step over subroutine without debug info
* Record/reverse syscall/signal
* Support reverse-step through solib trampoline

And these instructions are handled
* All main opcode
* opcode 31
-- Privileged instructions are listed, but not handled.
    Shoule I just remote them?
* opcode 59 and 63 (Decimal Floating-Point and Floating-point)
* opcode 4 (Only [vector] instructions are handled.)
* opcode 19 (Only conditional and branch instruction.)

SPE, Embedded, LMA, VSX and privileged instructions are not handled.

Wei-cheng

---
  gdb/configure.tgt                       |    3 +-
  gdb/ppc-linux-tdep.c                    |  353 +++++++
  gdb/ppc-tdep.h                          |    5 +
  gdb/rs6000-tdep.c                       | 1516 ++++++++++++++++++++++++++++++-
  gdb/testsuite/lib/gdb.exp               |    6 +-
  6 files changed, 1881 insertions(+), 7 deletions(-)

diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 1d7f54b..ae77efe 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -434,7 +434,8 @@ powerpc*-*-linux*)
  			ppc64-tdep.o solib-svr4.o solib-spu.o \
  			spu-multiarch.o \
  			glibc-tdep.o symfile-mem.o linux-tdep.o \
-			ravenscar-thread.o ppc-ravenscar-thread.o"
+			ravenscar-thread.o ppc-ravenscar-thread.o \
+			linux-record.o "
  	gdb_sim=../sim/ppc/libsim.a
  	build_gdbserver=yes
  	;;
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index a997869..608081c 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -49,6 +49,9 @@
  #include "spu-tdep.h"
  #include "xml-syscall.h"
  #include "linux-tdep.h"
+#include "linux-record.h"
+#include "record-full.h"
+#include "infrun.h"

  #include "stap-probe.h"
  #include "ax.h"
@@ -298,6 +301,23 @@ powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
  	  || strcmp (MSYMBOL_LINKAGE_NAME (sym.minsym),
  		     "__glink_PLTresolve") == 0))
      return 1;
+  else if (sym.minsym != NULL && execution_direction == EXEC_REVERSE)
+    {
+      /* When reverse stepping, gdb needs to know whether PC lies in
+	 the dynamic symbol resolve code, so it can keep going until
+	 reaching some user code.
+	 Using insns-match-pattern is not suitable, because we had to
+	 look both ahead and behind to check where we are in the middle
+	 of one of trampline sequences.  */
+#define SUBSTRCMP(sym, stub)  (memcmp (sym + 8, stub, sizeof (stub) - 1) == 0)
+      if (SUBSTRCMP (MSYMBOL_LINKAGE_NAME (sym.minsym), ".plt_call."))
+	return 1;
+      if (SUBSTRCMP (MSYMBOL_LINKAGE_NAME (sym.minsym), ".plt_branch."))
+	return 1;
+      if (SUBSTRCMP (MSYMBOL_LINKAGE_NAME (sym.minsym), ".plt_branch_r2off."))
+	return 1;
+#undef SUBSTRCMP
+    }

    return 0;
  }
@@ -764,6 +784,165 @@ ppc_linux_get_syscall_number (struct gdbarch *gdbarch,
    return ret;
  }

+/* PPC process record-replay */
+
+struct linux_record_tdep ppc_linux_record_tdep;
+
+static enum gdb_syscall
+ppc_canonicalize_syscall (int syscall)
+{
+  /* See arch/powerpc/include/uapi/asm/unistd.h */
+
+  if (syscall <= 165)
+    return syscall;
+  else if (syscall >= 167 && syscall <= 190)	/* Skip query_module 166 */
+    return syscall + 1;
+  else if (syscall >= 192 && syscall <= 197)	/* mmap2 */
+    return syscall;
+  else if (syscall == 208)			/* tkill */
+    return gdb_sys_tkill;
+  else if (syscall >= 207 && syscall <= 220)	/* gettid */
+    return syscall + 224 - 207;
+  else if (syscall >= 234 && syscall <= 239)	/* exit_group */
+    return syscall + 252 - 234;
+  else if (syscall >= 240 && syscall <=248)	/* timer_create */
+    return syscall += 259 - 240;
+  else if (syscall >= 250 && syscall <=251)	/* tgkill */
+    return syscall + 270 - 250;
+  else if (syscall == 336)
+    return gdb_sys_recv;
+  else if (syscall == 337)
+    return gdb_sys_recvfrom;
+  else if (syscall == 342)
+    return gdb_sys_recvmsg;
+  return -1;
+}
+
+/* Record all registers but PC register for process-record.  */
+
+static int
+ppc_all_but_pc_registers_record (struct regcache *regcache)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int i;
+
+  for (i = 0; i < 32; i++)
+    {
+      if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + i))
+        return -1;
+    }
+
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
+    return -1;
+
+  return 0;
+}
+
+static int
+ppc_linux_syscall_record (struct regcache *regcache)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ULONGEST scnum;
+  enum gdb_syscall syscall_gdb;
+  int ret;
+
+  regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum, &scnum);
+  syscall_gdb = ppc_canonicalize_syscall (scnum);
+
+  if (syscall_gdb < 0)
+    {
+      printf_unfiltered (_("Process record and replay target doesn't "
+                           "support syscall number %d\n"),
+                           (int) scnum);
+      return 0;
+    }
+
+  if (syscall_gdb == gdb_sys_sigreturn
+      || syscall_gdb == gdb_sys_rt_sigreturn)
+   {
+     if (ppc_all_but_pc_registers_record (regcache))
+       return -1;
+     return 0;
+   }
+
+  ret = record_linux_system_call (syscall_gdb, regcache,
+                                  &ppc_linux_record_tdep);
+  if (ret != 0)
+    return ret;
+
+  /* Record registers clobbered during syscall.  */
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 0))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 3))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 4))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 5))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 6))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 7))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 8))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 9))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 10))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 11))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 12))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
+    return -1;
+
+  return 0;
+}
+
+static int
+ppc64_linux_record_signal (struct gdbarch *gdbarch,
+                           struct regcache *regcache,
+                           enum gdb_signal signal)
+{
+  /* See arch/powerpc/kernel/signal_64.c
+	 arch/powerpc/include/asm/ptrace.h
+     for details.  */
+  const int SIGNAL_FRAMESIZE = 128;
+  const int sizeof_rt_sigframe = 1440 * 2 + 8 * 2 + 4 * 6 + 8 + 8 + 128 + 512;
+  ULONGEST sp;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (ppc_all_but_pc_registers_record (regcache))
+    return -1;
+
+  if (record_full_arch_list_add_reg (regcache, gdbarch_pc_regnum (gdbarch)))
+    return -1;
+
+  /* Record the change in the stack.
+     frame-size = sizeof (struct rt_sigframe) + SIGNAL_FRAMESIZE  */
+  regcache_raw_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &sp);
+  sp -= SIGNAL_FRAMESIZE;
+  sp -= sizeof_rt_sigframe;
+
+  if (record_full_arch_list_add_mem (sp, SIGNAL_FRAMESIZE + sizeof_rt_sigframe))
+    return -1;
+
+  if (record_full_arch_list_add_end ())
+    return -1;
+
+  return 0;
+}
+
  static void
  ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
  {
@@ -1345,6 +1524,15 @@ ppc_linux_init_abi (struct gdbarch_info info,
        set_solib_svr4_fetch_link_map_offsets
          (gdbarch, svr4_lp64_fetch_link_map_offsets);

+      if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
+	{
+	  powerpc_so_ops = svr4_so_ops;
+	  /* Override dynamic resolve function.  */
+	  powerpc_so_ops.in_dynsym_resolve_code =
+	    powerpc_linux_in_dynsym_resolve_code;
+	}
+      set_solib_ops (gdbarch, &powerpc_so_ops);
+
        /* Setting the correct XML syscall filename.  */
        set_xml_syscall_file_name (XML_SYSCALL_FILENAME_PPC64);

@@ -1414,6 +1602,171 @@ ppc_linux_init_abi (struct gdbarch_info info,
      }

    set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
+
+  /* Support reverse debugging.  */
+  set_gdbarch_process_record (gdbarch, ppc64_process_record);
+  set_gdbarch_process_record_signal (gdbarch, ppc64_linux_record_signal);
+  tdep->syscall_record = ppc_linux_syscall_record;
+
+  /* Initialize the ppc_linux_record_tdep.  */
+  /* These values are the size of the type that will be used in a system
+     call.  They are obtained from Linux Kernel source.
+
+     See arch/powerpc/include/uapi/asm/ioctls.h.  */
+  ppc_linux_record_tdep.size_pointer
+    = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+  ppc_linux_record_tdep.size__old_kernel_stat = 32;
+  ppc_linux_record_tdep.size_tms = 32;
+  ppc_linux_record_tdep.size_loff_t = 8;
+  ppc_linux_record_tdep.size_flock = 32;
+  ppc_linux_record_tdep.size_oldold_utsname = 45;
+  ppc_linux_record_tdep.size_ustat = 32;
+  ppc_linux_record_tdep.size_old_sigaction = 152;
+  ppc_linux_record_tdep.size_old_sigset_t = 128;
+  ppc_linux_record_tdep.size_rlimit = 16;
+  ppc_linux_record_tdep.size_rusage = 144;
+  ppc_linux_record_tdep.size_timeval = 16;
+  ppc_linux_record_tdep.size_timezone = 8;
+  ppc_linux_record_tdep.size_old_gid_t = 2;
+  ppc_linux_record_tdep.size_old_uid_t = 2;
+  ppc_linux_record_tdep.size_fd_set = 128;
+  ppc_linux_record_tdep.size_dirent = 280;
+  ppc_linux_record_tdep.size_dirent64 = 280;
+  ppc_linux_record_tdep.size_statfs = 120;
+  ppc_linux_record_tdep.size_statfs64 = 120;
+  ppc_linux_record_tdep.size_sockaddr = 16;
+  ppc_linux_record_tdep.size_int
+    = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
+  ppc_linux_record_tdep.size_long
+    = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+  ppc_linux_record_tdep.size_ulong
+    = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+  ppc_linux_record_tdep.size_msghdr = 56;
+  ppc_linux_record_tdep.size_itimerval = 32;
+  ppc_linux_record_tdep.size_stat = 144;
+  ppc_linux_record_tdep.size_old_utsname = 325;
+  ppc_linux_record_tdep.size_sysinfo = 112;
+  ppc_linux_record_tdep.size_msqid_ds = 120;
+  ppc_linux_record_tdep.size_shmid_ds = 112;
+  ppc_linux_record_tdep.size_new_utsname = 390;
+  ppc_linux_record_tdep.size_timex = 208;
+  ppc_linux_record_tdep.size_mem_dqinfo = 24;
+  ppc_linux_record_tdep.size_if_dqblk = 72;
+  ppc_linux_record_tdep.size_fs_quota_stat = 80;
+  ppc_linux_record_tdep.size_timespec = 16;
+  ppc_linux_record_tdep.size_pollfd = 8;
+  ppc_linux_record_tdep.size_NFS_FHSIZE = 32;
+  ppc_linux_record_tdep.size_knfsd_fh = 132;
+  ppc_linux_record_tdep.size_TASK_COMM_LEN = 32;
+  ppc_linux_record_tdep.size_sigaction = 152;
+  ppc_linux_record_tdep.size_sigset_t = 128;
+  ppc_linux_record_tdep.size_siginfo_t = 128;
+  ppc_linux_record_tdep.size_cap_user_data_t = 8;
+  ppc_linux_record_tdep.size_stack_t = 24;
+  ppc_linux_record_tdep.size_off_t = 8;
+  ppc_linux_record_tdep.size_stat64 = 144;
+  ppc_linux_record_tdep.size_gid_t = 4;
+  ppc_linux_record_tdep.size_uid_t = 4;
+  ppc_linux_record_tdep.size_PAGE_SIZE = 4096;
+  ppc_linux_record_tdep.size_flock64 = 32;
+  ppc_linux_record_tdep.size_user_desc = 16;
+  ppc_linux_record_tdep.size_io_event = 32;
+  ppc_linux_record_tdep.size_iocb = 64;
+  ppc_linux_record_tdep.size_epoll_event = 12;
+  ppc_linux_record_tdep.size_itimerspec = 32;
+  ppc_linux_record_tdep.size_mq_attr = 64;
+  ppc_linux_record_tdep.size_siginfo = 128;
+  ppc_linux_record_tdep.size_termios = 60;
+  ppc_linux_record_tdep.size_termios2 = 44;
+  ppc_linux_record_tdep.size_pid_t = 4;
+  ppc_linux_record_tdep.size_winsize = 8;
+  ppc_linux_record_tdep.size_serial_struct = 72;
+  ppc_linux_record_tdep.size_serial_icounter_struct = 80;
+  ppc_linux_record_tdep.size_hayes_esp_config = 12;
+  ppc_linux_record_tdep.size_size_t = 8;
+  ppc_linux_record_tdep.size_iovec = 16;
+
+  /* These values are the second argument of system call "sys_fcntl"
+     and "sys_fcntl64".  They are obtained from Linux Kernel source.  */
+  ppc_linux_record_tdep.fcntl_F_GETLK = 5;
+  ppc_linux_record_tdep.fcntl_F_GETLK64 = 12;
+  ppc_linux_record_tdep.fcntl_F_SETLK64 = 13;
+  ppc_linux_record_tdep.fcntl_F_SETLKW64 = 14;
+
+  ppc_linux_record_tdep.arg1 = PPC_R0_REGNUM + 3;
+  ppc_linux_record_tdep.arg2 = PPC_R0_REGNUM + 4;
+  ppc_linux_record_tdep.arg3 = PPC_R0_REGNUM + 5;
+  ppc_linux_record_tdep.arg4 = PPC_R0_REGNUM + 6;
+  ppc_linux_record_tdep.arg5 = PPC_R0_REGNUM + 7;
+  ppc_linux_record_tdep.arg6 = PPC_R0_REGNUM + 8;
+
+  /* These values are the second argument of system call "sys_ioctl".
+     They are obtained from Linux Kernel source.  */
+  ppc_linux_record_tdep.ioctl_TCGETS = 0x5401;
+  ppc_linux_record_tdep.ioctl_TCSETS = 0x5402;
+  ppc_linux_record_tdep.ioctl_TCSETSW = 0x5403;
+  ppc_linux_record_tdep.ioctl_TCSETSF = 0x5404;
+  ppc_linux_record_tdep.ioctl_TCGETA = 0x5405;
+  ppc_linux_record_tdep.ioctl_TCSETA = 0x5406;
+  ppc_linux_record_tdep.ioctl_TCSETAW = 0x5407;
+  ppc_linux_record_tdep.ioctl_TCSETAF = 0x5408;
+  ppc_linux_record_tdep.ioctl_TCSBRK = 0x5409;
+  ppc_linux_record_tdep.ioctl_TCXONC = 0x540A;
+  ppc_linux_record_tdep.ioctl_TCFLSH = 0x540B;
+  ppc_linux_record_tdep.ioctl_TIOCEXCL = 0x540C;
+  ppc_linux_record_tdep.ioctl_TIOCNXCL = 0x540D;
+  ppc_linux_record_tdep.ioctl_TIOCSCTTY = 0x540E;
+  ppc_linux_record_tdep.ioctl_TIOCGPGRP = 0x540F;
+  ppc_linux_record_tdep.ioctl_TIOCSPGRP = 0x5410;
+  ppc_linux_record_tdep.ioctl_TIOCOUTQ = 0x5411;
+  ppc_linux_record_tdep.ioctl_TIOCSTI = 0x5412;
+  ppc_linux_record_tdep.ioctl_TIOCGWINSZ = 0x5413;
+  ppc_linux_record_tdep.ioctl_TIOCSWINSZ = 0x5414;
+  ppc_linux_record_tdep.ioctl_TIOCMGET = 0x5415;
+  ppc_linux_record_tdep.ioctl_TIOCMBIS = 0x5416;
+  ppc_linux_record_tdep.ioctl_TIOCMBIC = 0x5417;
+  ppc_linux_record_tdep.ioctl_TIOCMSET = 0x5418;
+  ppc_linux_record_tdep.ioctl_TIOCGSOFTCAR = 0x5419;
+  ppc_linux_record_tdep.ioctl_TIOCSSOFTCAR = 0x541A;
+  ppc_linux_record_tdep.ioctl_FIONREAD = 0x541B;
+  ppc_linux_record_tdep.ioctl_TIOCINQ = ppc_linux_record_tdep.ioctl_FIONREAD;
+  ppc_linux_record_tdep.ioctl_TIOCLINUX = 0x541C;
+  ppc_linux_record_tdep.ioctl_TIOCCONS = 0x541D;
+  ppc_linux_record_tdep.ioctl_TIOCGSERIAL = 0x541E;
+  ppc_linux_record_tdep.ioctl_TIOCSSERIAL = 0x541F;
+  ppc_linux_record_tdep.ioctl_TIOCPKT = 0x5420;
+  ppc_linux_record_tdep.ioctl_FIONBIO = 0x5421;
+  ppc_linux_record_tdep.ioctl_TIOCNOTTY = 0x5422;
+  ppc_linux_record_tdep.ioctl_TIOCSETD = 0x5423;
+  ppc_linux_record_tdep.ioctl_TIOCGETD = 0x5424;
+  ppc_linux_record_tdep.ioctl_TCSBRKP = 0x5425;
+  ppc_linux_record_tdep.ioctl_TIOCTTYGSTRUCT = 0x5426;
+  ppc_linux_record_tdep.ioctl_TIOCSBRK = 0x5427;
+  ppc_linux_record_tdep.ioctl_TIOCCBRK = 0x5428;
+  ppc_linux_record_tdep.ioctl_TIOCGSID = 0x5429;
+  ppc_linux_record_tdep.ioctl_TCGETS2 = 0x802c542a;
+  ppc_linux_record_tdep.ioctl_TCSETS2 = 0x402c542b;
+  ppc_linux_record_tdep.ioctl_TCSETSW2 = 0x402c542c;
+  ppc_linux_record_tdep.ioctl_TCSETSF2 = 0x402c542d;
+  ppc_linux_record_tdep.ioctl_TIOCGPTN = 0x80045430;
+  ppc_linux_record_tdep.ioctl_TIOCSPTLCK = 0x40045431;
+  ppc_linux_record_tdep.ioctl_FIONCLEX = 0x5450;
+  ppc_linux_record_tdep.ioctl_FIOCLEX = 0x5451;
+  ppc_linux_record_tdep.ioctl_FIOASYNC = 0x5452;
+  ppc_linux_record_tdep.ioctl_TIOCSERCONFIG = 0x5453;
+  ppc_linux_record_tdep.ioctl_TIOCSERGWILD = 0x5454;
+  ppc_linux_record_tdep.ioctl_TIOCSERSWILD = 0x5455;
+  ppc_linux_record_tdep.ioctl_TIOCGLCKTRMIOS = 0x5456;
+  ppc_linux_record_tdep.ioctl_TIOCSLCKTRMIOS = 0x5457;
+  ppc_linux_record_tdep.ioctl_TIOCSERGSTRUCT = 0x5458;
+  ppc_linux_record_tdep.ioctl_TIOCSERGETLSR = 0x5459;
+  ppc_linux_record_tdep.ioctl_TIOCSERGETMULTI = 0x545A;
+  ppc_linux_record_tdep.ioctl_TIOCSERSETMULTI = 0x545B;
+  ppc_linux_record_tdep.ioctl_TIOCMIWAIT = 0x545C;
+  ppc_linux_record_tdep.ioctl_TIOCGICOUNT = 0x545D;
+  ppc_linux_record_tdep.ioctl_TIOCGHAYESESP = 0x545E;
+  ppc_linux_record_tdep.ioctl_TIOCSHAYESESP = 0x545F;
+  ppc_linux_record_tdep.ioctl_FIOQSIZE = 0x5460;
  }

  /* Provide a prototype to silence -Wmissing-prototypes.  */
diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h
index 08554ff..437ca8c 100644
--- a/gdb/ppc-tdep.h
+++ b/gdb/ppc-tdep.h
@@ -259,6 +259,8 @@ struct gdbarch_tdep
      /* ISA-specific types.  */
      struct type *ppc_builtin_type_vec64;
      struct type *ppc_builtin_type_vec128;
+
+    int (* syscall_record) (struct regcache *regcache);
  };


@@ -318,6 +320,9 @@ extern CORE_ADDR ppc_insn_d_field (unsigned int insn);

  extern CORE_ADDR ppc_insn_ds_field (unsigned int insn);

+extern int ppc64_process_record (struct gdbarch *gdbarch,
+				 struct regcache *regcache, CORE_ADDR addr);
+
  /* Instruction size.  */
  #define PPC_INSN_SIZE 4

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index dabf448..4153454 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -40,6 +40,8 @@
  #include "dwarf2-frame.h"
  #include "target-descriptions.h"
  #include "user-regs.h"
+#include "record-full.h"
+#include "auxv.h"

  #include "libbfd.h"		/* for bfd_default_set_arch_mach */
  #include "coff/internal.h"	/* for libcoff.h */
@@ -872,14 +874,14 @@ insn_changes_sp_or_jumps (unsigned long insn)
             limit for the size of an epilogue.  */

  static int
-rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
+				     struct gdbarch *gdbarch, CORE_ADDR pc)
  {
    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
    bfd_byte insn_buf[PPC_INSN_SIZE];
    CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end;
    unsigned long insn;
-  struct frame_info *curfrm;

    /* Find the search limits based on function boundaries and hard limit.  */

@@ -892,8 +894,6 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
    epilogue_end = pc + PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE;
    if (epilogue_end > func_end) epilogue_end = func_end;

-  curfrm = get_current_frame ();
-
    /* Scan forward until next 'blr'.  */

    for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE)
@@ -934,6 +934,15 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
    return 0;
  }

+/* Implementation of gdbarch_in_function_epilogue_p.  */
+
+static int
+rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  return rs6000_in_function_epilogue_frame_p (get_current_frame (),
+					      gdbarch, pc);
+}
+
  /* Get the ith function argument for the current function.  */
  static CORE_ADDR
  rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
@@ -3339,6 +3348,89 @@ static const struct frame_unwind rs6000_frame_unwind =
    NULL,
    default_frame_sniffer
  };
+
+static struct rs6000_frame_cache *
+rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+  volatile struct gdb_exception ex;
+  struct rs6000_frame_cache *cache;
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  CORE_ADDR sp;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
+  (*this_cache) = cache;
+  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      /* At this point the stack looks as if we just entered the
+	 function, and the return address is stored in LR.  */
+      CORE_ADDR sp, lr;
+
+      sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
+      lr = get_frame_register_unsigned (this_frame, tdep->ppc_lr_regnum);
+
+      cache->base = sp;
+      cache->initial_sp = sp;
+
+      trad_frame_set_value (cache->saved_regs,
+			    gdbarch_pc_regnum (gdbarch), lr);
+    }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
+
+  return cache;
+}
+
+static void
+rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
+			       void **this_cache, struct frame_id *this_id)
+{
+  CORE_ADDR pc;
+  struct rs6000_frame_cache *info =
+    rs6000_epilogue_frame_cache (this_frame, this_cache);
+
+  pc = get_frame_func (this_frame);
+  if (info->base == 0)
+    (*this_id) = frame_id_build_unavailable_stack (pc);
+  else
+    (*this_id) = frame_id_build (info->base, pc);
+}
+
+static struct value *
+rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
+				     void **this_cache, int regnum)
+{
+  struct rs6000_frame_cache *info =
+    rs6000_epilogue_frame_cache (this_frame, this_cache);
+  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
+}
+
+static int
+rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
+			       struct frame_info *this_frame,
+			       void **this_prologue_cache)
+{
+  if (frame_relative_level (this_frame) == 0)
+    return rs6000_in_function_epilogue_frame_p (this_frame,
+						get_frame_arch (this_frame),
+						get_frame_pc (this_frame));
+  else
+    return 0;
+}
+
+static const struct frame_unwind rs6000_epilogue_frame_unwind =
+{
+  NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
+  rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
+  NULL,
+  rs6000_epilogue_frame_sniffer
+};
  


  static CORE_ADDR
@@ -3543,6 +3635,1420 @@ bfd_uses_spe_extensions (bfd *abfd)
    return success;
  }

+/* These are macros for parsing instruction fields (I.1.6.28)  */
+
+#define PPC_FIELD(value, from, len) \
+	(((value) >> (32 - (from) - (len))) & ((1 << (len)) - 1))
+#define PPC_SEXT(v, bs) \
+	((((CORE_ADDR) (v) & (((CORE_ADDR) 1 << (bs)) - 1)) \
+	  ^ ((CORE_ADDR) 1 << ((bs) - 1))) \
+	 - ((CORE_ADDR) 1 << ((bs) - 1)))
+#define PPC_OP6(insn)	PPC_FIELD (insn, 0, 6)
+#define PPC_EXTOP(insn)	PPC_FIELD (insn, 21, 10)
+#define PPC_RT(insn)	PPC_FIELD (insn, 6, 5)
+#define PPC_RS(insn)	PPC_FIELD (insn, 6, 5)
+#define PPC_RA(insn)	PPC_FIELD (insn, 11, 5)
+#define PPC_RB(insn)	PPC_FIELD (insn, 16, 5)
+#define PPC_NB(insn)	PPC_FIELD (insn, 16, 5)
+#define PPC_VRT(insn)	PPC_FIELD (insn, 6, 5)
+#define PPC_FRT(insn)	PPC_FIELD (insn, 6, 5)
+#define PPC_SPR(insn)	(PPC_FIELD (insn, 11, 5) \
+			| (PPC_FIELD (insn, 16, 5) << 5))
+#define PPC_BF(insn)	PPC_FIELD (insn, 6, 3)
+#define PPC_BO(insn)	PPC_FIELD (insn, 6, 5)
+#define PPC_T(insn)	PPC_FIELD (insn, 6, 5)
+#define PPC_D(insn)	PPC_SEXT (PPC_FIELD (insn, 16, 16), 16)
+#define PPC_DS(insn)	PPC_SEXT (PPC_FIELD (insn, 16, 14), 14)
+#define PPC_BIT(insn,n)	((insn & (1 << (31 - (n)))) ? 1 : 0)
+#define PPC_OE(insn)	PPC_BIT (insn, 21)
+#define PPC_RC(insn)	PPC_BIT (insn, 31)
+#define PPC_Rc(insn)	PPC_BIT (insn, 21)
+#define PPC_LK(insn)	PPC_BIT (insn, 31)
+#define PPC_TX(insn)	PPC_BIT (insn, 31)
+
+#define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
+#define PPC_XER_NB(xer)	(xer & 0x7f)
+
+/* Record Vector-Scalar Registers.  */
+
+static int
+ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr,
+		int size)
+{
+  if (vsr < 0 || vsr >= 64)
+    return -1;
+
+  if (vsr >= 32)
+    {
+      if (tdep->ppc_vr0_regnum >= 0)
+	record_full_arch_list_add_reg (regcache, tdep->ppc_vr0_regnum + vsr);
+    }
+  else
+    {
+      if (tdep->ppc_fp0_regnum >= 0)
+	record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum + vsr);
+      if (size > 8 && tdep->ppc_vsr0_upper_regnum >= 0)
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_vsr0_upper_regnum + vsr);
+    }
+
+  return 0;
+}
+
+/* Parse instructions of primary opcode-4.  */
+
+static int
+ppc64_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
+			   CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_FIELD (insn, 21, 11);
+
+  if ((ext & 0x3f) == 45)
+    {
+      /* Vector Permute and Exclusive-OR */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+    }
+
+  switch ((ext & 0x1ff))
+    {
+			/* 5.16 Decimal Integer Arithmetic Instructions */
+    case 1:		/* Decimal Add Modulo */
+    case 65:		/* Decimal Subtract Modulo */
+
+      /* Bit-21 should be set.  */
+      if (!PPC_BIT (insn, 21))
+	break;
+
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    }
+
+  /* Bit-21 is used for RC */
+  switch (ext & 0x3ff)
+    {
+    case 6:		/* Vector Compare Equal To Unsigned Byte */
+    case 70:		/* Vector Compare Equal To Unsigned Halfword */
+    case 134:		/* Vector Compare Equal To Unsigned Word */
+    case 199:		/* Vector Compare Equal To Unsigned Doubleword */
+    case 774:		/* Vector Compare Greater Than Signed Byte */
+    case 838:		/* Vector Compare Greater Than Signed Halfword */
+    case 902:		/* Vector Compare Greater Than Signed Word */
+    case 967:		/* Vector Compare Greater Than Signed Doubleword */
+    case 518:		/* Vector Compare Greater Than Unsigned Byte */
+    case 646:		/* Vector Compare Greater Than Unsigned Word */
+    case 582:		/* Vector Compare Greater Than Unsigned Halfword */
+    case 711:		/* Vector Compare Greater Than Unsigned Doubleword */
+    case 966:		/* Vector Compare Bounds Single-Precision */
+    case 198:		/* Vector Compare Equal To Single-Precision */
+    case 454:		/* Vector Compare Greater Than or Equal To Single-Precision */
+    case 710:		/* Vector Compare Greater Than Single-Precision */
+      if (PPC_Rc (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+    }
+
+  switch (ext)
+    {
+    /* 5.8 Vector Permute and Formatting Instructions */
+    case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
+    case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
+    case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
+    case 334:		/* Vector Pack Signed Word Unsigned Saturate */
+    case 398:		/* Vector Pack Signed Halfword Signed Saturate */
+    case 462:		/* Vector Pack Signed Word Signed Saturate */
+    case 1230:		/* Vector Pack Unsigned Doubleword Unsigned Saturate */
+    case 1358:		/* Vector Pack Signed Doubleword Unsigned Saturate */
+    case 1486:		/* Vector Pack Signed Doubleword Signed Saturate */
+			/* 5.9 Vector Integer Instructions */
+    case 512:		/* Vector Add Unsigned Byte Saturate */
+    case 576:		/* Vector Add Unsigned Halfword Saturate */
+    case 640:		/* Vector Add Unsigned Word Saturate */
+    case 786:		/* Vector Add Signed Byte Saturate */
+    case 832:		/* Vector Add Signed Halfword Saturate */
+    case 896:		/* Vector Add Signed Word Saturate */
+    case 1536:		/* Vector Subtract Unsigned Byte Saturate */
+    case 1600:		/* Vector Subtract Unsigned Halfword Saturate */
+    case 1664:		/* Vector Subtract Unsigned Word Saturate */
+    case 1792:		/* Vector Subtract Signed Byte Saturate */
+    case 1856:		/* Vector Subtract Signed Halfword Saturate */
+    case 1920:		/* Vector Subtract Signed Word Saturate */
+    case 32:		/* Vector Multiply-High-Add Signed Halfword Saturate */
+    case 33:		/* Vector Multiply-High-Round-Add Signed Halfword Saturate */
+    case 39:		/* Vector Multiply-Sum Unsigned Halfword Saturate */
+    case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
+    case 1544:		/* Vector Sum across Quarter Unsigned Byte Saturate */
+    case 1800:		/* Vector Sum across Quarter Signed Byte Saturate */
+    case 1608:		/* Vector Sum across Quarter Signed Halfword Saturate */
+    case 1672:		/* Vector Sum across Half Signed Word Saturate */
+    case 1928:		/* Vector Sum across Signed Word Saturate */
+			/* 5.10 Vector Floating-Point Instruction Set */
+    case 970:		/* Vector Convert To Signed Fixed-Point Word Saturate */
+    case 906:		/* Vector Convert To Unsigned Fixed-Point Word Saturate */
+      record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
+      /* FALL-THROUGH */
+			/* 5.8 Vector Permute and Formatting Instructions */
+    case 12:		/* Vector Merge High Byte */
+    case 14:		/* Vector Pack Unsigned Halfword Unsigned Modulo */
+    case 42:		/* Vector Select */
+    case 43:		/* Vector Permute */
+    case 76:		/* Vector Merge High Halfword */
+    case 78:		/* Vector Pack Unsigned Word Unsigned Modulo */
+    case 140:		/* Vector Merge High Word */
+    case 268:		/* Vector Merge Low Byte */
+    case 332:		/* Vector Merge Low Halfword */
+    case 396:		/* Vector Merge Low Word */
+    case 526:		/* Vector Unpack High Signed Byte */
+    case 590:		/* Vector Unpack High Signed Halfword */
+    case 654:		/* Vector Unpack Low Signed Byte */
+    case 718:		/* Vector Unpack Low Signed Halfword */
+    case 782:		/* Vector Pack Pixel */
+    case 846:		/* Vector Unpack High Pixel */
+    case 974:		/* Vector Unpack Low Pixel */
+    case 1102:		/* Vector Pack Unsigned Doubleword Unsigned Modulo */
+    case 1614:		/* Vector Unpack High Signed Word */
+    case 1676:		/* Vector Merge Odd Word */
+    case 1742:		/* Vector Unpack Low Signed Word */
+    case 1932:		/* Vector Merge Even Word */
+    case 524:		/* Vector Splat Byte */
+    case 588:		/* Vector Splat Halfword */
+    case 652:		/* Vector Splat Word */
+    case 780:		/* Vector Splat Immediate Signed Byte */
+    case 844:		/* Vector Splat Immediate Signed Halfword */
+    case 908:		/* Vector Splat Immediate Signed Word */
+    case 44:		/* Vector Shift Left Double by Octet Immediate */
+    case 452:		/* Vector Shift Left */
+    case 708:		/* Vector Shift Right */
+    case 1036:		/* Vector Shift Left by Octet */
+    case 1100:		/* Vector Shift Right by Octet */
+			/* 5.9 Vector Integer Instructions */
+    case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
+    case 61:		/* Vector Add Extended & write Carry Unsigned Quadword */
+    case 62:		/* Vector Subtract Extended Unsigned Quadword Modulo */
+    case 63:		/* Vector Subtract Extended & write Carry Unsigned Quadword */
+    case 0:		/* Vector Add Unsigned Byte Modulo */
+    case 64:		/* Vector Add Unsigned Halfword Modulo */
+    case 128:		/* Vector Add Unsigned Word Modulo */
+    case 192:		/* Vector Add Unsigned Doubleword Modulo */
+    case 256:		/* Vector Add Unsigned Quadword Modulo */
+    case 320:		/* Vector Add & write Carry Unsigned Quadword */
+    case 384:		/* Vector Add and Write Carry-Out Unsigned Word */
+    case 8:		/* Vector Multiply Odd Unsigned Byte */
+    case 72:		/* Vector Multiply Odd Unsigned Halfword */
+    case 136:		/* Vector Multiply Odd Unsigned Word */
+    case 264:		/* Vector Multiply Odd Signed Byte */
+    case 328:		/* Vector Multiply Odd Signed Halfword */
+    case 392:		/* Vector Multiply Odd Signed Word */
+    case 520:		/* Vector Multiply Even Unsigned Byte */
+    case 584:		/* Vector Multiply Even Unsigned Halfword */
+    case 648:		/* Vector Multiply Even Unsigned Word */
+    case 776:		/* Vector Multiply Even Signed Byte */
+    case 840:		/* Vector Multiply Even Signed Halfword */
+    case 940:		/* Vector Multiply Even Signed Word */
+    case 137:		/* Vector Multiply Unsigned Word Modulo */
+    case 1024:		/* Vector Subtract Unsigned Byte Modulo */
+    case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
+    case 1152:		/* Vector Subtract Unsigned Word Modulo */
+    case 1216:		/* Vector Subtract Unsigned Doubleword Modulo */
+    case 1280:		/* Vector Subtract Unsigned Quadword Modulo */
+    case 1344:		/* Vector Subtract & write Carry Unsigned Quadword */
+    case 1408:		/* Vector Subtract and Write Carry-Out Unsigned Word */
+    case 34:		/* Vector Multiply-Low-Add Unsigned Halfword Modulo */
+    case 36:		/* Vector Multiply-Sum Unsigned Byte Modulo */
+    case 37:		/* Vector Multiply-Sum Mixed Byte Modulo */
+    case 38:		/* Vector Multiply-Sum Unsigned Halfword Modulo */
+    case 40:		/* Vector Multiply-Sum Signed Halfword Modulo */
+    case 1282:		/* Vector Average Signed Byte */
+    case 1346:		/* Vector Average Signed Halfword */
+    case 1410:		/* Vector Average Signed Word */
+    case 1026:		/* Vector Average Unsigned Byte */
+    case 1090:		/* Vector Average Unsigned Halfword */
+    case 1154:		/* Vector Average Unsigned Word */
+    case 258:		/* Vector Maximum Signed Byte */
+    case 322:		/* Vector Maximum Signed Halfword */
+    case 386:		/* Vector Maximum Signed Word */
+    case 450:		/* Vector Maximum Signed Doubleword */
+    case 2:		/* Vector Maximum Unsigned Byte */
+    case 66:		/* Vector Maximum Unsigned Halfword */
+    case 130:		/* Vector Maximum Unsigned Word */
+    case 194:		/* Vector Maximum Unsigned Doubleword */
+    case 770:		/* Vector Minimum Signed Byte */
+    case 834:		/* Vector Minimum Signed Halfword */
+    case 898:		/* Vector Minimum Signed Word */
+    case 962:		/* Vector Minimum Signed Doubleword */
+    case 514:		/* Vector Minimum Unsigned Byte */
+    case 578:		/* Vector Minimum Unsigned Halfword */
+    case 642:		/* Vector Minimum Unsigned Word */
+    case 706:		/* Vector Minimum Unsigned Doubleword */
+    case 1028:		/* Vector Logical AND */
+    case 1668:		/* Vector Logical Equivalent */
+    case 1092:		/* Vector Logical AND with Complement */
+    case 1412:		/* Vector Logical NAND */
+    case 1348:		/* Vector Logical OR with Complement */
+    case 1156:		/* Vector Logical OR */
+    case 1284:		/* Vector Logical NOR */
+    case 1220:		/* Vector Logical XOR */
+    case 4:		/* Vector Rotate Left Byte */
+    case 132:		/* Vector Rotate Left Word VX-form */
+    case 68:		/* Vector Rotate Left Halfword */
+    case 196:		/* Vector Rotate Left Doubleword */
+    case 260:		/* Vector Shift Left Byte */
+    case 388:		/* Vector Shift Left Word */
+    case 324:		/* Vector Shift Left Halfword */
+    case 1476:		/* Vector Shift Left Doubleword */
+    case 516:		/* Vector Shift Right Byte */
+    case 644:		/* Vector Shift Right Word */
+    case 580:		/* Vector Shift Right Halfword */
+    case 1732:		/* Vector Shift Right Doubleword */
+    case 772:		/* Vector Shift Right Algebraic Byte */
+    case 900:		/* Vector Shift Right Algebraic Word */
+    case 836:		/* Vector Shift Right Algebraic Halfword */
+    case 864:		/* Vector Shift Right Algebraic Doubleword */
+			/* 5.10 Vector Floating-Point Instruction Set */
+    case 10:		/* Vector Add Single-Precision */
+    case 74:		/* Vector Subtract Single-Precision */
+    case 46:		/* Vector Multiply-Add Single-Precision */
+    case 47:		/* Vector Negative Multiply-Subtract Single-Precision */
+    case 1034:		/* Vector Maximum Single-Precision */
+    case 1098:		/* Vector Minimum Single-Precision */
+    case 842:		/* Vector Convert From Signed Fixed-Point Word */
+    case 778:		/* Vector Convert From Unsigned Fixed-Point Word */
+    case 714:		/* Vector Round to Single-Precision Integer toward -Infinity */
+    case 522:		/* Vector Round to Single-Precision Integer Nearest */
+    case 650:		/* Vector Round to Single-Precision Integer toward +Infinity */
+    case 586:		/* Vector Round to Single-Precision Integer toward Zero */
+    case 394:		/* Vector 2 Raised to the Exponent Estimate Floating-Point */
+    case 458:		/* Vector Log Base 2 Estimate Floating-Point */
+    case 266:		/* Vector Reciprocal Estimate Single-Precision */
+    case 330:		/* Vector Reciprocal Square Root Estimate Single-Precision */
+			/* 5.11 Vector Exclusive-OR-based Instructions */
+    case 1288:		/* Vector AES Cipher */
+    case 1289:		/* Vector AES Cipher Last */
+    case 1352:		/* Vector AES Inverse Cipher */
+    case 1353:		/* Vector AES Inverse Cipher Last */
+    case 1480:		/* Vector AES SubBytes */
+    case 1730:		/* Vector SHA-512 Sigma Doubleword */
+    case 1666:		/* Vector SHA-256 Sigma Word */
+    case 1032:		/* Vector Polynomial Multiply-Sum Byte */
+    case 1160:		/* Vector Polynomial Multiply-Sum Word */
+    case 1096:		/* Vector Polynomial Multiply-Sum Halfword */
+    case 1224:		/* Vector Polynomial Multiply-Sum Doubleword */
+			/* 5.12 Vector Gather Instruction */
+    case 1292:		/* Vector Gather Bits by Bytes by Doubleword */
+			/* 5.13 Vector Count Leading Zeros Instructions */
+    case 1794:		/* Vector Count Leading Zeros Byte */
+    case 1858:		/* Vector Count Leading Zeros Halfword */
+    case 1922:		/* Vector Count Leading Zeros Word */
+    case 1986:		/* Vector Count Leading Zeros Doubleword */
+			/* 5.14 Vector Population Count Instructions */
+    case 1795:		/* Vector Population Count Byte */
+    case 1859:		/* Vector Population Count Halfword */
+    case 1923:		/* Vector Population Count Word */
+    case 1987:		/* Vector Population Count Doubleword */
+			/* 5.15 Vector Bit Permute Instruction */
+    case 1356:		/* Vector Bit Permute Quadword */
+			/* 5.16 Decimal Integer Arithmetic Instructions */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+
+			/* 5.17 Vector Status and Control Register Instructions */
+    case 1604:		/* Move To Vector Status and Control Register */
+      record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
+      return 0;
+    case 1540:		/* Move From Vector Status and Control Register */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+		      "%08x at %08lx, 4-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-19.  */
+
+static int
+ppc64_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
+			   CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+
+  switch (ext)
+    {
+    case 0:		/* Move Condition Register Field */
+    case 33:		/* Condition Register NOR */
+    case 129:		/* Condition Register AND with Complement */
+    case 193:		/* Condition Register XOR */
+    case 225:		/* Condition Register NAND */
+    case 257:		/* Condition Register AND */
+    case 289:		/* Condition Register Equivalent */
+    case 417:		/* Condition Register OR with Complement */
+    case 449:		/* Condition Register OR */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 16:		/* Branch Conditional */
+    case 560:		/* Branch Conditional to Branch Target Address Register */
+      if (PPC_BO (insn) & 0x2)
+	record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+      /* FALL-THROUGH */
+    case 528:		/* Branch Conditional to Count Register */
+      if (PPC_LK (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+      return 0;
+
+    case 150:		/* Instruction Synchronize */
+      /* Do nothing.  */
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+		      "%08x at %08lx, 19-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-31.  */
+
+static int
+ppc64_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
+			   CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+  int tmp, nr, nb, i;
+  CORE_ADDR at_dcsz, at_icsz, ea = 0;
+  ULONGEST rb, ra, xer;
+  int size = 0;
+
+  /* These instructions have OE bit.  */
+  switch (ext & 0x1ff)
+    {
+    /* These write RT and XER.  Update CR if RC is set.  */
+    case 8:		/* Subtract from carrying */
+    case 10:		/* Add carrying */
+    case 136:		/* Subtract from extended */
+    case 138:		/* Add extended */
+    case 200:		/* Subtract from zero extended */
+    case 202:		/* Add to zero extended */
+    case 232:		/* Subtract from minus one extended */
+    case 234:		/* Add to minus one extended */
+      /* CA is always altered, but SO/OV are only altered when OE=1.
+	 In any case, XER is always altered.  */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
+    /* These write RT.  Update CR if RC is set and update XER if OE is set.  */
+    case 40:		/* Subtract from */
+    case 104:		/* Negate */
+    case 233:		/* Multiply low doubleword */
+    case 235:		/* Multiply low word */
+    case 266:		/* Add */
+    case 393:		/* Divide Doubleword Extended Unsigned */
+    case 395:		/* Divide Word Extended Unsigned */
+    case 425:		/* Divide Doubleword Extended */
+    case 427:		/* Divide Word Extended */
+    case 457:		/* Divide Doubleword Unsigned */
+    case 459:		/* Divide Word Unsigned */
+    case 489:		/* Divide Doubleword */
+    case 491:		/* Divide Word */
+      if (PPC_OE (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      /* FALL-THROUGH */
+    case 9:		/* Multiply High Doubleword Unsigned */
+    case 11:		/* Multiply High Word Unsigned */
+    case 73:		/* Multiply High Doubleword */
+    case 75:		/* Multiply High Word */
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
+  if ((ext & 0x1f) == 15)
+    {
+      /* Integer Select. bit[16:20] is used for BC.  */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
+  switch (ext)
+    {
+    case 78:		/* Determine Leftmost Zero Byte */
+      /* CA is always altered, but SO/OV are only altered when OE=1.
+	 In any case, XER is always altered.  */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
+    /* These only write RT.  */
+    case 19:		/* Move from condition register */
+			/* Move From One Condition Register Field */
+    case 74:		/* Add and Generate Sixes */
+    case 74 | 0x200:	/* Add and Generate Sixes (bit-21 dont-care) */
+    case 302:		/* Move From Branch History Rolling Buffer */
+    case 334:		/* Move From Performance Monitor Register */
+    case 339:		/* Move From Special Purpose Register */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
+    /* These only write to RA.  */
+    case 51:		/* Move From VSR Doubleword */
+    case 115:		/* Move From VSR Word and Zero */
+    case 122:		/* Population count bytes */
+    case 378:		/* Population count words */
+    case 506:		/* Population count doublewords */
+    case 154:		/* Parity Word */
+    case 186:		/* Parity Doubleword */
+    case 252:		/* Bit Permute Doubleword */
+    case 282:		/* Convert Declets To Binary Coded Decimal */
+    case 314:		/* Convert Binary Coded Decimal To Declets */
+    case 508:		/* Compare bytes */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      return 0;
+
+    /* These write CR and optional RA.  */
+    case 792:		/* Shift Right Algebraic Word */
+    case 794:		/* Shift Right Algebraic Doubleword */
+    case 824:		/* Shift Right Algebraic Word Immediate */
+    case 826:		/* Shift Right Algebraic Doubleword Immediate (413) */
+    case 826 | 1:	/* Shift Right Algebraic Doubleword Immediate (413) */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 0:		/* Compare */
+    case 32:		/* Compare logical */
+    case 144:		/* Move To Condition Register Fields */
+			/* Move To One Condition Register Field */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    /* These write to RT.  Update RA if 'update indexed.'  */
+    case 53:		/* Load Doubleword with Update Indexed */
+    case 119:		/* Load Byte and Zero with Update Indexed */
+    case 311:		/* Load Halfword and Zero with Update Indexed */
+    case 55:		/* Load Word and Zero with Update Indexed */
+    case 375:		/* Load Halfword Algebraic with Update Indexed */
+    case 373:		/* Load Word Algebraic with Update Indexed */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 21:		/* Load Doubleword Indexed */
+    case 52:		/* Load Byte And Reserve Indexed */
+    case 116:		/* Load Halfword And Reserve Indexed */
+    case 20:		/* Load Word And Reserve Indexed */
+    case 84:		/* Load Doubleword And Reserve Indexed */
+    case 87:		/* Load Byte and Zero Indexed */
+    case 279:		/* Load Halfword and Zero Indexed */
+    case 23:		/* Load Word and Zero Indexed */
+    case 343:		/* Load Halfword Algebraic Indexed */
+    case 341:		/* Load Word Algebraic Indexed */
+    case 790:		/* Load Halfword Byte-Reverse Indexed */
+    case 534:		/* Load Word Byte-Reverse Indexed */
+    case 532:		/* Load Doubleword Byte-Reverse Indexed */
+    case 853:		/* Load Byte and Zero Caching Inhibited Indexed */
+    case 821:		/* Load Halfword and Zero Caching Inhibited Indexed */
+    case 789:		/* Load Word and Zero Caching Inhibited Indexed */
+    case 885:		/* Load Doubleword Caching Inhibited Indexed */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
+    case 597:		/* Load String Word Immediate */
+    case 533:		/* Load String Word Indexed */
+      if (ext == 597)
+	nr = PPC_NB (insn);
+      else
+	{
+	  regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
+	  nr = PPC_XER_NB (xer);
+	}
+
+      nr = (nr + 3) >> 2;
+
+      for (i = 0; i < nr; i++)
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + ((PPC_RT (insn) + i) & 0x1f));
+      return 0;
+
+    case 276:		/* Load Quadword And Reserve Indexed */
+      tmp = (tdep->ppc_gp0_regnum + PPC_RT (insn)) & ~1;
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp | 1);
+      return 0;
+
+    /* These write VRT.  */
+    case 6:		/* Load Vector for Shift Left Indexed */
+    case 38:		/* Load Vector for Shift Right Indexed */
+    case 7:		/* Load Vector Element Byte Indexed */
+    case 39:		/* Load Vector Element Halfword Indexed */
+    case 71:		/* Load Vector Element Word Indexed */
+    case 103:		/* Load Vector Indexed */
+    case 359:		/* Load Vector Indexed LRU */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+
+    /* These write FRT.  Update RA if 'update indexed.'  */
+    case 567:		/* Load Floating-Point Single with Update Indexed */
+    case 631:		/* Load Floating-Point Double with Update Indexed */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 535:		/* Load Floating-Point Single Indexed */
+    case 599:		/* Load Floating-Point Double Indexed */
+    case 855:		/* Load Floating-Point as Integer Word Algebraic Indexed */
+    case 887:		/* Load Floating-Point as Integer Word and Zero Indexed */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      return 0;
+
+    case 791:		/* Load Floating-Point Double Pair Indexed */
+      tmp = (tdep->ppc_fp0_regnum + PPC_FRT (insn)) & ~1;
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp | 1);
+      return 0;
+
+    /* These write VSR of size 8.  */
+    case 588:		/* Load VSX Scalar Doubleword Indexed */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn), 8);
+      return 0;
+
+    /* These write VSR of size 16.  */
+    case 179:		/* Move To VSR Doubleword */
+    case 211:		/* Move To VSR Word Algebraic */
+    case 243:		/* Move To VSR Word and Zero */
+    case 524:		/* Load VSX Scalar Single-Precision Indexed */
+    case 76:		/* Load VSX Scalar as Integer Word Algebraic Indexed */
+    case 12:		/* Load VSX Scalar as Integer Word and Zero Indexed */
+    case 844:		/* Load VSX Vector Doubleword*2 Indexed */
+    case 332:		/* Load VSX Vector Doubleword & Splat Indexed */
+    case 780:		/* Load VSX Vector Word*4 Indexed */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn), 16);
+      return 0;
+
+    /* These write RA.  Update CR if RC is set.  */
+    case 24:		/* Shift Left Word */
+    case 26:		/* Count Leading Zeros Word */
+    case 27:		/* Shift Left Doubleword */
+    case 28:		/* AND */
+    case 58:		/* Count Leading Zeros Doubleword */
+    case 60:		/* AND with Complement */
+    case 124:		/* NOR */
+    case 284:		/* Equivalent */
+    case 316:		/* XOR */
+    case 476:		/* NAND */
+    case 412:		/* OR with Complement */
+    case 444:		/* OR */
+    case 536:		/* Shift Right Word */
+    case 539:		/* Shift Right Doubleword */
+    case 922:		/* Extend Sign Halfword */
+    case 954:		/* Extend Sign Byte */
+    case 986:		/* Extend Sign Word */
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      return 0;
+
+    /* Store memory.  */
+    case 181:		/* Store Doubleword with Update Indexed */
+    case 183:		/* Store Word with Update Indexed */
+    case 247:		/* Store Byte with Update Indexed */
+    case 439:		/* Store Half Word with Update Indexed */
+    case 695:		/* Store Floating-Point Single with Update Indexed */
+    case 759:		/* Store Floating-Point Double with Update Indexed */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 135:		/* Store Vector Element Byte Indexed */
+    case 167:		/* Store Vector Element Halfword Indexed */
+    case 199:		/* Store Vector Element Word Indexed */
+    case 231:		/* Store Vector Indexed */
+    case 487:		/* Store Vector Indexed LRU */
+    case 716:		/* Store VSX Scalar Doubleword Indexed */
+    case 140:		/* Store VSX Scalar as Integer Word Indexed */
+    case 652:		/* Store VSX Scalar Single-Precision Indexed */
+    case 972:		/* Store VSX Vector Doubleword*2 Indexed */
+    case 908:		/* Store VSX Vector Word*4 Indexed */
+    case 149:		/* Store Doubleword Indexed */
+    case 151:		/* Store Word Indexed */
+    case 215:		/* Store Byte Indexed */
+    case 407:		/* Store Half Word Indexed */
+    case 694:		/* Store Byte Conditional Indexed */
+    case 726:		/* Store Halfword Conditional Indexed */
+    case 150:		/* Store Word Conditional Indexed */
+    case 214:		/* Store Doubleword Conditional Indexed */
+    case 182:		/* Store Quadword Conditional Indexed */
+    case 662:		/* Store Word Byte-Reverse Indexed */
+    case 918:		/* Store Halfword Byte-Reverse Indexed */
+    case 660:		/* Store Doubleword Byte-Reverse Indexed */
+    case 663:		/* Store Floating-Point Single Indexed */
+    case 727:		/* Store Floating-Point Double Indexed */
+    case 981:		/* Store Byte Caching Inhibited Indexed */
+    case 949:		/* Store Halfword Caching Inhibited Indexed */
+    case 917:		/* Store Word Caching Inhibited Indexed */
+    case 1013:		/* Store Doubleword Caching Inhibited Indexed */
+    case 919:		/* Store Floating-Point Double Pair Indexed */
+    case 983:		/* Store Floating-Point as Integer Word Indexed */
+      if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182)
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+      regcache_raw_read_unsigned (regcache,
+				  tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+      ea = ra + rb;
+
+      switch (ext)
+	{
+	case 183:	/* Store Word with Update Indexed */
+	case 199:	/* Store Vector Element Word Indexed */
+	case 140:	/* Store VSX Scalar as Integer Word Indexed */
+	case 652:	/* Store VSX Scalar Single-Precision Indexed */
+	case 151:	/* Store Word Indexed */
+	case 150:	/* Store Word Conditional Indexed */
+	case 917:	/* Store Word Caching Inhibited Indexed */
+	case 663:	/* Store Floating-Point Single Indexed */
+	case 695:	/* Store Floating-Point Single with Update Indexed */
+	case 983:	/* Store Floating-Point as Integer Word Indexed */
+	  size = 4;
+	  break;
+	case 247:	/* Store Byte with Update Indexed */
+	case 135:	/* Store Vector Element Byte Indexed */
+	case 215:	/* Store Byte Indexed */
+	case 694:	/* Store Byte Conditional Indexed */
+	case 662:	/* Store Word Byte-Reverse Indexed */
+	case 981:	/* Store Byte Caching Inhibited Indexed */
+	  size = 1;
+	  break;
+	case 439:	/* Store Half Word with Update Indexed */
+	case 167:	/* Store Vector Element Halfword Indexed */
+	case 407:	/* Store Half Word Indexed */
+	case 726:	/* Store Halfword Conditional Indexed */
+	case 918:	/* Store Halfword Byte-Reverse Indexed */
+	case 949:	/* Store Halfword Caching Inhibited Indexed */
+	  size = 2;
+	  break;
+	case 181:	/* Store Doubleword with Update Indexed */
+	case 716:	/* Store VSX Scalar Doubleword Indexed */
+	case 149:	/* Store Doubleword Indexed */
+	case 214:	/* Store Doubleword Conditional Indexed */
+	case 660:	/* Store Doubleword Byte-Reverse Indexed */
+	case 1013:	/* Store Doubleword Caching Inhibited Indexed */
+	  size = 8;
+	  break;
+	case 972:	/* Store VSX Vector Doubleword*2 Indexed */
+	case 908:	/* Store VSX Vector Word*4 Indexed */
+	case 182:	/* Store Quadword Conditional Indexed */
+	case 231:	/* Store Vector Indexed */
+	case 487:	/* Store Vector Indexed LRU */
+	case 919:	/* Store Floating-Point Double Pair Indexed */
+	  size = 16;
+	  break;
+	}
+
+      /* Align address for Store Vector instructions.  */
+      if ((ext & 0x1f) == 0x7)
+	{
+	  if ((ext & 0x3) < 3)
+	    addr = (addr >> (ext & 0x3)) << (ext & 0x3);
+	  else
+	    addr = addr & ~0x7ULL;
+	}
+
+      record_full_arch_list_add_mem (addr, size);
+      return 0;
+
+    case 725:		/* Store String Word Immediate */
+    case 661:		/* Store String Word Indexed */
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+	regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+      ea += ra;
+
+      if (ext == 725)
+	nb = PPC_NB (insn);
+      else
+	{
+	  regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
+	  nb = PPC_XER_NB (xer);
+
+	  regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &rb);
+	  ea += rb;
+	}
+
+      record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
+    case 467:		/* Move To Special Purpose Register */
+      switch (PPC_SPR (insn))
+	{
+	case 1:			/* XER */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+	  return 0;
+	case 8:			/* LR */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+	  return 0;
+	case 9:			/* CTR */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+	  return 0;
+	}
+
+      goto UNKNOWN_OP;
+
+    case 147:		/* Move To Split Little Endian */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
+      return 0;
+
+    case 512:		/* Move to Condition Register from XER */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      return 0;
+
+    case 4:		/* Trap Word */
+    case 68:		/* Trap Doubleword */
+    case 430:		/* Clear BHRB */
+    case 598:		/* Synchronize */
+    case 62:		/* Wait for Interrupt */
+    case 22:		/* Instruction Cache Block Touch */
+    case 854:		/* Enforce In-order Execution of I/O */
+    case 246:		/* Data Cache Block Touch for Store */
+    case 54:		/* Data Cache Block Store */
+    case 86:		/* Data Cache Block Flush */
+    case 278:		/* Data Cache Block Touch */
+    case 758:		/* Data Cache Block Allocate */
+      return 0;
+
+    case 18:		/* TLB Invalidate Local Indexed */
+    case 326:		/* Data Cache Read */
+    case 63:		/* Data Cache Block Store by External PID */
+    case 127:		/* Data Cache Block Flush by External PID */
+    case 134:		/* Data Cache Block Touch for Store and Lock Set */
+    case 166:		/* Data Cache Block Touch and Lock Set */
+    case 255:		/* Data Cache Block Touch for Store by External PID */
+    case 319:		/* Data Cache Block Touch by External PID */
+    case 390:		/* Data Cache Block Lock Clear */
+    case 422:		/* Data Cache Block Lock Query */
+    case 454:		/* Data Cache Invalidate */
+    case 998:		/* Instruction Cache Read */
+    case 966:		/* Instruction Cache Invalidate */
+    case 982:		/* Instruction Cache Block Invalidate */
+    case 198:		/* Instruction Cache Block Lock Query */
+    case 230:		/* Instruction Cache Block Lock Clear */
+    case 486:		/* Instruction Cache Block Touch and Lock Set */
+    case 206:		/* Message Send */
+    case 238:		/* Message Clear */
+    case 142:		/* Message Send Privileged */
+    case 174:		/* Message Clear Privileged */
+    case 131:		/* Write MSR External Enable */
+    case 163:		/* Write MSR External Enable Immediate */
+    case 270:		/* Embedded Hypervisor Privilege */
+    case 462:		/* Move To Performance Monitor Register */
+    case 494:		/* Move To Thread Management Register */
+    case 807:		/* Store Vector by External Process ID Indexed */
+    case 775:		/* Store Vector by External Process ID Indexed LRU */
+    case 95:		/* Load Byte by External Process ID Indexed */
+    case 287:		/* Load Halfword by External Process ID Indexed */
+    case 31:		/* Load Word by External Process ID Indexed */
+    case 29:		/* Load Doubleword by External Process ID Indexed */
+    case 295:		/* Load Vector by External Process ID Indexed */
+    case 263:		/* Load Vector by External Process ID Indexed LRU */
+    case 259:		/* Move From Device Control Register Indexed */
+    case 323:		/* Move From Device Control Register */
+    case 146:		/* Move To Machine State Register */
+    case 178:		/* Move To Machine State Register Doubleword */
+    case 387:		/* Move To Device Control Register Indexed */
+    case 419:		/* Move To Device Control Register User-mode Indexed */
+    case 291:		/* Move From Device Control Register User-mode Indexed */
+    case 451:		/* Move To Device Control Register */
+      /* Privileged instructions.  */
+      fprintf_unfiltered (gdb_stdlog, "Cannot record privileged instructions. "
+			  "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+      return -1;
+
+    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 */
+    case 942:		/* Transaction Reclaim */
+    case 1006:		/* Transaction Recheckpoint */
+      fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
+			  "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+      return -1;
+
+    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)  */
+
+      if (PPC_RA (insn) != 0)
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+      regcache_raw_read_unsigned (regcache,
+				  tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+      ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
+      record_full_arch_list_add_mem (ea, at_dcsz);
+      return 0;
+    }
+
+UNKNOWN_OP:
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+		      "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-59.  */
+
+static int
+ppc64_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
+			   CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+
+  switch (ext & 0x1f)
+    {
+    case 18:		/* Floating Divide */
+    case 20:		/* Floating Subtract */
+    case 21:		/* Floating Add */
+    case 22:		/* Floating Square Root */
+    case 24:		/* Floating Reciprocal Estimate */
+    case 25:		/* Floating Multiply */
+    case 26:		/* Floating Reciprocal Square Root Estimate */
+    case 28:		/* Floating Multiply-Subtract */
+    case 29:		/* Floating Multiply-Add */
+    case 30:		/* Floating Negative Multiply-Subtract */
+    case 31:		/* Floating Negative Multiply-Add */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+      return 0;
+    }
+
+  switch (ext)
+    {
+    case 2:		/* DFP Add */
+    case 3:		/* DFP Quantize */
+    case 34:		/* DFP Multiply */
+    case 35:		/* DFP Reround */
+    case 67:		/* DFP Quantize Immediate */
+    case 99:		/* DFP Round To FP Integer With Inexact */
+    case 227:		/* DFP Round To FP Integer Without Inexact */
+    case 258:		/* DFP Convert To DFP Long! */
+    case 290:		/* DFP Convert To Fixed */
+    case 514:		/* DFP Subtract */
+    case 546:		/* DFP Divide */
+    case 770:		/* DFP Round To DFP Short! */
+    case 802:		/* DFP Convert From Fixed */
+    case 834:		/* DFP Encode BCD To DPD */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      /* FALL-THROUGH */
+    case 130:		/* DFP Compare Ordered */
+    case 162:		/* DFP Test Exponent */
+    case 194:		/* DFP Test Data Class */
+    case 226:		/* DFP Test Data Group */
+    case 642:		/* DFP Compare Unordered */
+    case 674:		/* DFP Test Significance */
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 66:		/* DFP Shift Significand Left Immediate */
+    case 98:		/* DFP Shift Significand Right Immediate */
+    case 322:		/* DFP Decode DPD To BCD */
+    case 354:		/* DFP Extract Biased Exponent */
+    case 866:		/* DFP Insert Biased Exponent */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 846:		/* Floating Convert From Integer Doubleword Single */
+    case 974:		/* Floating Convert From Integer Doubleword Unsigned
+			   Single */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+		      "%08x at %08lx, 59-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-60.  */
+
+static int
+ppc64_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
+			   CORE_ADDR addr, uint32_t insn)
+{
+  int ext = PPC_EXTOP (insn);
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+		      "%08x at %08lx, 60-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-63.  */
+
+static int
+ppc64_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
+			   CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+  int tmp;
+
+  switch (ext & 0x1f)
+    {
+    case 18:		/* Floating Divide */
+    case 20:		/* Floating Subtract */
+    case 21:		/* Floating Add */
+    case 22:		/* Floating Square Root */
+    case 24:		/* Floating Reciprocal Estimate */
+    case 25:		/* Floating Multiply */
+    case 26:		/* Floating Reciprocal Square Root Estimate */
+    case 28:		/* Floating Multiply-Subtract */
+    case 29:		/* Floating Multiply-Add */
+    case 30:		/* Floating Negative Multiply-Subtract */
+    case 31:		/* Floating Negative Multiply-Add */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+    }
+
+  switch (ext)
+    {
+    case 2:		/* DFP Add */
+    case 3:		/* DFP Quantize */
+    case 34:		/* DFP Multiply */
+    case 35:		/* DFP Reround */
+    case 67:		/* DFP Quantize Immediate */
+    case 99:		/* DFP Round To FP Integer With Inexact */
+    case 227:		/* DFP Round To FP Integer Without Inexact */
+    case 258:		/* DFP Convert To DFP Extended */
+    case 290:		/* DFP Convert To Fixed */
+    case 514:		/* DFP Subtract */
+    case 546:		/* DFP Divide */
+    case 770:		/* DFP Round To DFP Long */
+    case 802:		/* DFP Convert From Fixed */
+    case 834:		/* DFP Encode BCD To DPD */
+      tmp = (tdep->ppc_fp0_regnum + PPC_FRT (insn)) & ~1;
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp | 1);
+      /* FALL-THROUGH */
+    case 130:		/* DFP Compare Ordered */
+    case 162:		/* DFP Test Exponent */
+    case 194:		/* DFP Test Data Class */
+    case 226:		/* DFP Test Data Group */
+    case 642:		/* DFP Compare Unordered */
+    case 674:		/* DFP Test Significance */
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 66:		/* DFP Shift Significand Left Immediate */
+    case 98:		/* DFP Shift Significand Right Immediate */
+    case 322:		/* DFP Decode DPD To BCD */
+    case 354:		/* DFP Extract Biased Exponent */
+    case 866:		/* DFP Insert Biased Exponent */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 12:		/* Floating Round to Single-Precision */
+    case 14:		/* Floating Convert To Integer Word */
+    case 15:		/* Floating Convert To Integer Word
+			   with round toward Zero */
+    case 142:		/* Floating Convert To Integer Word Unsigned */
+    case 143:		/* Floating Convert To Integer Word Unsigned
+			   with round toward Zero */
+    case 392:		/* Floating Round to Integer Nearest */
+    case 424:		/* Floating Round to Integer Toward Zero */
+    case 456:		/* Floating Round to Integer Plus */
+    case 488:		/* Floating Round to Integer Minus */
+    case 814:		/* Floating Convert To Integer Doubleword */
+    case 815:		/* Floating Convert To Integer Doubleword
+			   with round toward Zero */
+    case 846:		/* Floating Convert From Integer Doubleword */
+    case 942:		/* Floating Convert To Integer Doubleword Unsigned */
+    case 943:		/* Floating Convert To Integer Doubleword Unsigned
+			   with round toward Zero */
+    case 974:		/* Floating Convert From Integer Doubleword Unsigned */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 8:		/* Floating Copy Sign */
+    case 40:		/* Floating Negate */
+    case 72:		/* Floating Move Register */
+    case 136:		/* Floating Negative Absolute Value */
+    case 264:		/* Floating Absolute Value */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 838:		/* Floating Merge Odd Word */
+    case 966:		/* Floating Merge Even Word */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      return 0;
+
+    case 0:		/* Floating Compare Unordered */
+    case 32:		/* Floating Compare Ordered */
+    case 38:		/* Move To FPSCR Bit 1 */
+    case 64:		/* Move to Condition Register from FPSCR */
+    case 70:		/* Move To FPSCR Bit 0 */
+    case 134:		/* Move To FPSCR Field Immediate */
+    case 711:		/* Move To FPSCR Fields */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 23:		/* Floating Select */
+    case 128:		/* Floating Test for software Divide */
+    case 160:		/* Floating Test for software Square Root */
+    case 583:		/* Move From FPSCR */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+		      "%08x at %08lx, 59-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse the current instruction and record the values of the registers and
+   memory that will be changed in current instruction to "record_arch_list".
+   Return -1 if something wrong.  */
+
+int
+ppc64_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
+		      CORE_ADDR addr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  uint32_t insn;
+  int op6, tmp, i;
+
+  insn = read_memory_unsigned_integer (addr, 4, byte_order);
+  op6 = PPC_OP6 (insn);
+
+  switch (op6)
+    {
+    case 2:		/* Trap Doubleword Immediate */
+    case 3:		/* Trap Word Immediate */
+      /* Do nothing.  */
+      break;
+
+    case 4:
+      if (ppc64_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
+    case 17:		/* System call */
+      if (tdep->syscall_record != NULL)
+	{
+	  if (tdep->syscall_record (regcache) != 0)
+	    return -1;
+	}
+      else
+	{
+	  printf_unfiltered (_("no syscall record support\n"));
+	  return -1;
+	}
+      break;
+
+    case 7:		/* Multiply Low Immediate */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 8:		/* Subtract From Immediate Carrying */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 10:		/* Compare Logical Immediate  */
+    case 11:		/* Compare Immediate */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      break;
+
+    case 13:		/* Add Immediate Carrying and Record */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      /* FALL-THROUGH */
+    case 12:		/* Add Immediate Carrying */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      /* FALL-THROUGH */
+    case 14:		/* Add Immediate */
+    case 15:		/* Add Immediate Shifted */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 16:		/* Branch Conditional */
+      if (PPC_BO (insn) & 0x2)
+	record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+      /* FALL-THROUGH */
+    case 18:		/* Branch */
+      if (PPC_LK (insn))
+	record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+      break;
+
+    case 19:
+      if (ppc64_process_record_op19 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
+    case 20:		/* Rotate Left Word Immediate then Mask Insert */
+    case 21:		/* Rotate Left Word Immediate then AND with Mask */
+    case 23:		/* Rotate Left Word then AND with Mask */
+    case 30:		/* Rotate Left Doubleword Immediate then Clear Left */
+			/* Rotate Left Doubleword Immediate then Clear Right */
+			/* Rotate Left Doubleword Immediate then Clear */
+			/* Rotate Left Doubleword then Clear Left */
+			/* Rotate Left Doubleword then Clear Right */
+			/* Rotate Left Doubleword Immediate then Mask Insert */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      break;
+
+    case 24:		/* OR Immediate */
+    case 25:		/* OR Immediate Shifted */
+    case 26:		/* XOR Immediate */
+    case 27:		/* XOR Immediate Shifted */
+    case 28:		/* AND Immediate */
+    case 29:		/* AND Immediate Shifted */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      break;
+
+    case 31:
+      if (ppc64_process_record_op31 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
+    case 33:		/* Load Word and Zero with Update */
+    case 35:		/* Load Byte and Zero with Update */
+    case 41:		/* Load Halfword and Zero with Update */
+    case 43:		/* Load Halfword Algebraic with Update */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 32:		/* Load Word and Zero */
+    case 34:		/* Load Byte and Zero */
+    case 40:		/* Load Halfword and Zero */
+    case 42:		/* Load Halfword Algebraic */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 46:		/* Load Multiple Word */
+      for (i = PPC_RT (insn); i < 32; i++)
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 56:		/* Load Quadword */
+      tmp = (tdep->ppc_gp0_regnum + PPC_RT (insn)) & ~1;
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp | 1);
+      break;
+
+    case 49:		/* Load Floating-Point Single with Update */
+    case 51:		/* Load Floating-Point Double with Update */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 48:		/* Load Floating-Point Single */
+    case 50:		/* Load Floating-Point Double */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      break;
+
+    case 47:		/* Store Multiple Word */
+	{
+	  ULONGEST addr = 0;
+	  int size;
+
+	  if (PPC_RA (insn) != 0)
+	    regcache_raw_read_unsigned (regcache,
+					tdep->ppc_gp0_regnum + PPC_RA (insn),
+					&addr);
+
+	  addr += PPC_D (insn);
+
+	  for (i = PPC_RS (insn); i < 32; i++)
+	    record_full_arch_list_add_mem (addr + i * 4, 4);
+	}
+      break;
+
+    case 37:		/* Store Word with Update */
+    case 39:		/* Store Byte with Update */
+    case 45:		/* Store Halfword with Update */
+    case 53:		/* Store Floating-Point Single with Update */
+    case 55:		/* Store Floating-Point Double with Update */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 36:		/* Store Word */
+    case 38:		/* Store Byte */
+    case 44:		/* Store Halfword */
+    case 52:		/* Store Floating-Point Single */
+    case 54:		/* Store Floating-Point Double */
+	{
+	  ULONGEST addr = 0;
+	  int size = -1;
+
+	  if (PPC_RA (insn) != 0)
+	    regcache_raw_read_unsigned (regcache,
+					tdep->ppc_gp0_regnum + PPC_RA (insn),
+					&addr);
+	  addr += PPC_D (insn);
+
+	  if (op6 == 36 || op6 == 37 || op6 == 52 || op6 == 53)
+	    size = 4;
+	  else if (op6 == 54 || op6 == 55)
+	    size = 8;
+	  else if (op6 == 44 || op6 == 45)
+	    size = 2;
+	  else if (op6 == 38 || op6 == 39)
+	    size = 1;
+	  else
+	    gdb_assert (0);
+
+	  record_full_arch_list_add_mem (addr, size);
+	}
+      break;
+
+    case 57:		/* Load Floating-Point Double Pair */
+      tmp = (tdep->ppc_fp0_regnum + PPC_RT (insn)) & ~1;
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp | 1);
+      break;
+
+    case 58:		/* Load Doubleword */
+			/* Load Doubleword with Update */
+			/* Load Doubleword Algebraic */
+      if (PPC_FIELD (insn, 30, 2) > 2)
+	    goto UNKNOWN_OP;
+
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      if (PPC_BIT (insn, 31))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum + PPC_RA (insn));
+      break;
+
+    case 59:
+      if (ppc64_process_record_op59 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
+    case 60:
+      if (ppc64_process_record_op60 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
+    case 61:		/* Store Floating-Point Double Pair */
+    case 62:		/* Store Doubleword */
+			/* Store Doubleword with Update */
+			/* Store Quadword with Update */
+	{
+	  ULONGEST addr = 0;
+	  int size;
+	  int sub2 = PPC_FIELD (insn, 30, 2);
+
+	  if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2))
+	    goto UNKNOWN_OP;
+
+	  if (PPC_RA (insn) != 0)
+	    regcache_raw_read_unsigned (regcache,
+					tdep->ppc_gp0_regnum + PPC_RA (insn),
+					&addr);
+
+	  size = ((op6 == 61) || sub2 == 2) ? 16 : 8;
+
+	  addr += PPC_DS (insn) << 2;
+	  record_full_arch_list_add_mem (addr, size);
+
+	  if (op6 == 62 && sub2 == 1)
+	    record_full_arch_list_add_reg (regcache,
+					   tdep->ppc_gp0_regnum +
+					   PPC_RA (insn));
+
+	  break;
+	}
+
+    case 63:
+      if (ppc64_process_record_op63 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
+    default:
+UNKNOWN_OP:
+      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+			  "%08x at %08lx, %d.\n", insn, addr, op6);
+      return -1;
+    }
+
+  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
+    return -1;
+  if (record_full_arch_list_add_end ())
+    return -1;
+  return 0;
+}
+
  /* Initialize the current architecture based on INFO.  If possible, re-use an
     architecture from ARCHES, which is a list of architectures already created
     during this debugging session.
@@ -4154,6 +5660,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      case GDB_OSABI_NETBSD_ELF:
      case GDB_OSABI_UNKNOWN:
        set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
+      frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
        frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
        set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
        frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
@@ -4162,6 +5669,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        set_gdbarch_believe_pcc_promotion (gdbarch, 1);

        set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
+      frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
        frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
        set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
        frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 2c79bc1..77bd462 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1881,7 +1881,8 @@ proc supports_process_record {} {
      }

      if { [istarget "arm*-*-linux*"] || [istarget "x86_64-*-linux*"]
-         || [istarget "i\[34567\]86-*-linux*"] } {
+         || [istarget "i\[34567\]86-*-linux*"]
+         || [istarget "powerpc*-linux*"] } {
  	return 1
      }

@@ -1897,7 +1898,8 @@ proc supports_reverse {} {
      }

      if { [istarget "arm*-*-linux*"] || [istarget "x86_64-*-linux*"]
-         || [istarget "i\[34567\]86-*-linux*"] } {
+         || [istarget "i\[34567\]86-*-linux*"]
+         || [istarget "powerpc*-linux*"] } {
  	return 1
      }

-- 



More information about the Gdb-patches mailing list