ubsan: bpf: left shift cannot be represented in type 'DI' (aka 'long')
[deliverable/binutils-gdb.git] / gdb / aix-thread.c
index 4ad6a479a968d7ab27812260b9979f1e8fc93856..35b77fe4ec0c719d41344c02c7ab2839f8f91c9c 100644 (file)
@@ -1,13 +1,13 @@
 /* Low level interface for debugging AIX 4.3+ pthreads.
 
-   Copyright (C) 1999, 2000, 2002, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1999-2019 Free Software Foundation, Inc.
    Written by Nick Duffek <nsd@redhat.com>.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 /* This module uses the libpthdebug.a library provided by AIX 4.3+ for
      */
 
 #include "defs.h"
-#include "gdb_assert.h"
 #include "gdbthread.h"
 #include "target.h"
 #include "inferior.h"
 #include "regcache.h"
 #include "gdbcmd.h"
 #include "ppc-tdep.h"
-#include "gdb_string.h"
-#include "observer.h"
+#include "observable.h"
+#include "objfiles.h"
 
 #include <procinfo.h>
 #include <sys/types.h>
 #include <sched.h>
 #include <sys/pthdebug.h>
 
+#if !HAVE_DECL_GETTHRDS
+extern int getthrds (pid_t, struct thrdsinfo64 *, int, tid_t *, int);
+#endif
+
 /* Whether to emit debugging output.  */
-static int debug_aix_thread;
+static bool debug_aix_thread;
 
 /* In AIX 5.1, functions use pthdb_tid_t instead of tid_t.  */
 #ifndef PTHDB_VERSION_3
@@ -69,13 +70,7 @@ static int debug_aix_thread;
 
 /* Return whether to treat PID as a debuggable thread id.  */
 
-#define PD_TID(ptid)   (pd_active && ptid_get_tid (ptid) != 0)
-
-/* Build a thread ptid.  */
-#define BUILD_THREAD(TID, PID) ptid_build (PID, 0, TID)
-
-/* Build and lwp ptid.  */
-#define BUILD_LWP(LWP, PID) MERGEPID (PID, LWP)
+#define PD_TID(ptid)   (pd_active && ptid.tid () != 0)
 
 /* pthdb_user_t value that we pass to pthdb functions.  0 causes
    PTHDB_BAD_USER errors, so use 1.  */
@@ -89,11 +84,20 @@ static int debug_aix_thread;
 
 /* Private data attached to each element in GDB's thread list.  */
 
-struct private_thread_info {
+struct aix_thread_info : public private_thread_info
+{
   pthdb_pthread_t pdtid;        /* thread's libpthdebug id */
   pthdb_tid_t tid;                     /* kernel thread id */
 };
 
+/* Return the aix_thread_info attached to THREAD.  */
+
+static aix_thread_info *
+get_aix_thread_info (thread_info *thread)
+{
+  return static_cast<aix_thread_info *> (thread->priv.get ());
+}
+
 /* Information about a thread of which libpthdebug is aware.  */
 
 struct pd_thread {
@@ -104,13 +108,46 @@ struct pd_thread {
 
 /* This module's target-specific operations, active while pd_able is true.  */
 
-static struct target_ops aix_thread_ops;
+static const target_info aix_thread_target_info = {
+  "aix-threads",
+  N_("AIX pthread support"),
+  N_("AIX pthread support")
+};
+
+class aix_thread_target final : public target_ops
+{
+public:
+  const target_info &info () const override
+  { return aix_thread_target_info; }
+
+  strata stratum () const override { return thread_stratum; }
+
+  void detach (inferior *, int) override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+                                       const char *annex,
+                                       gdb_byte *readbuf,
+                                       const gdb_byte *writebuf,
+                                       ULONGEST offset, ULONGEST len,
+                                       ULONGEST *xfered_len) override;
+
+  void mourn_inferior () override;
+
+  bool thread_alive (ptid_t ptid) override;
+
+  std::string pid_to_str (ptid_t) override;
+
+  const char *extra_thread_info (struct thread_info *) override;
 
-/* Copy of the target over which ops is pushed.  This is more
-   convenient than a pointer to deprecated_child_ops or core_ops,
-   because they lack current_target's default callbacks.  */
+  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+};
 
-static struct target_ops base_target;
+static aix_thread_target aix_thread_ops;
 
 /* Address of the function that libpthread will call when libpthdebug
    is ready to be initialized.  */
@@ -166,7 +203,7 @@ static pthdb_session_t pd_session;
 /* Return a printable representation of pthdebug function return
    STATUS.  */
 
-static char *
+static const char *
 pd_status2str (int status)
 {
   switch (status)
@@ -241,7 +278,14 @@ ptrace_check (int req, int id, int ret)
   return 0;  /* Not reached.  */
 }
 
-/* Call ptracex (REQ, ID, ADDR, DATA, BUF).  Return success.  */
+/* Call ptracex (REQ, ID, ADDR, DATA, BUF) or
+   ptrace64 (REQ, ID, ADDR, DATA, BUF) if HAVE_PTRACE64.
+   Return success.  */
+
+#ifdef HAVE_PTRACE64
+# define ptracex(request, pid, addr, data, buf) \
+        ptrace64 (request, pid, addr, data, buf)
+#endif
 
 static int
 ptrace64aix (int req, int id, long long addr, int data, int *buf)
@@ -250,14 +294,24 @@ ptrace64aix (int req, int id, long long addr, int data, int *buf)
   return ptrace_check (req, id, ptracex (req, id, addr, data, buf));
 }
 
-/* Call ptrace (REQ, ID, ADDR, DATA, BUF).  Return success.  */
+/* Call ptrace (REQ, ID, ADDR, DATA, BUF) or
+   ptrace64 (REQ, ID, ADDR, DATA, BUF) if HAVE_PTRACE64.
+   Return success.  */
+
+#ifdef HAVE_PTRACE64
+# define ptrace(request, pid, addr, data, buf) \
+        ptrace64 (request, pid, addr, data, buf)
+# define addr_ptr long long
+#else
+# define addr_ptr int *
+#endif
 
 static int
-ptrace32 (int req, int id, int *addr, int data, int *buf)
+ptrace32 (int req, int id, addr_ptr addr, int data, int *buf)
 {
   errno = 0;
   return ptrace_check (req, id, 
-                      ptrace (req, id, (int *) addr, data, buf));
+                      ptrace (req, id, addr, data, buf));
 }
 
 /* If *PIDP is a composite process/thread id, convert it to a
@@ -270,7 +324,7 @@ pid_to_prc (ptid_t *ptidp)
 
   ptid = *ptidp;
   if (PD_TID (ptid))
-    *ptidp = pid_to_ptid (PIDGET (ptid));
+    *ptidp = ptid_t (ptid.pid ());
 }
 
 /* pthdb callback: for <i> from 0 to COUNT, set SYMBOLS[<i>].addr to
@@ -279,7 +333,7 @@ pid_to_prc (ptid_t *ptidp)
 static int
 pdc_symbol_addrs (pthdb_user_t user, pthdb_symbol_t *symbols, int count)
 {
-  struct minimal_symbol *ms;
+  struct bound_minimal_symbol ms;
   int i;
   char *name;
 
@@ -299,13 +353,14 @@ pdc_symbol_addrs (pthdb_user_t user, pthdb_symbol_t *symbols, int count)
        symbols[i].addr = 0;
       else
        {
-         if (!(ms = lookup_minimal_symbol (name, NULL, NULL)))
+         ms = lookup_minimal_symbol (name, NULL, NULL);
+         if (ms.minsym == NULL)
            {
              if (debug_aix_thread)
                fprintf_unfiltered (gdb_stdlog, " returning PDC_FAILURE\n");
              return PDC_FAILURE;
            }
-         symbols[i].addr = SYMBOL_VALUE_ADDRESS (ms);
+         symbols[i].addr = BMSYMBOL_VALUE_ADDRESS (ms);
        }
       if (debug_aix_thread)
        fprintf_unfiltered (gdb_stdlog, "  symbols[%d].addr = %s\n",
@@ -356,7 +411,7 @@ pdc_read_regs (pthdb_user_t user,
        }
       else
        {
-         if (!ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL))
+         if (!ptrace32 (PTT_READ_GPRS, tid, (uintptr_t) gprs32, 0, NULL))
            memset (gprs32, 0, sizeof (gprs32));
          memcpy (context->gpr, gprs32, sizeof(gprs32));
        }
@@ -365,9 +420,9 @@ pdc_read_regs (pthdb_user_t user,
   /* Floating-point registers.  */
   if (flags & PTHDB_FLAG_FPRS)
     {
-      if (!ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL))
+      if (!ptrace32 (PTT_READ_FPRS, tid, (uintptr_t) fprs, 0, NULL))
        memset (fprs, 0, sizeof (fprs));
