/* Low level interface for debugging AIX 4.3+ pthreads.
- Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Copyright (C) 1999-2021 Free Software Foundation, Inc.
Written by Nick Duffek <nsd@redhat.com>.
This file is part of GDB.
*/
#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 <string.h>
-#include "observer.h"
+#include "observable.h"
+#include "objfiles.h"
#include <procinfo.h>
#include <sys/types.h>
#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
/* Return whether to treat PID as a debuggable thread id. */
-#define PD_TID(ptid) (pd_active && ptid_get_tid (ptid) != 0)
+#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. */
/* 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 {
/* 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 *, target_wait_flags) 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;
+
+ ptid_t get_ada_task_ptid (long lwp, long thread) override;
+};
+
+static aix_thread_target aix_thread_ops;
/* Address of the function that libpthread will call when libpthdebug
is ready to be initialized. */
/* Return a printable representation of pthdebug function return
STATUS. */
-static char *
+static const char *
pd_status2str (int status)
{
switch (status)
ptid = *ptidp;
if (PD_TID (ptid))
- *ptidp = pid_to_ptid (ptid_get_pid (ptid));
+ *ptidp = ptid_t (ptid.pid ());
}
/* pthdb callback: for <i> from 0 to COUNT, set SYMBOLS[<i>].addr to
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;
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",
if (debug_aix_thread)
fprintf_unfiltered (gdb_stdlog, "pdc_read_regs tid=%d flags=%s\n",
- (int) tid, hex_string (flags));
+ (int) tid, hex_string (flags));
/* General-purpose registers. */
if (flags & PTHDB_FLAG_GPRS)
if (debug_aix_thread)
fprintf_unfiltered (gdb_stdlog, "pdc_write_regs tid=%d flags=%s\n",
- (int) tid, hex_string (flags));
+ (int) tid, hex_string (flags));
/* General-purpose registers. */
if (flags & PTHDB_FLAG_GPRS)
"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)
"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)
{
if (debug_aix_thread)
fprintf_unfiltered (gdb_stdlog,
- "pdc_alloc (user = %ld, len = %ld, bufp = 0x%lx)\n",
+ "pdc_alloc (user = %ld, len = %ld, bufp = 0x%lx)\n",
user, len, (long) bufp);
*bufp = xmalloc (len);
if (debug_aix_thread)
if (debug_aix_thread)
fprintf_unfiltered (gdb_stdlog,
"pdc_free (user = %ld, buf = 0x%lx)\n", user,
- (long) buf);
+ (long) buf);
xfree (buf);
return PDC_SUCCESS;
}
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;
{
struct thrdsinfo64 thrinf;
tid_t ktid = 0;
- int result = 0;
while (1)
{
- if (getthrds (ptid_get_pid (inferior_ptid), &thrinf,
- sizeof (thrinf), &ktid, 1) != 1)
+ if (getthrds (inferior_ptid.pid (), &thrinf,
+ sizeof (thrinf), &ktid, 1) != 1)
break;
if (thrinf.ti_cursig == SIGTRAP)
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)
{
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 = ptid_get_pid (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 (ptid_build (infpid, 0, pbuf[pi].pthid));
- 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;
+
+ process_stratum_target *proc_target
+ = current_inferior ()->process_target ();
+ thread = add_thread_with_info (proc_target,
+ ptid_t (infpid, 0, pbuf[pi].pthid),
+ priv);
+
pi++;
}
else
ptid_t pptid, gptid;
int cmp_result;
- pptid = ptid_build (infpid, 0, pbuf[pi].pthid);
+ pptid = ptid_t (infpid, 0, pbuf[pi].pthid);
gptid = gbuf[gi]->ptid;
pdtid = pbuf[pi].pdtid;
tid = pbuf[pi].tid;
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;
+ process_stratum_target *proc_target
+ = current_inferior ()->process_target ();
+ thread = add_thread (proc_target, pptid);
+
+ aix_thread_info *priv = new aix_thread_info;
+ thread->priv.reset (priv);
+ priv->pdtid = pdtid;
+ priv->tid = tid;
pi++;
}
}
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,
{
ptid = thread->ptid;
if (set_infpid)
- inferior_ptid = ptid;
+ switch_to_thread (thread);
}
return ptid;
}
{
int status;
char *stub_name;
- struct minimal_symbol *ms;
+ struct bound_minimal_symbol ms;
/* Don't initialize twice. */
if (pd_able)
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);
+ pd_brk_addr = BMSYMBOL_VALUE_ADDRESS (ms);
if (!create_thread_event_breakpoint (target_gdbarch (), pd_brk_addr))
return;
/* Prepare for thread debugging. */
- push_target (&aix_thread_ops);
+ current_inferior ()->push_target (&aix_thread_ops);
pd_able = 1;
/* If we're debugging a core file or an attached inferior, the
if (pd_active)
pd_deactivate ();
pd_able = 0;
- unpush_target (&aix_thread_ops);
+ current_inferior ()->unpush_target (&aix_thread_ops);
}
/* new_objfile observer callback.
/* Attach to process specified by ARGS. */
static void
-aix_thread_attach (struct target_ops *ops, char *args, int from_tty)
+aix_thread_inferior_created (inferior *inf)
{
- struct target_ops *beneath = find_target_beneath (ops);
-
- beneath->to_attach (beneath, args, from_tty);
- pd_activate (1);
+ pd_enable ();
}
/* Detach from the process attached to by aix_thread_attach(). */
-static void
-aix_thread_detach (struct target_ops *ops, const char *args, int from_tty)
+void
+aix_thread_target::detach (inferior *inf, int from_tty)
{
- struct target_ops *beneath = find_target_beneath (ops);
+ target_ops *beneath = this->beneath ();
pd_disable ();
- beneath->to_detach (beneath, 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 (struct target_ops *ops,
- ptid_t ptid, int step, enum gdb_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 ();
- struct target_ops *beneath = find_target_beneath (ops);
+ scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
- inferior_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
- beneath->to_resume (beneath, ptid, step, sig);
- do_cleanups (cleanup);
+ inferior_ptid = ptid_t (inferior_ptid.pid ());
+ beneath ()->resume (ptid, step, sig);
}
else
{
- thread = find_thread_ptid (ptid);
+ thread = find_thread_ptid (current_inferior (), ptid);
if (!thread)
error (_("aix-thread resume: unknown pthread %ld"),
- ptid_get_lwp (ptid));
+ ptid.lwp ());
- tid[0] = thread->private->tid;
+ aix_thread_info *priv = get_aix_thread_info (thread);
+
+ tid[0] = priv->tid;
if (tid[0] == PTHDB_INVALID_TID)
error (_("aix-thread resume: no tid for pthread %ld"),
- ptid_get_lwp (ptid));
+ ptid.lwp ());
tid[1] = 0;
if (arch64)
ptrace64aix (PTT_CONTINUE, tid[0], (long long) 1,
- gdb_signal_to_host (sig), (void *) tid);
+ gdb_signal_to_host (sig), (PTRACE_TYPE_ARG5) tid);
else
ptrace32 (PTT_CONTINUE, tid[0], (addr_ptr) 1,
- gdb_signal_to_host (sig), (void *) tid);
+ gdb_signal_to_host (sig), (PTRACE_TYPE_ARG5) tid);
}
}
If an error occurs, return -1, else return the pid of the stopped
thread. */
-static ptid_t
-aix_thread_wait (struct target_ops *ops,
- ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+aix_thread_target::wait (ptid_t ptid, struct target_waitstatus *status,
+ target_wait_flags options)
{
- struct cleanup *cleanup = save_inferior_ptid ();
- struct target_ops *beneath = find_target_beneath (ops);
+ {
+ scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
- pid_to_prc (&ptid);
+ pid_to_prc (&ptid);
- inferior_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
- ptid = beneath->to_wait (beneath, ptid, status, options);
- do_cleanups (cleanup);
+ inferior_ptid = ptid_t (inferior_ptid.pid ());
+ ptid = beneath ()->wait (ptid, status, options);
+ }
- if (ptid_get_pid (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 == GDB_SIGNAL_TRAP)
{
- struct regcache *regcache = get_thread_regcache (ptid);
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ process_stratum_target *proc_target
+ = current_inferior ()->process_target ();
+ struct regcache *regcache = get_thread_regcache (proc_target, ptid);
+ struct gdbarch *gdbarch = regcache->arch ();
if (regcache_read_pc (regcache)
- - target_decr_pc_after_break (gdbarch) == pd_brk_addr)
+ - gdbarch_decr_pc_after_break (gdbarch) == pd_brk_addr)
return pd_activate (0);
}
static void
supply_gprs64 (struct regcache *regcache, uint64_t *vals)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+ 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. */
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. */
static void
supply_fprs (struct regcache *regcache, double *vals)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int regno;
for (regno = tdep->ppc_fp0_regnum;
regno < tdep->ppc_fp0_regnum + ppc_num_fprs;
regno++)
- regcache_raw_supply (regcache, regno,
- (char *) (vals + regno - tdep->ppc_fp0_regnum));
+ regcache->raw_supply (regno,
+ (char *) (vals + regno - tdep->ppc_fp0_regnum));
}
/* Predicate to test whether given register number is a "special" register. */
uint64_t lr, uint64_t ctr, uint32_t xer,
uint32_t fpscr)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- 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);
- regcache_raw_supply (regcache, tdep->ppc_ctr_regnum, (char *) &ctr);
- regcache_raw_supply (regcache, tdep->ppc_xer_regnum, (char *) &xer);
+ 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
uint32_t lr, uint32_t ctr, uint32_t xer,
uint32_t fpscr)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- 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);
- regcache_raw_supply (regcache, tdep->ppc_ctr_regnum, (char *) &ctr);
- regcache_raw_supply (regcache, tdep->ppc_xer_regnum, (char *) &xer);
+ 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
static void
fetch_regs_user_thread (struct regcache *regcache, pthdb_pthread_t pdtid)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int status, i;
pthdb_context_t ctx;
status = pthdb_pthread_context (pd_session, pdtid, &ctx);
if (status != PTHDB_SUCCESS)
error (_("aix-thread: fetch_registers: pthdb_pthread_context returned %s"),
- pd_status2str (status));
+ pd_status2str (status));
/* General-purpose registers. */
fetch_regs_kernel_thread (struct regcache *regcache, int regno,
pthdb_tid_t tid)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
uint64_t gprs64[ppc_num_gprs];
uint32_t gprs32[ppc_num_gprs];
/* General-purpose registers. */
if (regno == -1
|| (tdep->ppc_gp0_regnum <= regno
- && regno < tdep->ppc_gp0_regnum + ppc_num_gprs))
+ && regno < tdep->ppc_gp0_regnum + ppc_num_gprs))
{
if (arch64)
{
if (ppc_floating_point_unit_p (gdbarch)
&& (regno == -1
- || (regno >= tdep->ppc_fp0_regnum
- && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
+ || (regno >= tdep->ppc_fp0_regnum
+ && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
{
if (!ptrace32 (PTT_READ_FPRS, tid, (uintptr_t) fprs, 0, NULL))
memset (fprs, 0, sizeof (fprs));
}
else
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
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_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 target_ops *ops,
- struct regcache *regcache, int regno)
+void
+aix_thread_target::fetch_registers (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))
- beneath->to_fetch_registers (beneath, regcache, regno);
+ if (!PD_TID (regcache->ptid ()))
+ beneath ()->fetch_registers (regcache, regno);
else
{
- thread = find_thread_ptid (inferior_ptid);
- tid = thread->private->tid;
+ thread = find_thread_ptid (current_inferior (), 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);
}
static void
fill_gprs64 (const struct regcache *regcache, uint64_t *vals)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
int regno;
for (regno = 0; regno < ppc_num_gprs; regno++)
- if (REG_VALID == regcache_register_status (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 (get_regcache_arch (regcache));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
int regno;
for (regno = 0; regno < ppc_num_gprs; regno++)
- if (REG_VALID == regcache_register_status (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 *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int regno;
for (regno = tdep->ppc_fp0_regnum;
regno < tdep->ppc_fp0_regnum + ppc_num_fprs;
regno++)
- if (REG_VALID == regcache_register_status (regcache, regno))
- regcache_raw_collect (regcache, regno,
- vals + regno - tdep->ppc_fp0_regnum);
+ 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
uint64_t *lr, uint64_t *ctr, uint32_t *xer,
uint32_t *fpscr)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ 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
gdb_assert (sizeof (*iar) == register_size
(gdbarch, gdbarch_pc_regnum (gdbarch)));
- if (REG_VALID == regcache_register_status (regcache,
- gdbarch_pc_regnum (gdbarch)))
- regcache_raw_collect (regcache, gdbarch_pc_regnum (gdbarch), iar);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_ps_regnum))
- regcache_raw_collect (regcache, tdep->ppc_ps_regnum, msr);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_cr_regnum))
- regcache_raw_collect (regcache, tdep->ppc_cr_regnum, cr);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_lr_regnum))
- regcache_raw_collect (regcache, tdep->ppc_lr_regnum, lr);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_ctr_regnum))
- regcache_raw_collect (regcache, tdep->ppc_ctr_regnum, ctr);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_xer_regnum))
- regcache_raw_collect (regcache, tdep->ppc_xer_regnum, xer);
+ 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
- && REG_VALID == regcache_register_status (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
uint32_t *lr, uint32_t *ctr, uint32_t *xer,
uint32_t *fpscr)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ 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
gdb_assert (sizeof (*iar) == register_size (gdbarch,
gdbarch_pc_regnum (gdbarch)));
- if (REG_VALID == regcache_register_status (regcache,
- gdbarch_pc_regnum (gdbarch)))
- regcache_raw_collect (regcache, gdbarch_pc_regnum (gdbarch), iar);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_ps_regnum))
- regcache_raw_collect (regcache, tdep->ppc_ps_regnum, msr);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_cr_regnum))
- regcache_raw_collect (regcache, tdep->ppc_cr_regnum, cr);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_lr_regnum))
- regcache_raw_collect (regcache, tdep->ppc_lr_regnum, lr);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_ctr_regnum))
- regcache_raw_collect (regcache, tdep->ppc_ctr_regnum, ctr);
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_xer_regnum))
- regcache_raw_collect (regcache, tdep->ppc_xer_regnum, xer);
+ 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
- && REG_VALID == regcache_register_status (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
static void
store_regs_user_thread (const struct regcache *regcache, pthdb_pthread_t pdtid)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ 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,
status = pthdb_pthread_context (pd_session, pdtid, &ctx);
if (status != PTHDB_SUCCESS)
error (_("aix-thread: store_registers: pthdb_pthread_context returned %s"),
- pd_status2str (status));
+ pd_status2str (status));
/* Collect general-purpose register values from the regcache. */
for (i = 0; i < ppc_num_gprs; i++)
- if (REG_VALID == regcache_register_status (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;
}
}
fill_sprs32 (regcache, &tmp_iar, &tmp_msr, &tmp_cr, &tmp_lr, &tmp_ctr,
&tmp_xer, &tmp_fpscr);
- if (REG_VALID == regcache_register_status (regcache,
- gdbarch_pc_regnum (gdbarch)))
+ if (REG_VALID == regcache->get_register_status
+ (gdbarch_pc_regnum (gdbarch)))
ctx.iar = tmp_iar;
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_ps_regnum))
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_ps_regnum))
ctx.msr = tmp_msr;
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_cr_regnum))
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_cr_regnum))
ctx.cr = tmp_cr;
- if (REG_VALID == regcache_register_status (regcache, tdep->ppc_lr_regnum))
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_lr_regnum))
ctx.lr = tmp_lr;
- if (REG_VALID == regcache_register_status (regcache,
- tdep->ppc_ctr_regnum))
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_ctr_regnum))
ctx.ctr = tmp_ctr;
- if (REG_VALID == regcache_register_status (regcache,
- tdep->ppc_xer_regnum))
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_xer_regnum))
ctx.xer = tmp_xer;
- if (REG_VALID == regcache_register_status (regcache,
- tdep->ppc_xer_regnum))
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_xer_regnum))
ctx.fpscr = tmp_fpscr;
}
if (status != PTHDB_SUCCESS)
error (_("aix-thread: store_registers: "
"pthdb_pthread_setcontext returned %s"),
- pd_status2str (status));
+ pd_status2str (status));
}
/* Store register REGNO if != -1 or all registers otherwise into
store_regs_kernel_thread (const struct regcache *regcache, int regno,
pthdb_tid_t tid)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ 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,
"store_regs_kernel_thread tid=%lx regno=%d\n",
- (long) tid, regno);
+ (long) tid, regno);
/* General-purpose registers. */
if (regno == -1
|| (tdep->ppc_gp0_regnum <= regno
- && regno < tdep->ppc_gp0_regnum + ppc_num_fprs))
+ && regno < tdep->ppc_gp0_regnum + ppc_num_fprs))
{
if (arch64)
{
if (ppc_floating_point_unit_p (gdbarch)
&& (regno == -1
- || (regno >= tdep->ppc_fp0_regnum
- && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
+ || (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, (uintptr_t) fprs, 0, NULL);
sprs32.pt_fpscr = tmp_fpscr;
if (tdep->ppc_mq_regnum >= 0)
- if (REG_VALID == regcache_register_status (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, (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 target_ops *ops,
- struct regcache *regcache, int regno)
+void
+aix_thread_target::store_registers (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))
- beneath->to_store_registers (beneath, regcache, regno);
+ if (!PD_TID (regcache->ptid ()))
+ beneath ()->store_registers (regcache, regno);
else
{
- thread = find_thread_ptid (inferior_ptid);
- tid = thread->private->tid;
+ thread = find_thread_ptid (current_inferior (), 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. */
+/* Implement the to_xfer_partial target_ops method. */
-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, ULONGEST len)
+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 *old_chain = save_inferior_ptid ();
- LONGEST xfer;
- struct target_ops *beneath = find_target_beneath (ops);
+ scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
- inferior_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
- xfer = beneath->to_xfer_partial (beneath, object, annex,
- readbuf, writebuf, offset, len);
-
- do_cleanups (old_chain);
- return xfer;
+ 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 (struct target_ops *ops)
+void
+aix_thread_target::mourn_inferior ()
{
- struct target_ops *beneath = find_target_beneath (ops);
+ target_ops *beneath = this->beneath ();
pd_deactivate ();
- beneath->to_mourn_inferior (beneath);
+ beneath->mourn_inferior ();
}
/* Return whether thread PID is still valid. */
-static int
-aix_thread_thread_alive (struct target_ops *ops, ptid_t ptid)
+bool
+aix_thread_target::thread_alive (ptid_t ptid)
{
- struct target_ops *beneath = find_target_beneath (ops);
-
if (!PD_TID (ptid))
- return beneath->to_thread_alive (beneath, 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. */
- return in_thread_list (ptid);
+ process_stratum_target *proc_target
+ = current_inferior ()->process_target ();
+ return in_thread_list (proc_target, ptid);
}
/* Return a printable representation of composite PID for use in
"info threads" output. */
-static char *
-aix_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
+std::string
+aix_thread_target::pid_to_str (ptid_t ptid)
{
- static char *ret = NULL;
- struct target_ops *beneath = find_target_beneath (ops);
-
if (!PD_TID (ptid))
- return beneath->to_pid_to_str (beneath, 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;
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, NULL);
- ui_file_delete (buf);
+ ret = xstrdup (buf.c_str ());
return ret;
}
-static ptid_t
-aix_thread_get_ada_task_ptid (long lwp, long thread)
+ptid_t
+aix_thread_target::get_ada_task_ptid (long lwp, long thread)
{
- return ptid_build (ptid_get_pid (inferior_ptid), 0, thread);
+ return ptid_t (inferior_ptid.pid (), 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;
- /* 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_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
init.c. */
-void _initialize_aix_thread (void);
-
+void _initialize_aix_thread ();
void
-_initialize_aix_thread (void)
+_initialize_aix_thread ()
{
- init_aix_thread_ops ();
- complete_target_initialization (&aix_thread_ops);
-
/* Notice when object files get loaded and unloaded. */
- observer_attach_new_objfile (new_objfile);
+ gdb::observers::new_objfile.attach (new_objfile, "aix-thread");
+
+ /* 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,
+ "aix-thread");
add_setshow_boolean_cmd ("aix-thread", class_maintenance, &debug_aix_thread,
_("Set debugging of AIX thread module."),