* linux-low.c: Delete inclusion of ansidecl.h, elf/common.h,
[deliverable/binutils-gdb.git] / gdb / aix-thread.c
index a941ea7d63d2a075b1e9fec0d14f87a483965022..92693d632a3796fd957e02f452dd0e8ce4e49f94 100644 (file)
@@ -1,6 +1,7 @@
 /* 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.
@@ -104,12 +105,6 @@ struct pd_thread {
 
 static struct target_ops aix_thread_ops;
 
-/* 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.  */
-
-static struct target_ops base_target;
-
 /* Address of the function that libpthread will call when libpthdebug
    is ready to be initialized.  */
 
@@ -363,9 +358,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.  */
@@ -434,7 +429,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;
@@ -575,22 +570,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;
 }
 
@@ -878,25 +887,24 @@ pd_enable (void)
     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)))
     return;
   pd_brk_addr = SYMBOL_VALUE_ADDRESS (ms);
-  if (!create_thread_event_breakpoint (pd_brk_addr))
+  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;
 
@@ -938,26 +946,31 @@ new_objfile (struct objfile *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);
+  struct target_ops *beneath = find_target_beneath (ops);
+  
+  beneath->to_attach (beneath, 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)
 {
+  struct target_ops *beneath = find_target_beneath (ops);
+
   pd_disable ();
-  base_target.to_detach (args, from_tty);
+  beneath->to_detach (beneath, args, 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)
+aix_thread_resume (struct target_ops *ops,
+                   ptid_t ptid, int step, enum target_signal sig)
 {
   struct thread_info *thread;
   pthdb_tid_t tid[2];
@@ -965,13 +978,15 @@ aix_thread_resume (ptid_t ptid, int step, enum target_signal sig)
   if (!PD_TID (ptid))
     {
       struct cleanup *cleanup = save_inferior_ptid ();
+      struct target_ops *beneath = find_target_beneath (ops);
+      
       inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
-      base_target.to_resume (ptid, step, sig);
+      beneath->to_resume (beneath, ptid, step, sig);
       do_cleanups (cleanup);
     }
   else
     {
-      thread = find_thread_pid (ptid);
+      thread = find_thread_ptid (ptid);
       if (!thread)
        error (_("aix-thread resume: unknown pthread %ld"),
               TIDGET (ptid));
@@ -984,10 +999,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);
     }
 }
 
@@ -996,25 +1011,32 @@ aix_thread_resume (ptid_t ptid, int step, enum target_signal sig)
    thread.  */
 
 static ptid_t
-aix_thread_wait (ptid_t ptid, struct target_waitstatus *status)
+aix_thread_wait (struct target_ops *ops,
+                ptid_t ptid, struct target_waitstatus *status, int options)
 {
   struct cleanup *cleanup = save_inferior_ptid ();
+  struct target_ops *beneath = find_target_beneath (ops);
 
   pid_to_prc (&ptid);
 
   inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
-  ptid = base_target.to_wait (ptid, status);
+  ptid = beneath->to_wait (beneath, ptid, status, options);
   do_cleanups (cleanup);
 
   if (PIDGET (ptid) == -1)
     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)
-        - 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 == 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);
 }