-         memcpy (context->fpr, fprs, sizeof(fprs));
+      memcpy (context->fpr, fprs, sizeof(fprs));
     }
 
   /* Special-purpose registers.  */
@@ -382,7 +437,7 @@ pdc_read_regs (pthdb_user_t user,
        }
       else
        {
-         if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
+         if (!ptrace32 (PTT_READ_SPRS, tid, (uintptr_t) &sprs32, 0, NULL))
            memset (&sprs32, 0, sizeof (sprs32));
          memcpy (&context->msr, &sprs32, sizeof(sprs32));
        }
@@ -391,7 +446,7 @@ pdc_read_regs (pthdb_user_t user,
 }
 
 /* Write register function should be able to write requested context
-   information to specified debuggee's kernel thread id. 
+   information to specified debuggee's kernel thread id.
    If successful return 0, else non-zero is returned.  */
 
 static int
@@ -417,13 +472,13 @@ pdc_write_regs (pthdb_user_t user,
        ptrace64aix (PTT_WRITE_GPRS, tid, 
                     (unsigned long) context->gpr, 0, NULL);
       else
-       ptrace32 (PTT_WRITE_GPRS, tid, (int *) context->gpr, 0, NULL);
+       ptrace32 (PTT_WRITE_GPRS, tid, (uintptr_t) context->gpr, 0, NULL);
     }
 
  /* Floating-point registers.  */
   if (flags & PTHDB_FLAG_FPRS)
     {
-      ptrace32 (PTT_WRITE_FPRS, tid, (int *) context->fpr, 0, NULL);
+      ptrace32 (PTT_WRITE_FPRS, tid, (uintptr_t) context->fpr, 0, NULL);
     }
 
   /* Special-purpose registers.  */
@@ -436,7 +491,7 @@ pdc_write_regs (pthdb_user_t user,
        }
       else
        {
-         ptrace32 (PTT_WRITE_SPRS, tid, (int *) &context->msr, 0, NULL);
+         ptrace32 (PTT_WRITE_SPRS, tid, (uintptr_t) &context->msr, 0, NULL);
        }
     }
   return 0;
@@ -455,7 +510,7 @@ pdc_read_data (pthdb_user_t user, void *buf,
       "pdc_read_data (user = %ld, buf = 0x%lx, addr = %s, len = %ld)\n",
       user, (long) buf, hex_string (addr), len);
 
-  status = target_read_memory (addr, buf, len);
+  status = target_read_memory (addr, (gdb_byte *) buf, len);
   ret = status == 0 ? PDC_SUCCESS : PDC_FAILURE;
 
   if (debug_aix_thread)
@@ -477,7 +532,7 @@ pdc_write_data (pthdb_user_t user, void *buf,
       "pdc_write_data (user = %ld, buf = 0x%lx, addr = %s, len = %ld)\n",
       user, (long) buf, hex_string (addr), len);
 
-  status = target_write_memory (addr, buf, len);
+  status = target_write_memory (addr, (gdb_byte *) buf, len);
   ret = status == 0 ? PDC_SUCCESS : PDC_FAILURE;
 
   if (debug_aix_thread)
@@ -577,22 +632,36 @@ pcmp (const void *p1v, const void *p2v)
   return p1->pthid < p2->pthid ? -1 : p1->pthid > p2->pthid;
 }
 
-/* iterate_over_threads() callback for counting GDB threads.  */
+/* iterate_over_threads() callback for counting GDB threads.
+
+   Do not count the main thread (whose tid is zero).  This matches
+   the list of threads provided by the pthreaddebug library, which
+   does not include that main thread either, and thus allows us
+   to compare the two lists.  */
 
 static int
 giter_count (struct thread_info *thread, void *countp)
 {
-  (*(int *) countp)++;
+  if (PD_TID (thread->ptid))
+    (*(int *) countp)++;
   return 0;
 }
 
-/* iterate_over_threads() callback for accumulating GDB thread pids.  */
+/* iterate_over_threads() callback for accumulating GDB thread pids.
+
+   Do not include the main thread (whose tid is zero).  This matches
+   the list of threads provided by the pthreaddebug library, which
+   does not include that main thread either, and thus allows us
+   to compare the two lists.  */
 
 static int
 giter_accum (struct thread_info *thread, void *bufp)
 {
-  **(struct thread_info ***) bufp = thread;
-  (*(struct thread_info ***) bufp)++;
+  if (PD_TID (thread->ptid))
+    {
+      **(struct thread_info ***) bufp = thread;
+      (*(struct thread_info ***) bufp)++;
+    }
   return 0;
 }
 
