2009-01-06 Sandra Loosemore <sandra@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / aix-thread.c
index e6d7a2990dc0c751e16b410a6af1e38fcfbd206c..04570c66793e535c09073c3e67f801a4419c7d9c 100644 (file)
@@ -1,13 +1,14 @@
 /* Low level interface for debugging AIX 4.3+ pthreads.
 
-   Copyright (C) 1999, 2000, 2002, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2002, 2007, 2008, 2009
+   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 +17,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
@@ -50,6 +49,7 @@
 #include "gdbcmd.h"
 #include "ppc-tdep.h"
 #include "gdb_string.h"
+#include "observer.h"
 
 #include <procinfo.h>
 #include <sys/types.h>
@@ -129,11 +129,6 @@ static int pd_active = 0;
 
 static int arch64;
 
-/* Saved pointer to previous owner of
-   deprecated_target_new_objfile_hook.  */
-
-static void (*target_new_objfile_chain)(struct objfile *);
-
 /* Forward declarations for pthdb callbacks.  */
 
 static int pdc_symbol_addrs (pthdb_user_t, pthdb_symbol_t *, int);
@@ -369,9 +364,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, (void *) fprs, 0, NULL))
        memset (fprs, 0, sizeof (fprs));
-         memcpy (context->fpr, fprs, sizeof(fprs));
+      memcpy (context->fpr, fprs, sizeof(fprs));
     }
 
   /* Special-purpose registers.  */
@@ -440,7 +435,7 @@ pdc_write_regs (pthdb_user_t user,
        }
       else
        {
-         ptrace32 (PTT_WRITE_SPRS, tid, (int *) &context->msr, 0, NULL);
+         ptrace32 (PTT_WRITE_SPRS, tid, (void *) &context->msr, 0, NULL);
        }
     }
   return 0;
@@ -925,7 +920,7 @@ pd_disable (void)
   unpush_target (&aix_thread_ops);
 }
 
-/* deprecated_target_new_objfile_hook callback.
+/* new_objfile observer callback.
 
    If OBJFILE is non-null, check whether a threaded application is
    being debugged, and if so, prepare for thread debugging.
@@ -939,27 +934,24 @@ new_objfile (struct objfile *objfile)
     pd_enable ();
   else
     pd_disable ();
-
-  if (target_new_objfile_chain)
-    target_new_objfile_chain (objfile);
 }
 
 /* Attach to process specified by ARGS.  */
 
 static void
-aix_thread_attach (char *args, int from_tty)
+aix_thread_attach (struct target_ops *ops, char *args, int from_tty)
 {
-  base_target.to_attach (args, from_tty);
+  base_target.to_attach (&base_target, args, from_tty);
   pd_activate (1);
 }
 
 /* Detach from the process attached to by aix_thread_attach().  */
 
 static void
-aix_thread_detach (char *args, int from_tty)
+aix_thread_detach (struct target_ops *ops, char *args, int from_tty)
 {
   pd_disable ();
-  base_target.to_detach (args, from_tty);
+  base_target.to_detach (&base_target, args, from_tty);
 }
 
 /* Tell the inferior process to continue running thread PID if != -1
@@ -993,10 +985,10 @@ aix_thread_resume (ptid_t ptid, int step, enum target_signal sig)
 
       if (arch64)
        ptrace64aix (PTT_CONTINUE, tid[0], 1, 
-                    target_signal_to_host (sig), (int *) tid);
+                    target_signal_to_host (sig), (void *) tid);
       else
        ptrace32 (PTT_CONTINUE, tid[0], (int *) 1,
-                 target_signal_to_host (sig), (int *) tid);
+                 target_signal_to_host (sig), (void *) tid);
     }
 }
 
@@ -1019,10 +1011,16 @@ aix_thread_wait (ptid_t ptid, struct target_waitstatus *status)
     return pid_to_ptid (-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) - DECR_PC_AFTER_BREAK == pd_brk_addr)
-    return pd_activate (0);
+  if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED
+      && status->value.sig == TARGET_SIGNAL_TRAP)
+    {
+      struct regcache *regcache = get_thread_regcache (ptid);
+      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+      if (regcache_read_pc (regcache)
+         - gdbarch_decr_pc_after_break (gdbarch) == pd_brk_addr)
+       return pd_activate (0);
+    }
 
   return pd_update (0);
 }
@@ -1032,7 +1030,7 @@ 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 (get_regcache_arch (regcache));
   int regno;
 
   for (regno = 0; regno < ppc_num_gprs; regno++)
@@ -1053,12 +1051,13 @@ 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 = get_regcache_arch (regcache);
+  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,
@@ -1067,11 +1066,11 @@ supply_fprs (struct regcache *regcache, double *vals)
 
 /* 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 == PC_REGNUM
+  return regno == gdbarch_pc_regnum (gdbarch)
       || regno == tdep->ppc_ps_regnum
       || regno == tdep->ppc_cr_regnum
       || regno == tdep->ppc_lr_regnum
@@ -1091,9 +1090,11 @@ 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);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  regcache_raw_supply (regcache, PC_REGNUM, (char *) &iar);
+  regcache_raw_supply (regcache, gdbarch_pc_regnum (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);
@@ -1113,9 +1114,11 @@ 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);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  regcache_raw_supply (regcache, PC_REGNUM, (char *) &iar);
+  regcache_raw_supply (regcache, gdbarch_pc_regnum (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);
@@ -1136,7 +1139,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 = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int status, i;
   pthdb_context_t ctx;
 
@@ -1158,7 +1162,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.  */
@@ -1190,7 +1194,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 = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint64_t gprs64[ppc_num_gprs];
   uint32_t gprs32[ppc_num_gprs];
   double fprs[ppc_num_fprs];
