/* Low level interface for debugging AIX 4.3+ pthreads.
- Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Copyright (C) 1999-2015 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 "objfiles.h"
#include <procinfo.h>
#include <sys/types.h>
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",
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);
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;
+ thread->priv = XNEW (struct private_thread_info);
+ thread->priv->pdtid = pbuf[pi].pdtid;
+ thread->priv->tid = pbuf[pi].tid;
pi++;
}
else
if (cmp_result == 0)
{
- gbuf[gi]->private->pdtid = pdtid;
- gbuf[gi]->private->tid = tid;
+ gbuf[gi]->priv->pdtid = pdtid;
+ gbuf[gi]->priv->tid = tid;
pi++;
gi++;
}
else
{
thread = add_thread (pptid);
- thread->private = xmalloc (sizeof (struct private_thread_info));
- thread->private->pdtid = pdtid;
- thread->private->tid = tid;
+ thread->priv = XNEW (struct private_thread_info);
+ thread->priv->pdtid = pdtid;
+ thread->priv->tid = tid;
pi++;
}
}
{
const pthdb_tid_t tid = *(pthdb_tid_t *)tidp;
- return (thread->private->tid == tid);
+ return (thread->priv->tid == tid);
}
/* Synchronize libpthdebug's state with the inferior and with GDB,
{
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;
/* Attach to process specified by ARGS. */
static void
-aix_thread_attach (struct target_ops *ops, char *args, int from_tty)
+aix_thread_inferior_created (struct target_ops *ops, int from_tty)
{
- 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(). */
error (_("aix-thread resume: unknown pthread %ld"),
ptid_get_lwp (ptid));
- tid[0] = thread->private->tid;
+ tid[0] = thread->priv->tid;
if (tid[0] == PTHDB_INVALID_TID)
error (_("aix-thread resume: no tid for pthread %ld"),
ptid_get_lwp (ptid));
else
{
thread = find_thread_ptid (inferior_ptid);
- tid = thread->private->tid;
+ tid = thread->priv->tid;
if (tid == PTHDB_INVALID_TID)
- fetch_regs_user_thread (regcache, thread->private->pdtid);
+ fetch_regs_user_thread (regcache, thread->priv->pdtid);
else
fetch_regs_kernel_thread (regcache, regno, tid);
}
else
{
thread = find_thread_ptid (inferior_ptid);
- tid = thread->private->tid;
+ tid = thread->priv->tid;
if (tid == PTHDB_INVALID_TID)
- store_regs_user_thread (regcache, thread->private->pdtid);
+ store_regs_user_thread (regcache, thread->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
+static enum target_xfer_status
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)
+ ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
{
struct cleanup *old_chain = save_inferior_ptid ();
- LONGEST xfer;
+ enum target_xfer_status xfer;
struct target_ops *beneath = find_target_beneath (ops);
inferior_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
- xfer = beneath->to_xfer_partial (beneath, object, annex,
- readbuf, writebuf, offset, len);
+ xfer = beneath->to_xfer_partial (beneath, object, annex, readbuf,
+ writebuf, offset, len, xfered_len);
do_cleanups (old_chain);
return xfer;
THREAD, for use in "info threads" output. */
static char *
-aix_thread_extra_thread_info (struct thread_info *thread)
+aix_thread_extra_thread_info (struct target_ops *self,
+ struct thread_info *thread)
{
struct ui_file *buf;
int status;
buf = mem_fileopen ();
- pdtid = thread->private->pdtid;
- tid = thread->private->tid;
+ pdtid = thread->priv->pdtid;
+ tid = thread->priv->tid;
if (tid != PTHDB_INVALID_TID)
/* i18n: Like "thread-identifier %d, [state] running, suspended" */
}
static ptid_t
-aix_thread_get_ada_task_ptid (long lwp, long thread)
+aix_thread_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
{
return ptid_build (ptid_get_pid (inferior_ptid), 0, thread);
}
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;
/* Notice when object files get loaded and unloaded. */
observer_attach_new_objfile (new_objfile);
+ /* Add ourselves to inferior_created event chain.
+ This is needed to enable the thread target on "attach". */
+ observer_attach_inferior_created (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."),