@@ -601,19 +670,17 @@ giter_accum (struct thread_info *thread, void *bufp)
 static int
 ptid_cmp (ptid_t ptid1, ptid_t ptid2)
 {
-  int pid1, pid2;
-
-  if (ptid_get_pid (ptid1) < ptid_get_pid (ptid2))
+  if (ptid1.pid () < ptid2.pid ())
     return -1;
-  else if (ptid_get_pid (ptid1) > ptid_get_pid (ptid2))
+  else if (ptid1.pid () > ptid2.pid ())
     return 1;
-  else if (ptid_get_tid (ptid1) < ptid_get_tid (ptid2))
+  else if (ptid1.tid () < ptid2.tid ())
     return -1;
-  else if (ptid_get_tid (ptid1) > ptid_get_tid (ptid2))
+  else if (ptid1.tid () > ptid2.tid ())
     return 1;
-  else if (ptid_get_lwp (ptid1) < ptid_get_lwp (ptid2))
+  else if (ptid1.lwp () < ptid2.lwp ())
     return -1;
-  else if (ptid_get_lwp (ptid1) > ptid_get_lwp (ptid2))
+  else if (ptid1.lwp () > ptid2.lwp ())
     return 1;
   else
     return 0;
@@ -637,16 +704,11 @@ static pthdb_tid_t
 get_signaled_thread (void)
 {
   struct thrdsinfo64 thrinf;
-  pthdb_tid_t ktid = 0;
-  int result = 0;
-
-  /* getthrds(3) isn't prototyped in any AIX 4.3.3 #include file.  */
-  extern int getthrds (pid_t, struct thrdsinfo64 *, 
-                      int, pthdb_tid_t *, int);
+  tid_t ktid = 0;
 
   while (1)
   {
-    if (getthrds (PIDGET (inferior_ptid), &thrinf, 
+    if (getthrds (inferior_ptid.pid (), &thrinf, 
                  sizeof (thrinf), &ktid, 1) != 1)
       break;
 
@@ -686,7 +748,7 @@ sync_threadlists (void)
 
   pcount = 0;
   psize = 1;
-  pbuf = (struct pd_thread *) xmalloc (psize * sizeof *pbuf);
+  pbuf = XNEWVEC (struct pd_thread, psize);
 
   for (cmd = PTHDB_LIST_FIRST;; cmd = PTHDB_LIST_NEXT)
     {
@@ -723,26 +785,28 @@ sync_threadlists (void)
 
   gcount = 0;
   iterate_over_threads (giter_count, &gcount);
-  g = gbuf = (struct thread_info **) xmalloc (gcount * sizeof *gbuf);
+  g = gbuf = XNEWVEC (struct thread_info *, gcount);
   iterate_over_threads (giter_accum, &g);
   qsort (gbuf, gcount, sizeof *gbuf, gcmp);
 
   /* Apply differences between the two arrays to GDB's thread list.  */
 
-  infpid = PIDGET (inferior_ptid);
+  infpid = inferior_ptid.pid ();
   for (pi = gi = 0; pi < pcount || gi < gcount;)
     {
       if (pi == pcount)
        {
-         delete_thread (gbuf[gi]->ptid);
+         delete_thread (gbuf[gi]);
          gi++;
        }
       else if (gi == gcount)
        {
-         thread = add_thread (BUILD_THREAD (pbuf[pi].pthid, infpid));
-         thread->private = xmalloc (sizeof (struct private_thread_info));
-         thread->private->pdtid = pbuf[pi].pdtid;
-         thread->private->tid = pbuf[pi].tid;
+         aix_thread_info *priv = new aix_thread_info;
+         priv->pdtid = pbuf[pi].pdtid;
+         priv->tid = pbuf[pi].tid;
+
+         thread = add_thread_with_info (ptid_t (infpid, 0, pbuf[pi].pthid), priv);
+
          pi++;
        }
       else
@@ -750,7 +814,7 @@ sync_threadlists (void)
          ptid_t pptid, gptid;
          int cmp_result;
 
-         pptid = BUILD_THREAD (pbuf[pi].pthid, infpid);
+         pptid = ptid_t (infpid, 0, pbuf[pi].pthid);
          gptid = gbuf[gi]->ptid;
          pdtid = pbuf[pi].pdtid;
          tid = pbuf[pi].tid;
@@ -759,22 +823,26 @@ sync_threadlists (void)
 
          if (cmp_result == 0)
            {
-             gbuf[gi]->private->pdtid = pdtid;
-             gbuf[gi]->private->tid = tid;
+             aix_thread_info *priv = get_aix_thread_info (gbuf[gi]);
+
+             priv->pdtid = pdtid;
+             priv->tid = tid;
              pi++;
              gi++;
            }
          else if (cmp_result > 0)
            {
-             delete_thread (gptid);
+             delete_thread (gbuf[gi]);
              gi++;
            }
          else
            {
              thread = add_thread (pptid);
-             thread->private = xmalloc (sizeof (struct private_thread_info));
-             thread->private->pdtid = pdtid;
-             thread->private->tid = tid;
+
+             aix_thread_info *priv = new aix_thread_info;
+             thread->priv.reset (priv);
+             priv->pdtid = pdtid;
+             priv->tid = tid;
              pi++;
            }
        }
@@ -791,8 +859,9 @@ static int
 iter_tid (struct thread_info *thread, void *tidp)
 {
   const pthdb_tid_t tid = *(pthdb_tid_t *)tidp;
+  aix_thread_info *priv = get_aix_thread_info (thread);
 
-  return (thread->private->tid == tid);
+  return priv->tid == tid;
 }
 
 /* Synchronize libpthdebug's state with the inferior and with GDB,
@@ -832,7 +901,7 @@ pd_update (int set_infpid)
   return ptid;
 }
 
-/* Try to start debugging threads in the current process. 
+/* Try to start debugging threads in the current process.
    If successful and SET_INFPID, set inferior_ptid to reflect the
    current thread.  */
 
@@ -873,32 +942,32 @@ pd_enable (void)
 {
   int status;
   char *stub_name;
-  struct minimal_symbol *ms;
+  struct bound_minimal_symbol ms;
 
   /* Don't initialize twice.  */
   if (pd_able)
     return;
 
   /* Check application word size.  */
-  arch64 = register_size (current_gdbarch, 0) == 8;
+  arch64 = register_size (target_gdbarch (), 0) == 8;
 
   /* Check whether the application is pthreaded.  */
   stub_name = NULL;
   status = pthdb_session_pthreaded (PD_USER, PTHDB_FLAG_REGS,
                                    &pd_callbacks, &stub_name);
-  if ((status != PTHDB_SUCCESS && 
-       status != PTHDB_NOT_PTHREADED) || !stub_name)
+  if ((status != PTHDB_SUCCESS
+       && status != PTHDB_NOT_PTHREADED) || !stub_name)
     return;
 
   /* Set a breakpoint on the returned stub function.  */
-  if (!(ms = lookup_minimal_symbol (stub_name, NULL, NULL)))
+  ms = lookup_minimal_symbol (stub_name, NULL, NULL);
+  if (ms.minsym == NULL)
     return;
-  pd_brk_addr = SYMBOL_VALUE_ADDRESS (ms);
-  if (!create_thread_event_breakpoint (pd_brk_addr))
+  pd_brk_addr = BMSYMBOL_VALUE_ADDRESS (ms);
+  if (!create_thread_event_breakpoint (target_gdbarch (), pd_brk_addr))
     return;
 
   /* Prepare for thread debugging.  */
-  base_target = current_target;
   push_target (&aix_thread_ops);
   pd_able = 1;
 
@@ -940,56 +1009,59 @@ new_objfile (struct objfile *objfile)
 /* Attach to process specified by ARGS.  */
 
 static void
-aix_thread_attach (char *args, int from_tty)
+aix_thread_inferior_created (struct target_ops *ops, int from_tty)
 {
-  base_target.to_attach (args, from_tty);
-  pd_activate (1);
+  pd_enable ();
 }
 
 /* Detach from the process attached to by aix_thread_attach().  */
 
-static void
-aix_thread_detach (char *args, int from_tty)
+void
+aix_thread_target::detach (inferior *inf, int from_tty)
 {
+  target_ops *beneath = this->beneath ();
+
   pd_disable ();
-  base_target.to_detach (args, from_tty);
+  beneath->detach (inf, from_tty);
 }
 
 /* Tell the inferior process to continue running thread PID if != -1
    and all threads otherwise.  */
 
-static void
-aix_thread_resume (ptid_t ptid, int step, enum target_signal sig)
+void
+aix_thread_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 {
   struct thread_info *thread;
   pthdb_tid_t tid[2];
 
   if (!PD_TID (ptid))
     {
-      struct cleanup *cleanup = save_inferior_ptid ();
-      inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
-      base_target.to_resume (ptid, step, sig);
-      do_cleanups (cleanup);
+      scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
+      
+      inferior_ptid = ptid_t (inferior_ptid.pid ());
+      beneath ()->resume (ptid, step, sig);
     }
   else
     {
-      thread = find_thread_pid (ptid);
+      thread = find_thread_ptid (ptid);
       if (!thread)
        error (_("aix-thread resume: unknown pthread %ld"),
-              TIDGET (ptid));
+              ptid.lwp ());
+
+      aix_thread_info *priv = get_aix_thread_info (thread);
 
-      tid[0] = thread->private->tid;
+      tid[0] = priv->tid;
       if (tid[0] == PTHDB_INVALID_TID)
        error (_("aix-thread resume: no tid for pthread %ld"),
-              TIDGET (ptid));
+              ptid.lwp ());
       tid[1] = 0;
 
       if (arch64)
-       ptrace64aix (PTT_CONTINUE, tid[0], 1, 
-                    target_signal_to_host (sig), (int *) tid);
+       ptrace64aix (PTT_CONTINUE, tid[0], (long long) 1,
+                    gdb_signal_to_host (sig), (PTRACE_TYPE_ARG5) tid);
       else
-       ptrace32 (PTT_CONTINUE, tid[0], (int *) 1,
-                 target_signal_to_host (sig), (int *) tid);
+       ptrace32 (PTT_CONTINUE, tid[0], (addr_ptr) 1,
+                 gdb_signal_to_host (sig), (PTRACE_TYPE_ARG5) tid);
     }
 }
 
@@ -997,26 +1069,33 @@ aix_thread_resume (ptid_t ptid, int step, enum target_signal sig)
    If an error occurs, return -1, else return the pid of the stopped
    thread.  */
 
-static ptid_t
-aix_thread_wait (ptid_t ptid, struct target_waitstatus *status)
+ptid_t
+aix_thread_target::wait (ptid_t ptid, struct target_waitstatus *status,
+                        int options)
 {
-  struct cleanup *cleanup = save_inferior_ptid ();
+  {
+    scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
-  pid_to_prc (&ptid);
+    pid_to_prc (&ptid);
 
-  inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
-  ptid = base_target.to_wait (ptid, status);
-  do_cleanups (cleanup);
+    inferior_ptid = ptid_t (inferior_ptid.pid ());
+    ptid = beneath ()->wait (ptid, status, options);
+  }
 
-  if (PIDGET (ptid) == -1)
-    return pid_to_ptid (-1);
+  if (ptid.pid () == -1)
+    return ptid_t (-1);
 
   /* Check whether libpthdebug might be ready to be initialized.  */
-  if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED &&
-      status->value.sig == TARGET_SIGNAL_TRAP
-      && read_pc_pid (ptid)
-        - gdbarch_decr_pc_after_break (current_gdbarch) == pd_brk_addr)
-    return pd_activate (0);
+  if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED
+      && status->value.sig == GDB_SIGNAL_TRAP)
+    {
+      struct regcache *regcache = get_thread_regcache (ptid);
+      struct gdbarch *gdbarch = regcache->arch ();
+
+      if (regcache_read_pc (regcache)
+         - gdbarch_decr_pc_after_break (gdbarch) == pd_brk_addr)
+       return pd_activate (0);
+    }
 
   return pd_update (0);
 }
@@ -1026,12 +1105,12 @@ aix_thread_wait (ptid_t ptid, struct target_waitstatus *status)
 static void
 supply_gprs64 (struct regcache *regcache, uint64_t *vals)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
   int regno;
 
   for (regno = 0; regno < ppc_num_gprs; regno++)
-    regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + regno,
-                        (char *) (vals + regno));
+    regcache->raw_supply (tdep->ppc_gp0_regnum + regno,
+                         (char *) (vals + regno));
 }
 
 /* Record that 32-bit register REGNO contains VAL.  */
@@ -1039,7 +1118,7 @@ supply_gprs64 (struct regcache *regcache, uint64_t *vals)
 static void
 supply_reg32 (struct regcache *regcache, int regno, uint32_t val)
 {
-  regcache_raw_supply (regcache, regno, (char *) &val);
+  regcache->raw_supply (regno, (char *) &val);
 }
 
 /* Record that the floating-point registers contain VALS.  */
@@ -1047,25 +1126,28 @@ supply_reg32 (struct regcache *regcache, int regno, uint32_t val)
 static void
 supply_fprs (struct regcache *regcache, double *vals)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int regno;
 
   /* This function should never be called on architectures without
      floating-point registers.  */
-  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
+  gdb_assert (ppc_floating_point_unit_p (gdbarch));
 
-  for (regno = 0; regno < ppc_num_fprs; regno++)
-    regcache_raw_supply (regcache, regno + tdep->ppc_fp0_regnum,
-                        (char *) (vals + regno));
+  for (regno = tdep->ppc_fp0_regnum;
+       regno < tdep->ppc_fp0_regnum + ppc_num_fprs;
+       regno++)
+    regcache->raw_supply (regno,
+                         (char *) (vals + regno - tdep->ppc_fp0_regnum));
 }
 
 /* Predicate to test whether given register number is a "special" register.  */
 static int