@@ -1060,11 +1082,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 == 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
@@ -1230,14 +1252,14 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
           || (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)
        {
@@ -1269,16 +1291,18 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
    thread/process specified by inferior_ptid.  */
 
 static void
-aix_thread_fetch_registers (struct regcache *regcache, int regno)
+aix_thread_fetch_registers (struct target_ops *ops,
+                            struct regcache *regcache, int regno)
 {
   struct thread_info *thread;
   pthdb_tid_t tid;
+  struct target_ops *beneath = find_target_beneath (ops);
 
   if (!PD_TID (inferior_ptid))
-    base_target.to_fetch_registers (regcache, regno);
+    beneath->to_fetch_registers (beneath, regcache, regno);
   else
     {
-      thread = find_thread_pid (inferior_ptid);
+      thread = find_thread_ptid (inferior_ptid);
       tid = thread->private->tid;
 
       if (tid == PTHDB_INVALID_TID)
@@ -1547,14 +1571,14 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
               && 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)
        {
@@ -1608,16 +1632,18 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
    thread/process specified by inferior_ptid.  */
 
 static void
-aix_thread_store_registers (struct regcache *regcache, int regno)
+aix_thread_store_registers (struct target_ops *ops,
+                            struct regcache *regcache, int regno)
 {
   struct thread_info *thread;
   pthdb_tid_t tid;
+  struct target_ops *beneath = find_target_beneath (ops);
 
   if (!PD_TID (inferior_ptid))
-    base_target.to_store_registers (regcache, regno);
+    beneath->to_store_registers (beneath, regcache, regno);
   else
     {
-      thread = find_thread_pid (inferior_ptid);
+      thread = find_thread_ptid (inferior_ptid);
       tid = thread->private->tid;
 
       if (tid == PTHDB_INVALID_TID)
@@ -1638,43 +1664,36 @@ aix_thread_xfer_partial (struct target_ops *ops, enum target_object object,
 {
   struct cleanup *old_chain = save_inferior_ptid ();
   LONGEST xfer;
+  struct target_ops *beneath = find_target_beneath (ops);
 
   inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
-  xfer = base_target.to_xfer_partial (ops, object, annex,
-                                     readbuf, writebuf, offset, len);
+  xfer = beneath->to_xfer_partial (beneath, object, annex,
+                                  readbuf, writebuf, offset, len);
 
   do_cleanups (old_chain);
   return xfer;
 }
 
-/* Kill and forget about the inferior process.  */
-
-static void
-aix_thread_kill (void)
-{
-  struct cleanup *cleanup = save_inferior_ptid ();
-
-  inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
-  base_target.to_kill ();
-  do_cleanups (cleanup);
-}
-
 /* Clean up after the inferior exits.  */
 
 static void
-aix_thread_mourn_inferior (void)
+aix_thread_mourn_inferior (struct target_ops *ops)
 {
+  struct target_ops *beneath = find_target_beneath (ops);
+
   pd_deactivate ();
-  base_target.to_mourn_inferior ();
+  beneath->to_mourn_inferior (beneath);
 }
 
 /* Return whether thread PID is still valid.  */
 
 static int
-aix_thread_thread_alive (ptid_t ptid)
+aix_thread_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
+  struct target_ops *beneath = find_target_beneath (ops);
+
   if (!PD_TID (ptid))
-    return base_target.to_thread_alive (ptid);
+    return beneath->to_thread_alive (beneath, ptid);
 
   /* We update the thread list every time the child stops, so all
      valid threads should be in the thread list.  */
@@ -1685,12 +1704,13 @@ aix_thread_thread_alive (ptid_t ptid)
    "info threads" output.  */
 
 static char *
-aix_thread_pid_to_str (ptid_t ptid)
+aix_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   static char *ret = NULL;
+  struct target_ops *beneath = find_target_beneath (ops);
 
   if (!PD_TID (ptid))
-    return base_target.to_pid_to_str (ptid);
+    return beneath->to_pid_to_str (beneath, ptid);
 
   /* Free previous return value; a new one will be allocated by
      xstrprintf().  */
@@ -1714,7 +1734,6 @@ 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))
@@ -1755,37 +1774,43 @@ aix_thread_extra_thread_info (struct thread_info *thread)
 
   xfree (ret);                 /* Free old buffer.  */
 
-  ret = ui_file_xstrdup (buf, &length);
+  ret = ui_file_xstrdup (buf, NULL);
   ui_file_delete (buf);
 
   return ret;
 }
 
+static ptid_t
+aix_thread_get_ada_task_ptid (long lwp, long thread)
+{
+  return ptid_build (ptid_get_pid (inferior_ptid), 0, thread);
+}
+
 /* Initialize target aix_thread_ops.  */
 
 static void
 init_aix_thread_ops (void)
 {
-  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;
+  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;
+  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_get_ada_task_ptid = aix_thread_get_ada_task_ptid;
+  aix_thread_ops.to_stratum = thread_stratum;
+  aix_thread_ops.to_magic = OPS_MAGIC;
 }
 
 /* Module startup initialization function, automagically called by
This page took 0.030843 seconds and 4 git commands to generate.