/* Solaris threads debugging interface.
- Copyright (C) 1996-2013 Free Software Foundation, Inc.
+ Copyright (C) 1996-2015 Free Software Foundation, Inc.
This file is part of GDB.
#include "target.h"
#include "inferior.h"
#include <fcntl.h>
-#include "gdb_stat.h"
+#include <sys/stat.h>
#include <dlfcn.h>
#include "gdbcmd.h"
#include "gdbcore.h"
#include "solib.h"
#include "symfile.h"
#include "observer.h"
-#include "gdb_string.h"
#include "procfs.h"
+#include "symtab.h"
+#include "minsyms.h"
+#include "objfiles.h"
struct target_ops sol_thread_ops;
/* Default definitions: These must be defined in tm.h if they are to
be shared with a process module such as procfs. */
-#define GET_PID(ptid) ptid_get_pid (ptid)
-#define GET_LWP(ptid) ptid_get_lwp (ptid)
-#define GET_THREAD(ptid) ptid_get_tid (ptid)
-
-#define is_lwp(ptid) (GET_LWP (ptid) != 0)
-#define is_thread(ptid) (GET_THREAD (ptid) != 0)
-
-#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
-#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
-
/* Pointers to routines from libthread_db resolved by dlopen(). */
static void (*p_td_log)(const int on_off);
td_thrhandle_t th;
td_err_e val;
- if (is_lwp (thread_id))
+ if (ptid_lwp_p (thread_id))
return thread_id; /* It's already an LWP ID. */
/* It's a thread. Convert to LWP. */
- val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
+ val = p_td_ta_map_id2thr (main_ta, ptid_get_tid (thread_id), &th);
if (val == TD_NOTHR)
return pid_to_ptid (-1); /* Thread must have terminated. */
else if (val != TD_OK)
td_state_string (ti.ti_state));
}
- return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
+ return ptid_build (ptid_get_pid (thread_id), ti.ti_lid, 0);
}
/* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
td_thrhandle_t th;
td_err_e val;
- if (is_thread (lwp))
+ if (ptid_tid_p (lwp))
return lwp; /* It's already a thread ID. */
/* It's an LWP. Convert it to a thread ID. */
if (!target_thread_alive (lwp))
return pid_to_ptid (-1); /* Must be a defunct LPW. */
- val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
+ val = p_td_ta_map_lwp2thr (main_ta, ptid_get_lwp (lwp), &th);
if (val == TD_NOTHR)
return pid_to_ptid (-1); /* Thread must have terminated. */
else if (val != TD_OK)
else if (val != TD_OK)
error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
- return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
+ return ptid_build (ptid_get_pid (lwp), 0 , ti.ti_tid);
}
\f
program was started via the normal ptrace (PTRACE_TRACEME). */
static void
-sol_thread_detach (struct target_ops *ops, char *args, int from_tty)
+sol_thread_detach (struct target_ops *ops, const char *args, int from_tty)
{
struct target_ops *beneath = find_target_beneath (ops);
sol_thread_active = 0;
- inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
+ inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
unpush_target (ops);
beneath->to_detach (beneath, args, from_tty);
}
old_chain = save_inferior_ptid ();
- inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
- if (PIDGET (inferior_ptid) == -1)
+ inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
+ if (ptid_get_pid (inferior_ptid) == -1)
inferior_ptid = procfs_first_available ();
- if (PIDGET (ptid) != -1)
+ if (ptid_get_pid (ptid) != -1)
{
ptid_t save_ptid = ptid;
ptid = thread_to_lwp (ptid, -2);
- if (PIDGET (ptid) == -2) /* Inactive thread. */
+ if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
error (_("This version of Solaris can't start inactive threads."));
- if (info_verbose && PIDGET (ptid) == -1)
+ if (info_verbose && ptid_get_pid (ptid) == -1)
warning (_("Specified thread %ld seems to have terminated"),
- GET_THREAD (save_ptid));
+ ptid_get_tid (save_ptid));
}
beneath->to_resume (beneath, ptid, step, signo);
save_ptid = inferior_ptid;
old_chain = save_inferior_ptid ();
- inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
- if (PIDGET (inferior_ptid) == -1)
+ inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
+ if (ptid_get_pid (inferior_ptid) == -1)
inferior_ptid = procfs_first_available ();
- if (PIDGET (ptid) != -1)
+ if (ptid_get_pid (ptid) != -1)
{
ptid_t save_ptid = ptid;
ptid = thread_to_lwp (ptid, -2);
- if (PIDGET (ptid) == -2) /* Inactive thread. */
+ if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
error (_("This version of Solaris can't start inactive threads."));
- if (info_verbose && PIDGET (ptid) == -1)
+ if (info_verbose && ptid_get_pid (ptid) == -1)
warning (_("Specified thread %ld seems to have terminated"),
- GET_THREAD (save_ptid));
+ ptid_get_tid (save_ptid));
}
rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
{
/* Map the LWP of interest back to the appropriate thread ID. */
rtnval = lwp_to_thread (rtnval);
- if (PIDGET (rtnval) == -1)
+ if (ptid_get_pid (rtnval) == -1)
rtnval = save_ptid;
/* See if we have a new thread. */
- if (is_thread (rtnval)
+ if (ptid_tid_p (rtnval)
&& !ptid_equal (rtnval, save_ptid)
&& (!in_thread_list (rtnval)
|| is_exited (rtnval)))
gdb_fpregset_t *fpregset_p = &fpregset;
struct target_ops *beneath = find_target_beneath (ops);
- if (!is_thread (inferior_ptid))
+ if (!ptid_tid_p (inferior_ptid))
{
/* It's an LWP; pass the request on to the layer beneath. */
beneath->to_fetch_registers (beneath, regcache, regnum);
}
/* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
- thread = GET_THREAD (inferior_ptid);
+ thread = ptid_get_tid (inferior_ptid);
if (thread == 0)
error (_("sol_thread_fetch_registers: thread == 0"));
prgregset_t gregset;
prfpregset_t fpregset;
- if (!is_thread (inferior_ptid))
+ if (!ptid_tid_p (inferior_ptid))
{
struct target_ops *beneath = find_target_beneath (ops);
}
/* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
- thread = GET_THREAD (inferior_ptid);
+ thread = ptid_get_tid (inferior_ptid);
val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
if (val != TD_OK)
target_write_partial for details of each variant. One, and only
one, of readbuf or writebuf must be non-NULL. */
-static LONGEST
+static enum target_xfer_status
sol_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)
{
- int retval;
+ enum target_xfer_status retval;
struct cleanup *old_chain;
struct target_ops *beneath = find_target_beneath (ops);
old_chain = save_inferior_ptid ();
- if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
+ if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
{
/* It's either a thread or an LWP that isn't alive. Any live
LWP will do so use the first available.
inferior_ptid = procfs_first_available ();
}
- retval = beneath->to_xfer_partial (beneath, object, annex,
- readbuf, writebuf, offset, len);
+ retval = beneath->to_xfer_partial (beneath, object, annex, readbuf,
+ writebuf, offset, len, xfered_len);
do_cleanups (old_chain);
td_err_e err;
ptid_t ptid;
+ /* Don't attempt to use thread_db for remote targets. */
+ if (!(target_can_run (¤t_target) || core_bfd))
+ return;
+
/* Do nothing if we couldn't load libthread_db.so.1. */
if (p_td_ta_new == NULL)
return;
main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
ptid = lwp_to_thread (inferior_ptid);
- if (PIDGET (ptid) != -1)
+ if (ptid_get_pid (ptid) != -1)
inferior_ptid = ptid;
- target_find_new_threads ();
+ target_update_thread_list ();
break;
default:
static int
sol_thread_alive (struct target_ops *ops, ptid_t ptid)
{
- if (is_thread (ptid))
+ if (ptid_tid_p (ptid))
{
/* It's a (user-level) thread. */
td_err_e val;
td_thrhandle_t th;
int pid;
- pid = GET_THREAD (ptid);
+ pid = ptid_get_tid (ptid);
if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
return 0; /* Thread not found. */
if ((val = p_td_thr_validate (&th)) != TD_OK)
ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
{
- struct minimal_symbol *ms;
+ struct bound_minimal_symbol ms;
ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
- if (!ms)
+ if (!ms.minsym)
return PS_NOSYM;
- *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
+ *ld_symbol_addr = BMSYMBOL_VALUE_ADDRESS (ms);
return PS_OK;
}
old_chain = save_inferior_ptid ();
- if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
+ if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
{
/* It's either a thread or an LWP that isn't alive. Any live
LWP will do so use the first available.
old_chain = save_inferior_ptid ();
- inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
+ inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
target_fetch_registers (regcache, -1);
old_chain = save_inferior_ptid ();
- inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
+ inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
supply_gregset (regcache, (const gdb_gregset_t *) gregset);
vfprintf_filtered (gdb_stderr, fmt, args);
}
+/* Get size of extra register set. Currently a noop. */
+
+ps_err_e
+ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
+{
+ return PS_OK;
+}
+
+/* Get extra register set. Currently a noop. */
+
+ps_err_e
+ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+ return PS_OK;
+}
+
+/* Set extra register set. Currently a noop. */
+
+ps_err_e
+ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+ return PS_OK;
+}
+
/* Get floating-point registers for LWP. */
ps_err_e
old_chain = save_inferior_ptid ();
- inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
+ inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
target_fetch_registers (regcache, -1);
old_chain = save_inferior_ptid ();
- inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
+ inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
/* FIXME: can't I get the process ID from the prochandle or
something? */
- if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
+ if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
return PS_BADLID;
- ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
+ ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
+ lwpid, 0));
if (ret)
{
memcpy (pldt, ret, sizeof (struct ssd));
{
static char buf[100];
- if (is_thread (ptid))
+ if (ptid_tid_p (ptid))
{
ptid_t lwp;
lwp = thread_to_lwp (ptid, -2);
- if (PIDGET (lwp) == -1)
+ if (ptid_get_pid (lwp) == -1)
xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
- GET_THREAD (ptid));
- else if (PIDGET (lwp) != -2)
+ ptid_get_tid (ptid));
+ else if (ptid_get_pid (lwp) != -2)
xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
- GET_THREAD (ptid), GET_LWP (lwp));
+ ptid_get_tid (ptid), ptid_get_lwp (lwp));
else
- xsnprintf (buf, sizeof (buf), "Thread %ld ", GET_THREAD (ptid));
+ xsnprintf (buf, sizeof (buf), "Thread %ld ",
+ ptid_get_tid (ptid));
}
- else if (GET_LWP (ptid) != 0)
- xsnprintf (buf, sizeof (buf), "LWP %ld ", GET_LWP (ptid));
+ else if (ptid_get_lwp (ptid) != 0)
+ xsnprintf (buf, sizeof (buf), "LWP %ld ", ptid_get_lwp (ptid));
else
- xsnprintf (buf, sizeof (buf), "process %d ", PIDGET (ptid));
+ xsnprintf (buf, sizeof (buf), "process %d ", ptid_get_pid (ptid));
return buf;
}
\f
-/* Worker bee for find_new_threads. Callback function that gets
+/* Worker bee for update_thread_list. Callback function that gets
called once per user-level thread (i.e. not for LWP's). */
static int
-sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
+sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
{
td_err_e retval;
td_thrinfo_t ti;
if (retval != TD_OK)
return -1;
- ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
+ ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
if (!in_thread_list (ptid) || is_exited (ptid))
add_thread (ptid);
}
static void
-sol_find_new_threads (struct target_ops *ops)
+sol_update_thread_list (struct target_ops *ops)
{
struct target_ops *beneath = find_target_beneath (ops);
- /* First Find any new LWP's. */
- if (beneath->to_find_new_threads != NULL)
- beneath->to_find_new_threads (beneath);
+ /* Delete dead threads. */
+ prune_threads ();
+
+ /* Find any new LWP's. */
+ beneath->to_update_thread_list (beneath);
/* Then find any new user-level threads. */
- p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
+ p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}
printf_filtered (" startfunc=%s",
msym.minsym
- ? SYMBOL_PRINT_NAME (msym.minsym)
+ ? MSYMBOL_PRINT_NAME (msym.minsym)
: paddress (target_gdbarch (), ti.ti_startfunc));
}
printf_filtered (" sleepfunc=%s",
msym.minsym
- ? SYMBOL_PRINT_NAME (msym.minsym)
+ ? MSYMBOL_PRINT_NAME (msym.minsym)
: paddress (target_gdbarch (), ti.ti_pc));
}
}
static ptid_t
-sol_get_ada_task_ptid (long lwp, long thread)
+sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
{
struct thread_info *thread_info =
iterate_over_threads (thread_db_find_thread_from_tid, &thread);
{
/* The list of threads is probably not up to date. Find any
thread that is missing from the list, and try again. */
- sol_find_new_threads (¤t_target);
+ sol_update_thread_list (¤t_target);
thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
&thread);
}
sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
sol_thread_ops.to_thread_alive = sol_thread_alive;
sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
- sol_thread_ops.to_find_new_threads = sol_find_new_threads;
+ sol_thread_ops.to_update_thread_list = sol_update_thread_list;
sol_thread_ops.to_stratum = thread_stratum;
sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
sol_thread_ops.to_magic = OPS_MAGIC;
resolve (td_thr_getgregs);
resolve (td_thr_setgregs);
- add_target (&sol_thread_ops);
+ complete_target_initialization (&sol_thread_ops);
add_cmd ("sol-threads", class_maintenance, info_solthreads,
_("Show info on Solaris user threads."), &maintenanceinfolist);