-special_register_p (int regno)
+special_register_p (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  return regno == gdbarch_pc_regnum (current_gdbarch)
+  return regno == gdbarch_pc_regnum (gdbarch)
       || regno == tdep->ppc_ps_regnum
       || regno == tdep->ppc_cr_regnum
       || regno == tdep->ppc_lr_regnum
@@ -1085,18 +1167,17 @@ supply_sprs64 (struct regcache *regcache,
               uint64_t lr, uint64_t ctr, uint32_t xer,
               uint32_t fpscr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-
-  regcache_raw_supply (regcache, gdbarch_pc_regnum (current_gdbarch),
-                      (char *) &iar);
-  regcache_raw_supply (regcache, tdep->ppc_ps_regnum, (char *) &msr);
-  regcache_raw_supply (regcache, tdep->ppc_cr_regnum, (char *) &cr);
-  regcache_raw_supply (regcache, tdep->ppc_lr_regnum, (char *) &lr);
-  regcache_raw_supply (regcache, tdep->ppc_ctr_regnum, (char *) &ctr);
-  regcache_raw_supply (regcache, tdep->ppc_xer_regnum, (char *) &xer);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  regcache->raw_supply (gdbarch_pc_regnum (gdbarch), (char *) &iar);
+  regcache->raw_supply (tdep->ppc_ps_regnum, (char *) &msr);
+  regcache->raw_supply (tdep->ppc_cr_regnum, (char *) &cr);
+  regcache->raw_supply (tdep->ppc_lr_regnum, (char *) &lr);
+  regcache->raw_supply (tdep->ppc_ctr_regnum, (char *) &ctr);
+  regcache->raw_supply (tdep->ppc_xer_regnum, (char *) &xer);
   if (tdep->ppc_fpscr_regnum >= 0)
-    regcache_raw_supply (regcache, tdep->ppc_fpscr_regnum,
-                        (char *) &fpscr);
+    regcache->raw_supply (tdep->ppc_fpscr_regnum, (char *) &fpscr);
 }
 
 /* Record that the special registers contain the specified 32-bit
@@ -1108,18 +1189,17 @@ supply_sprs32 (struct regcache *regcache,
               uint32_t lr, uint32_t ctr, uint32_t xer,
               uint32_t fpscr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-
-  regcache_raw_supply (regcache, gdbarch_pc_regnum (current_gdbarch),
-                      (char *) &iar);
-  regcache_raw_supply (regcache, tdep->ppc_ps_regnum, (char *) &msr);
-  regcache_raw_supply (regcache, tdep->ppc_cr_regnum, (char *) &cr);
-  regcache_raw_supply (regcache, tdep->ppc_lr_regnum, (char *) &lr);
-  regcache_raw_supply (regcache, tdep->ppc_ctr_regnum, (char *) &ctr);
-  regcache_raw_supply (regcache, tdep->ppc_xer_regnum, (char *) &xer);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  regcache->raw_supply (gdbarch_pc_regnum (gdbarch), (char *) &iar);
+  regcache->raw_supply (tdep->ppc_ps_regnum, (char *) &msr);
+  regcache->raw_supply (tdep->ppc_cr_regnum, (char *) &cr);
+  regcache->raw_supply (tdep->ppc_lr_regnum, (char *) &lr);
+  regcache->raw_supply (tdep->ppc_ctr_regnum, (char *) &ctr);
+  regcache->raw_supply (tdep->ppc_xer_regnum, (char *) &xer);
   if (tdep->ppc_fpscr_regnum >= 0)
-    regcache_raw_supply (regcache, tdep->ppc_fpscr_regnum,
-                        (char *) &fpscr);
+    regcache->raw_supply (tdep->ppc_fpscr_regnum, (char *) &fpscr);
 }
 
 /* Fetch all registers from pthread PDTID, which doesn't have a kernel
@@ -1132,7 +1212,8 @@ supply_sprs32 (struct regcache *regcache,
 static void
 fetch_regs_user_thread (struct regcache *regcache, pthdb_pthread_t pdtid)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int status, i;
   pthdb_context_t ctx;
 
@@ -1154,7 +1235,7 @@ fetch_regs_user_thread (struct regcache *regcache, pthdb_pthread_t pdtid)
 
   /* Floating-point registers.  */
 
-  if (ppc_floating_point_unit_p (current_gdbarch))
+  if (ppc_floating_point_unit_p (gdbarch))
     supply_fprs (regcache, ctx.fpr);
 
   /* Special registers.  */
@@ -1186,7 +1267,8 @@ static void
 fetch_regs_kernel_thread (struct regcache *regcache, int regno,
                          pthdb_tid_t tid)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint64_t gprs64[ppc_num_gprs];
   uint32_t gprs32[ppc_num_gprs];
   double fprs[ppc_num_fprs];
@@ -1213,7 +1295,7 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
        }
       else
        {
-         if (!ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL))
+         if (!ptrace32 (PTT_READ_GPRS, tid, (uintptr_t) gprs32, 0, NULL))
            memset (gprs32, 0, sizeof (gprs32));
          for (i = 0; i < ppc_num_gprs; i++)
            supply_reg32 (regcache, tdep->ppc_gp0_regnum + i, gprs32[i]);