@@ -1226,19 +1231,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, (void *) 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)
        {
@@ -1251,7 +1256,7 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
        }
       else
        {
-         struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+         struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
          if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
            memset (&sprs32, 0, sizeof (sprs32));
@@ -1294,7 +1299,7 @@ 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 (get_regcache_arch (regcache));
   int regno;
 
   for (regno = 0; regno < ppc_num_gprs; regno++)
@@ -1306,7 +1311,7 @@ fill_gprs64 (const struct regcache *regcache, uint64_t *vals)
 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 (get_regcache_arch (regcache));
   int regno;
 
   for (regno = 0; regno < ppc_num_gprs; regno++)
@@ -1319,12 +1324,13 @@ fill_gprs32 (const struct regcache *regcache, uint32_t *vals)
 static void
 fill_fprs (const struct regcache *regcache, double *vals)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  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;
@@ -1342,17 +1348,19 @@ 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 = get_regcache_arch (regcache);
+  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, PC_REGNUM));
+  gdb_assert (sizeof (*iar) == register_size
+                                (gdbarch, gdbarch_pc_regnum (gdbarch)));
 
-  if (regcache_valid_p (regcache, PC_REGNUM))
-    regcache_raw_collect (regcache, PC_REGNUM, iar);
+  if (regcache_valid_p (regcache, gdbarch_pc_regnum (gdbarch)))
+    regcache_raw_collect (regcache, gdbarch_pc_regnum (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))
@@ -1374,17 +1382,19 @@ 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 = get_regcache_arch (regcache);
+  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, PC_REGNUM));
+  gdb_assert (sizeof (*iar) == register_size (gdbarch,
+                                             gdbarch_pc_regnum (gdbarch)));
 
-  if (regcache_valid_p (regcache, PC_REGNUM))
-    regcache_raw_collect (regcache, PC_REGNUM, iar);
+  if (regcache_valid_p (regcache, gdbarch_pc_regnum (gdbarch)))
+    regcache_raw_collect (regcache, gdbarch_pc_regnum (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))
@@ -1409,7 +1419,8 @@ 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 = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int status, i;
   pthdb_context_t ctx;
   uint32_t int32;
@@ -1447,7 +1458,7 @@ store_regs_user_thread (const struct regcache *regcache, pthdb_pthread_t pdtid)
       }
 
   /* 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,7 +1476,7 @@ 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, PC_REGNUM))
+      if (regcache_valid_p (regcache, gdbarch_pc_regnum (gdbarch)))
        ctx.iar = tmp_iar;
       if (regcache_valid_p (regcache, tdep->ppc_ps_regnum))
        ctx.msr = tmp_msr;
@@ -1499,7 +1510,8 @@ 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 = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint64_t gprs64[ppc_num_gprs];
   uint32_t gprs32[ppc_num_gprs];
   double fprs[ppc_num_fprs];
@@ -1535,20 +1547,20 @@ store_regs_kernel_thread (const 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)))
     {
       /* Pre-fetch: some regs may not be in the cache.  */
-      ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL);
+      ptrace32 (PTT_READ_FPRS, tid, (void *) fprs, 0, NULL);
       fill_fprs (regcache, fprs);
-      ptrace32 (PTT_WRITE_FPRS, tid, (int *) fprs, 0, NULL);
+      ptrace32 (PTT_WRITE_FPRS, tid, (void *) fprs, 0, NULL);
     }
 
   /* Special-purpose registers.  */
 
-  if (regno == -1 || special_register_p (regno))
+  if (regno == -1 || special_register_p (gdbarch, regno))
     {
       if (arch64)
        {
@@ -1656,10 +1668,10 @@ aix_thread_kill (void)
 /* Clean up after the inferior exits.  */
 
 static void
-aix_thread_mourn_inferior (void)
+aix_thread_mourn_inferior (struct target_ops *ops)
 {
   pd_deactivate ();
-  base_target.to_mourn_inferior ();
+  base_target.to_mourn_inferior (&base_target);
 }
 
 /* Return whether thread PID is still valid.  */
@@ -1792,8 +1804,7 @@ _initialize_aix_thread (void)
   add_target (&aix_thread_ops);
 
   /* Notice when object files get loaded and unloaded.  */
-  target_new_objfile_chain = deprecated_target_new_objfile_hook;
-  deprecated_target_new_objfile_hook = new_objfile;
+  observer_attach_new_objfile (new_objfile);
 
   add_setshow_boolean_cmd ("aix-thread", class_maintenance, &debug_aix_thread,
                            _("Set debugging of AIX thread module."),
This page took 0.028982 seconds and 4 git commands to generate.