@@ -1222,19 +1304,19 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
 
   /* Floating-point registers.  */
 
-  if (ppc_floating_point_unit_p (current_gdbarch)
+  if (ppc_floating_point_unit_p (gdbarch)
       && (regno == -1
           || (regno >= tdep->ppc_fp0_regnum
               && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
     {
-      if (!ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL))
+      if (!ptrace32 (PTT_READ_FPRS, tid, (uintptr_t) fprs, 0, NULL))
        memset (fprs, 0, sizeof (fprs));
       supply_fprs (regcache, fprs);
     }
 
   /* Special-purpose registers.  */
 
-  if (regno == -1 || special_register_p (regno))
+  if (regno == -1 || special_register_p (gdbarch, regno))
     {
       if (arch64)
        {
@@ -1247,39 +1329,37 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
        }
       else
        {
-         struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-
-         if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
+         if (!ptrace32 (PTT_READ_SPRS, tid, (uintptr_t) &sprs32, 0, NULL))
            memset (&sprs32, 0, sizeof (sprs32));
          supply_sprs32 (regcache, sprs32.pt_iar, sprs32.pt_msr, sprs32.pt_cr,
                         sprs32.pt_lr, sprs32.pt_ctr, sprs32.pt_xer,
                         sprs32.pt_fpscr);
 
          if (tdep->ppc_mq_regnum >= 0)
-           regcache_raw_supply (regcache, tdep->ppc_mq_regnum,
-                                (char *) &sprs32.pt_mq);
+           regcache->raw_supply (tdep->ppc_mq_regnum, (char *) &sprs32.pt_mq);
        }
     }
 }
 
-/* Fetch register REGNO if != -1 or all registers otherwise in the
-   thread/process specified by inferior_ptid.  */
+/* Fetch register REGNO if != -1 or all registers otherwise from the
+   thread/process connected to REGCACHE.  */
 
-static void
-aix_thread_fetch_registers (struct regcache *regcache, int regno)
+void
+aix_thread_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct thread_info *thread;
   pthdb_tid_t tid;
 
-  if (!PD_TID (inferior_ptid))
-    base_target.to_fetch_registers (regcache, regno);
+  if (!PD_TID (regcache->ptid ()))
+    beneath ()->fetch_registers (regcache, regno);
   else
     {
-      thread = find_thread_pid (inferior_ptid);
-      tid = thread->private->tid;
+      thread = find_thread_ptid (regcache->ptid ());
+      aix_thread_info *priv = get_aix_thread_info (thread);
+      tid = priv->tid;
 
       if (tid == PTHDB_INVALID_TID)
-       fetch_regs_user_thread (regcache, thread->private->pdtid);
+       fetch_regs_user_thread (regcache, priv->pdtid);
       else
        fetch_regs_kernel_thread (regcache, regno, tid);
     }
@@ -1290,43 +1370,44 @@ aix_thread_fetch_registers (struct regcache *regcache, int regno)
 static void
 fill_gprs64 (const struct regcache *regcache, uint64_t *vals)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
   int regno;
 
   for (regno = 0; regno < ppc_num_gprs; regno++)
-    if (regcache_valid_p (regcache, tdep->ppc_gp0_regnum + regno))
-      regcache_raw_collect (regcache, tdep->ppc_gp0_regnum + regno,
-                           vals + regno);
+    if (REG_VALID == regcache->get_register_status
+                      (tdep->ppc_gp0_regnum + regno))
+      regcache->raw_collect (tdep->ppc_gp0_regnum + regno, vals + regno);
 }
 
 static void 
 fill_gprs32 (const struct regcache *regcache, uint32_t *vals)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
   int regno;
 
   for (regno = 0; regno < ppc_num_gprs; regno++)
-    if (regcache_valid_p (regcache, tdep->ppc_gp0_regnum + regno))
-      regcache_raw_collect (regcache, tdep->ppc_gp0_regnum + regno,
-                           vals + regno);
+    if (REG_VALID == regcache->get_register_status
+                      (tdep->ppc_gp0_regnum + regno))
+      regcache->raw_collect (tdep->ppc_gp0_regnum + regno, vals + regno);
 }
 
 /* Store the floating point registers into a double array.  */
 static void
 fill_fprs (const struct regcache *regcache, double *vals)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int regno;
 
   /* This function should never be called on architectures without
      floating-point registers.  */
-  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
+  gdb_assert (ppc_floating_point_unit_p (gdbarch));
 
   for (regno = tdep->ppc_fp0_regnum;
        regno < tdep->ppc_fp0_regnum + ppc_num_fprs;
        regno++)
-    if (regcache_valid_p (regcache, regno))
-      regcache_raw_collect (regcache, regno, vals + regno);
+    if (REG_VALID == regcache->get_register_status (regno))
+      regcache->raw_collect (regno, vals + regno - tdep->ppc_fp0_regnum);
 }
 
 /* Store the special registers into the specified 64-bit and 32-bit
@@ -1338,7 +1419,8 @@ fill_sprs64 (const struct regcache *regcache,
             uint64_t *lr, uint64_t *ctr, uint32_t *xer,
             uint32_t *fpscr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   /* Verify that the size of the size of the IAR buffer is the
      same as the raw size of the PC (in the register cache).  If
@@ -1346,24 +1428,23 @@ fill_sprs64 (const struct regcache *regcache,
      there's some other kind of internal error.  To be really safe,
      we should check all of the sizes.   */
   gdb_assert (sizeof (*iar) == register_size
-                                (current_gdbarch,
-                                 gdbarch_pc_regnum (current_gdbarch)));
-
-  if (regcache_valid_p (regcache, gdbarch_pc_regnum (current_gdbarch)))
-    regcache_raw_collect (regcache, gdbarch_pc_regnum (current_gdbarch), iar);
-  if (regcache_valid_p (regcache, tdep->ppc_ps_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_ps_regnum, msr);
-  if (regcache_valid_p (regcache, tdep->ppc_cr_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_cr_regnum, cr);
-  if (regcache_valid_p (regcache, tdep->ppc_lr_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_lr_regnum, lr);
-  if (regcache_valid_p (regcache, tdep->ppc_ctr_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_ctr_regnum, ctr);
-  if (regcache_valid_p (regcache, tdep->ppc_xer_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_xer_regnum, xer);
+                                (gdbarch, gdbarch_pc_regnum (gdbarch)));
+
+  if (REG_VALID == regcache->get_register_status (gdbarch_pc_regnum (gdbarch)))
+    regcache->raw_collect (gdbarch_pc_regnum (gdbarch), iar);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_ps_regnum))
+    regcache->raw_collect (tdep->ppc_ps_regnum, msr);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_cr_regnum))
+    regcache->raw_collect (tdep->ppc_cr_regnum, cr);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_lr_regnum))
+    regcache->raw_collect (tdep->ppc_lr_regnum, lr);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_ctr_regnum))
+    regcache->raw_collect (tdep->ppc_ctr_regnum, ctr);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_xer_regnum))
+    regcache->raw_collect (tdep->ppc_xer_regnum, xer);
   if (tdep->ppc_fpscr_regnum >= 0
-      && regcache_valid_p (regcache, tdep->ppc_fpscr_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_fpscr_regnum, fpscr);
+      && REG_VALID == regcache->get_register_status (tdep->ppc_fpscr_regnum))
+    regcache->raw_collect (tdep->ppc_fpscr_regnum, fpscr);
 }
 
 static void
@@ -1372,32 +1453,32 @@ fill_sprs32 (const struct regcache *regcache,
             uint32_t *lr, uint32_t *ctr, uint32_t *xer,
             uint32_t *fpscr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   /* Verify that the size of the size of the IAR buffer is the
      same as the raw size of the PC (in the register cache).  If
      they're not, then either GDB has been built incorrectly, or
      there's some other kind of internal error.  To be really safe,
      we should check all of the sizes.  */
-  gdb_assert (sizeof (*iar) == register_size (current_gdbarch,
-                                             gdbarch_pc_regnum
-                                             (current_gdbarch)));
-
-  if (regcache_valid_p (regcache, gdbarch_pc_regnum (current_gdbarch)))
-    regcache_raw_collect (regcache, gdbarch_pc_regnum (current_gdbarch), iar);
-  if (regcache_valid_p (regcache, tdep->ppc_ps_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_ps_regnum, msr);
-  if (regcache_valid_p (regcache, tdep->ppc_cr_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_cr_regnum, cr);
-  if (regcache_valid_p (regcache, tdep->ppc_lr_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_lr_regnum, lr);
-  if (regcache_valid_p (regcache, tdep->ppc_ctr_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_ctr_regnum, ctr);
-  if (regcache_valid_p (regcache, tdep->ppc_xer_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_xer_regnum, xer);
+  gdb_assert (sizeof (*iar) == register_size (gdbarch,
+                                             gdbarch_pc_regnum (gdbarch)));
+
+  if (REG_VALID == regcache->get_register_status (gdbarch_pc_regnum (gdbarch)))
+    regcache->raw_collect (gdbarch_pc_regnum (gdbarch), iar);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_ps_regnum))
+    regcache->raw_collect (tdep->ppc_ps_regnum, msr);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_cr_regnum))
+    regcache->raw_collect (tdep->ppc_cr_regnum, cr);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_lr_regnum))
+    regcache->raw_collect (tdep->ppc_lr_regnum, lr);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_ctr_regnum))
+    regcache->raw_collect (tdep->ppc_ctr_regnum, ctr);
+  if (REG_VALID == regcache->get_register_status (tdep->ppc_xer_regnum))
+    regcache->raw_collect (tdep->ppc_xer_regnum, xer);
   if (tdep->ppc_fpscr_regnum >= 0
-      && regcache_valid_p (regcache, tdep->ppc_fpscr_regnum))
-    regcache_raw_collect (regcache, tdep->ppc_fpscr_regnum, fpscr);
+      && REG_VALID == regcache->get_register_status (tdep->ppc_fpscr_regnum))
+    regcache->raw_collect (tdep->ppc_fpscr_regnum, fpscr);
 }
 
 /* Store all registers into pthread PDTID, which doesn't have a kernel
@@ -1409,12 +1490,12 @@ fill_sprs32 (const struct regcache *regcache,
 static void
 store_regs_user_thread (const struct regcache *regcache, pthdb_pthread_t pdtid)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int status, i;
   pthdb_context_t ctx;
   uint32_t int32;
   uint64_t int64;
-  double   dbl;
 
   if (debug_aix_thread)
     fprintf_unfiltered (gdb_stdlog, 
@@ -1430,24 +1511,22 @@ store_regs_user_thread (const struct regcache *regcache, pthdb_pthread_t pdtid)
   /* Collect general-purpose register values from the regcache.  */
 
   for (i = 0; i < ppc_num_gprs; i++)
-    if (regcache_valid_p (regcache, tdep->ppc_gp0_regnum + i))
+    if (REG_VALID == regcache->get_register_status (tdep->ppc_gp0_regnum + i))
       {
        if (arch64)
          {
-           regcache_raw_collect (regcache, tdep->ppc_gp0_regnum + i,
-                                 (void *) &int64);
+           regcache->raw_collect (tdep->ppc_gp0_regnum + i, (void *) &int64);
            ctx.gpr[i] = int64;
          }
        else
          {
-           regcache_raw_collect (regcache, tdep->ppc_gp0_regnum + i,
-                                 (void *) &int32);
+           regcache->raw_collect (tdep->ppc_gp0_regnum + i, (void *) &int32);
            ctx.gpr[i] = int32;
          }
       }
 
   /* Collect floating-point register values from the regcache.  */
-  if (ppc_floating_point_unit_p (current_gdbarch))
+  if (ppc_floating_point_unit_p (gdbarch))
     fill_fprs (regcache, ctx.fpr);
 
   /* Special registers (always kept in ctx as 64 bits).  */
@@ -1465,25 +1544,27 @@ store_regs_user_thread (const struct regcache *regcache, pthdb_pthread_t pdtid)
 
       fill_sprs32 (regcache, &tmp_iar, &tmp_msr, &tmp_cr, &tmp_lr, &tmp_ctr,
                             &tmp_xer, &tmp_fpscr);
-      if (regcache_valid_p (regcache, gdbarch_pc_regnum (current_gdbarch)))
+      if (REG_VALID == regcache->get_register_status
+                        (gdbarch_pc_regnum (gdbarch)))
        ctx.iar = tmp_iar;
-      if (regcache_valid_p (regcache, tdep->ppc_ps_regnum))
+      if (REG_VALID == regcache->get_register_status (tdep->ppc_ps_regnum))
        ctx.msr = tmp_msr;
-      if (regcache_valid_p (regcache, tdep->ppc_cr_regnum))
+      if (REG_VALID == regcache->get_register_status (tdep->ppc_cr_regnum))
        ctx.cr  = tmp_cr;
-      if (regcache_valid_p (regcache, tdep->ppc_lr_regnum))
+      if (REG_VALID == regcache->get_register_status (tdep->ppc_lr_regnum))
        ctx.lr  = tmp_lr;
-      if (regcache_valid_p (regcache, tdep->ppc_ctr_regnum))
+      if (REG_VALID == regcache->get_register_status (tdep->ppc_ctr_regnum))
        ctx.ctr = tmp_ctr;
-      if (regcache_valid_p (regcache, tdep->ppc_xer_regnum))
+      if (REG_VALID == regcache->get_register_status (tdep->ppc_xer_regnum))
        ctx.xer = tmp_xer;
-      if (regcache_valid_p (regcache, tdep->ppc_xer_regnum))
+      if (REG_VALID == regcache->get_register_status (tdep->ppc_xer_regnum))
        ctx.fpscr = tmp_fpscr;
     }
 
   status = pthdb_pthread_setcontext (pd_session, pdtid, &ctx);
   if (status != PTHDB_SUCCESS)
-    error (_("aix-thread: store_registers: pthdb_pthread_setcontext returned %s"),
+    error (_("aix-thread: store_registers: "
+            "pthdb_pthread_setcontext returned %s"),
            pd_status2str (status));
 }
 
@@ -1499,13 +1580,13 @@ static void
 store_regs_kernel_thread (const struct regcache *regcache, int regno,
                          pthdb_tid_t tid)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint64_t gprs64[ppc_num_gprs];
   uint32_t gprs32[ppc_num_gprs];
   double fprs[ppc_num_fprs];
   struct ptxsprs sprs64;
   struct ptsprs  sprs32;
-  int i;
 
   if (debug_aix_thread)
     fprintf_unfiltered (gdb_stdlog, 
@@ -1527,28 +1608,28 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
       else
        {
          /* Pre-fetch: some regs may not be in the cache.  */
-         ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL);
+         ptrace32 (PTT_READ_GPRS, tid, (uintptr_t) gprs32, 0, NULL);
          fill_gprs32 (regcache, gprs32);
-         ptrace32 (PTT_WRITE_GPRS, tid, gprs32, 0, NULL);
+         ptrace32 (PTT_WRITE_GPRS, tid, (uintptr_t) gprs32, 0, NULL);
        }
     }
 
   /* Floating-point registers.  */
 
-  if (ppc_floating_point_unit_p (current_gdbarch)
+  if (ppc_floating_point_unit_p (gdbarch)
       && (regno == -1
           || (regno >= tdep->ppc_fp0_regnum
               && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
     {
       /* Pre-fetch: some regs may not be in the cache.  */
-      ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL);
+      ptrace32 (PTT_READ_FPRS, tid, (uintptr_t) fprs, 0, NULL);
       fill_fprs (regcache, fprs);
-      ptrace32 (PTT_WRITE_FPRS, tid, (int *) fprs, 0, NULL);
+      ptrace32 (PTT_WRITE_FPRS, tid, (uintptr_t) fprs, 0, NULL);
     }
 
   /* Special-purpose registers.  */
 
-  if (regno == -1 || special_register_p (regno))
+  if (regno == -1 || special_register_p (gdbarch, regno))
     {
       if (arch64)
        {
@@ -1575,7 +1656,7 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
          gdb_assert (sizeof (sprs32.pt_iar) == 4);
 
          /* Pre-fetch: some registers won't be in the cache.  */
-         ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL);
+         ptrace32 (PTT_READ_SPRS, tid, (uintptr_t) &sprs32, 0, NULL);
 
          fill_sprs32 (regcache, &tmp_iar, &tmp_msr, &tmp_cr, &tmp_lr,
                       &tmp_ctr, &tmp_xer, &tmp_fpscr);
@@ -1589,86 +1670,73 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
          sprs32.pt_fpscr = tmp_fpscr;
 
          if (tdep->ppc_mq_regnum >= 0)
-           if (regcache_valid_p (regcache, tdep->ppc_mq_regnum))
-             regcache_raw_collect (regcache, tdep->ppc_mq_regnum,
-                                   &sprs32.pt_mq);
+           if (REG_VALID == regcache->get_register_status
+                              (tdep->ppc_mq_regnum))
+             regcache->raw_collect (tdep->ppc_mq_regnum, &sprs32.pt_mq);
 
-         ptrace32 (PTT_WRITE_SPRS, tid, (int *) &sprs32, 0, NULL);
+         ptrace32 (PTT_WRITE_SPRS, tid, (uintptr_t) &sprs32, 0, NULL);
        }
     }
 }
 
 /* Store gdb's current view of the register set into the
-   thread/process specified by inferior_ptid.  */
+   thread/process connected to REGCACHE.  */
 
-static void
-aix_thread_store_registers (struct regcache *regcache, int regno)
+void
+aix_thread_target::store_registers (struct regcache *regcache, int regno)
 {
   struct thread_info *thread;
   pthdb_tid_t tid;
 
-  if (!PD_TID (inferior_ptid))
-    base_target.to_store_registers (regcache, regno);
+  if (!PD_TID (regcache->ptid ()))
+    beneath ()->store_registers (regcache, regno);
   else
     {
-      thread = find_thread_pid (inferior_ptid);
-      tid = thread->private->tid;
+      thread = find_thread_ptid (regcache->ptid ());
+      aix_thread_info *priv = get_aix_thread_info (thread);
+      tid = priv->tid;
 
       if (tid == PTHDB_INVALID_TID)
-       store_regs_user_thread (regcache, thread->private->pdtid);
+       store_regs_user_thread (regcache, priv->pdtid);
       else
        store_regs_kernel_thread (regcache, regno, tid);
     }
 }
 
-/* Attempt a transfer all LEN bytes starting at OFFSET between the
-   inferior's OBJECT:ANNEX space and GDB's READBUF/WRITEBUF buffer.
-   Return the number of bytes actually transferred.  */
-
-static LONGEST
-aix_thread_xfer_partial (struct target_ops *ops, enum target_object object,
-                        const char *annex, gdb_byte *readbuf,
-                        const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
-{
-  struct cleanup *old_chain = save_inferior_ptid ();
-  LONGEST xfer;
-
-  inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
-  xfer = base_target.to_xfer_partial (ops, object, annex,
-                                     readbuf, writebuf, offset, len);
-
-  do_cleanups (old_chain);
-  return xfer;
-}
-
-/* Kill and forget about the inferior process.  */
+/* Implement the to_xfer_partial target_ops method.  */
 
-static void
-aix_thread_kill (void)
+enum target_xfer_status
+aix_thread_target::xfer_partial (enum target_object object,
+                                const char *annex, gdb_byte *readbuf,
+                                const gdb_byte *writebuf,
+                                ULONGEST offset, ULONGEST len,
+                                ULONGEST *xfered_len)
 {
-  struct cleanup *cleanup = save_inferior_ptid ();
+  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
-  inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
-  base_target.to_kill ();
-  do_cleanups (cleanup);
+  inferior_ptid = ptid_t (inferior_ptid.pid ());
+  return beneath ()->xfer_partial (object, annex, readbuf,
+                                  writebuf, offset, len, xfered_len);
 }
 
 /* Clean up after the inferior exits.  */
 
-static void
-aix_thread_mourn_inferior (void)
+void
+aix_thread_target::mourn_inferior ()
 {
+  target_ops *beneath = this->beneath ();
+
   pd_deactivate ();
-  base_target.to_mourn_inferior ();
+  beneath->mourn_inferior ();
 }
 
 /* Return whether thread PID is still valid.  */
 
-static int
-aix_thread_thread_alive (ptid_t ptid)
+bool
+aix_thread_target::thread_alive (ptid_t ptid)
 {
   if (!PD_TID (ptid))
-    return base_target.to_thread_alive (ptid);
+    return beneath ()->thread_alive (ptid);
 
   /* We update the thread list every time the child stops, so all
      valid threads should be in the thread list.  */
@@ -1678,29 +1746,21 @@ aix_thread_thread_alive (ptid_t ptid)
 /* Return a printable representation of composite PID for use in
    "info threads" output.  */
 
-static char *
-aix_thread_pid_to_str (ptid_t ptid)
+std::string
+aix_thread_target::pid_to_str (ptid_t ptid)
 {
-  static char *ret = NULL;
-
   if (!PD_TID (ptid))
-    return base_target.to_pid_to_str (ptid);
-
-  /* Free previous return value; a new one will be allocated by
-     xstrprintf().  */
-  xfree (ret);
+    return beneath ()->pid_to_str (ptid);
 
-  ret = xstrprintf (_("Thread %ld"), ptid_get_tid (ptid));
-  return ret;
+  return string_printf (_("Thread %ld"), ptid.tid ());
 }
 
 /* Return a printable representation of extra information about
    THREAD, for use in "info threads" output.  */
 
-static char *
-aix_thread_extra_thread_info (struct thread_info *thread)
+const char *
+aix_thread_target::extra_thread_info (struct thread_info *thread)
 {
-  struct ui_file *buf;
   int status;
   pthdb_pthread_t pdtid;
   pthdb_tid_t tid;
@@ -1708,96 +1768,78 @@ aix_thread_extra_thread_info (struct thread_info *thread)
   pthdb_suspendstate_t suspendstate;
   pthdb_detachstate_t detachstate;
   int cancelpend;
-  long length;
   static char *ret = NULL;
 
   if (!PD_TID (thread->ptid))
     return NULL;
 
-  buf = mem_fileopen ();
+  string_file buf;
+  aix_thread_info *priv = get_aix_thread_info (thread);
 
-  pdtid = thread->private->pdtid;
-  tid = thread->private->tid;
+  pdtid = priv->pdtid;
+  tid = priv->tid;
 
   if (tid != PTHDB_INVALID_TID)
     /* i18n: Like "thread-identifier %d, [state] running, suspended" */
-    fprintf_unfiltered (buf, _("tid %d"), (int)tid);
+    buf.printf (_("tid %d"), (int)tid);
 
   status = pthdb_pthread_state (pd_session, pdtid, &state);
   if (status != PTHDB_SUCCESS)
     state = PST_NOTSUP;
-  fprintf_unfiltered (buf, ", %s", state2str (state));
+  buf.printf (", %s", state2str (state));
 
   status = pthdb_pthread_suspendstate (pd_session, pdtid, 
                                       &suspendstate);
   if (status == PTHDB_SUCCESS && suspendstate == PSS_SUSPENDED)
     /* i18n: Like "Thread-Id %d, [state] running, suspended" */
-    fprintf_unfiltered (buf, _(", suspended"));
+    buf.printf (_(", suspended"));
 
   status = pthdb_pthread_detachstate (pd_session, pdtid, 
                                      &detachstate);
   if (status == PTHDB_SUCCESS && detachstate == PDS_DETACHED)
     /* i18n: Like "Thread-Id %d, [state] running, detached" */
-    fprintf_unfiltered (buf, _(", detached"));
+    buf.printf (_(", detached"));
 
   pthdb_pthread_cancelpend (pd_session, pdtid, &cancelpend);
   if (status == PTHDB_SUCCESS && cancelpend)
     /* i18n: Like "Thread-Id %d, [state] running, cancel pending" */
-    fprintf_unfiltered (buf, _(", cancel pending"));
+    buf.printf (_(", cancel pending"));
 
-  ui_file_write (buf, "", 1);
+  buf.write ("", 1);
 
   xfree (ret);                 /* Free old buffer.  */
 
-  ret = ui_file_xstrdup (buf, &length);
-  ui_file_delete (buf);
+  ret = xstrdup (buf.c_str ());
 
   return ret;
 }
 
-/* Initialize target aix_thread_ops.  */
-
-static void
-init_aix_thread_ops (void)
+ptid_t
+aix_thread_target::get_ada_task_ptid (long lwp, long thread)
 {
-  aix_thread_ops.to_shortname          = "aix-threads";
-  aix_thread_ops.to_longname           = _("AIX pthread support");
-  aix_thread_ops.to_doc                = _("AIX pthread support");
-
-  aix_thread_ops.to_attach             = aix_thread_attach;
-  aix_thread_ops.to_detach             = aix_thread_detach;
-  aix_thread_ops.to_resume             = aix_thread_resume;
-  aix_thread_ops.to_wait               = aix_thread_wait;
-  aix_thread_ops.to_fetch_registers    = aix_thread_fetch_registers;
-  aix_thread_ops.to_store_registers    = aix_thread_store_registers;
-  aix_thread_ops.to_xfer_partial       = aix_thread_xfer_partial;
-  /* No need for aix_thread_ops.to_create_inferior, because we activate thread
-     debugging when the inferior reaches pd_brk_addr.  */
-  aix_thread_ops.to_kill               = aix_thread_kill;
-  aix_thread_ops.to_mourn_inferior     = aix_thread_mourn_inferior;
-  aix_thread_ops.to_thread_alive       = aix_thread_thread_alive;
-  aix_thread_ops.to_pid_to_str         = aix_thread_pid_to_str;
-  aix_thread_ops.to_extra_thread_info  = aix_thread_extra_thread_info;
-  aix_thread_ops.to_stratum            = thread_stratum;
-  aix_thread_ops.to_magic              = OPS_MAGIC;
+  return ptid_t (inferior_ptid.pid (), 0, thread);
 }
 
+
 /* Module startup initialization function, automagically called by
    init.c.  */
 
 void
 _initialize_aix_thread (void)
 {
-  init_aix_thread_ops ();
-  add_target (&aix_thread_ops);
-
   /* Notice when object files get loaded and unloaded.  */
-  observer_attach_new_objfile (new_objfile);
+  gdb::observers::new_objfile.attach (new_objfile);
+
+  /* Add ourselves to inferior_created event chain.
+     This is needed to enable the thread target on "attach".  */
+  gdb::observers::inferior_created.attach (aix_thread_inferior_created);
 
   add_setshow_boolean_cmd ("aix-thread", class_maintenance, &debug_aix_thread,
-                           _("Set debugging of AIX thread module."),
-                           _("Show debugging of AIX thread module."),
-                           _("Enables debugging output (used to debug GDB)."),
-                           NULL, NULL, /* FIXME: i18n: Debugging of AIX thread module is \"%d\".  */
-                           &setdebuglist, &showdebuglist);
+                          _("Set debugging of AIX thread module."),
+                          _("Show debugging of AIX thread module."),
+                          _("Enables debugging output (used to debug GDB)."),
+                          NULL, NULL,
+                          /* FIXME: i18n: Debugging of AIX thread
+                             module is \"%d\".  */
+                          &setdebuglist, &showdebuglist);
 }
This page took 0.058292 seconds and 4 git commands to generate.