* corelow.c (get_core_registers): Adjust.

(core_file_thread_alive): Rename to...
	(core_thread_alive): ... this.
	(core_pid_to_str): Try gdbarch_core_pid_to_str first.
	(init_core_ops): Adjust.
	(coreops_suppress_target): Delete.
	(_initialize_corelow): Unconditionally add core_ops.
	* procfs.c: Include "inf-child.h".
	(procfs_ops): Delete.
	(init_procfs_ops): Delete.  Reimplement as...
	(procfs_target): ... this, inheriting from inf-child.
	(procfs_attach, procfs_detach, procfs_fetch_registers): Adjust.
	(procfs_prepare_to_store): Delete.
	(procfs_store_registers, procfs_resume): Adjust.
	(procfs_open): Delete.
	(procfs_suppress_run): Delete.
	(procfs_can_run): Delete.
	(procfs_mourn_inferior): Adjust.
	(procfs_init_inferior): Add target_ops parameter.  Adjust.
	(procfs_create_inferior): Don't pass procfs_init_inferior to
	fork_inferior.  Instead call it after fork_inferior returns.
	(procfs_find_new_threads): Adjust.
	(_initialize_procfs): Adjust to use procfs_target instead of
	init_procfs_ops.
	* sol-thread.c (orig_core_ops, sol_core_ops): Delete.
	(lwp_to_thread): Use target_thread_alive.
	(sol_thread_open): Delete.
	(sol_thread_attach): Delete.
	(sol_thread_detach, sol_thread_resume, sol_thread_wait)
	(sol_thread_fetch_registers, sol_thread_store_registers): Adjust
	to use find_target_beneath.
	(sol_thread_prepare_to_store, sol_thread_xfer_memory): Delete.
	(sol_thread_xfer_partial): Adjust to use find_target_beneath.
	(sol_thread_files_info, sol_thread_kill_inferior): Delete.
	(check_for_thread_db): New.
	(sol_thread_notice_signals, sol_thread_create_inferior): Delete.
	(sol_thread_new_objfile): Call check_for_thread_db.
	(sol_thread_mourn_inferior): Adjust to use find_target_beneath.
	(sol_thread_can_run): Delete.
	(sol_thread_alive): Adjust to use find_target_beneath.
	(sol_thread_stop): Delete.
	(rw_common): Use target_write_memory or target_read_memory.
	(ps_lgetregs, ps_lgetfpregs): Use target_fetch_registers.
	(ps_lsetregs, ps_lsetfpregs): Use target_store_registers.
	(solaris_pid_to_str): Remove check for libthread_db initialization
	failing.
	(sol_find_new_threads): Remove check for libthread_db
	initialization failing, or for an invalid inferior_ptid.  Adjust
	to use find_target_beneath.
	(sol_core_open, sol_core_close, sol_core_detach,
	sol_core_files_info, sol_find_memory_regions,
	sol_make_note_section, ignore): Delete.
	(init_sol_thread_ops): Make it a thread_stratum target.  Remove
	unneeded callback settings.
	(init_sol_core_ops): Delete.
	(_initialize_sol_thread): No longer call init_sol_core_ops, set
	procfs_suppress_run, or hack with core_ops.

	* target.h (struct target_ops): Add a target_ops * parameter to
	to_resume, to_fetch_registers, to_store_registers, to_thread_alive
	and to_find_new_threads.
	(target_fetch_registers, target_store_registers)
	(target_thread_alive, target_find_new_threads): Redeclare as
	function.

	* target.c (update_current_target): Do not inherit or de_fault
	to_resume, to_fetch_registers, to_store_registers,
	to_thread_alive, to_find_new_threads.
	(target_resume): Adjust.
	(target_thread_alive, target_find_new_threads): New.
	(debug_to_resume, debug_to_fetch_registers): Delete.
	(target_fetch_registers): New.
	(debug_to_store_registers): Delete.
	(target_store_registers): New.
	(debug_to_thread_alive, debug_to_find_new_threads): Delete.
	(setup_target_debug): Adjust.

	* gdbcore.h (core_ops): Delete declaration.

	* inf-ptrace.c, linux-nat.c, remote.c, amd64-linux-nat.c,
	inf-child.c, linux-thread-db.c, bsd-uthread.c, inf-ttrace.c,
	i386-sol2-tdep.c, darwin-nat.c, gnu-nat.c, go32-nat.c,
	hpux-thread.c, i386-linux-nat.c, i386fbsd-nat.c, monitor.c,
	nto-procfs.c, remote-m32r-sdi.c, remote-mips.c, windows-nat.c,
	alphabsd-nat.c, amd64bsd-nat.c, arm-linux-nat.c, armnbsd-nat.c,
	bsd-kvm.c, hppa-hpux-nat.c, hppa-linux-nat.c, hppabsd-nat.c,
	hppanbsd-nat.c, i386-darwin-nat.c, i386bsd-nat.c,
	ia64-linux-nat.c, m32r-linux-nat.c, m68kbsd-nat.c,
	m68klinux-nat.c, m88kbsd-nat.c, mips-linux-nat.c,
	mips64obsd-nat.c, mipsnbsd-nat.c, ppc-linux-nat.c, ppcnbsd-nat.c,
	ppcobsd-nat.c, remote-sim.c, rs6000-nat.c, s390-nat.c,
	shnbsd-nat.c, sparc-nat.c, sparc-nat.h, spu-linux-nat.c,
	vaxbsd-nat.c, xtensa-linux-nat.c: Adjust to target_ops changes.

	* gdbarch.sh (core_pid_to_str): New gdbarch callback.
	* gdbarch.h, gdbarch.c: Regenerate.

	* sol2-tdep.c: Include "inferior.h".
	(sol2_core_pid_to_str): New.
	* sol2-tdep.h (sol2_core_pid_to_str): Declare.

	* amd64-sol2-tdep.c (amd64_sol2_init_abi): Set it.
	* sparc-sol2-tdep.c (sparc32_sol2_init_abi): Set it.
	* sparc64-sol2-tdep.c (sparc64_sol2_init_abi): Set it.
	* i386-sol2-tdep.c (i386_sol2_init_abi): Set it.
This commit is contained in:
Pedro Alves
2009-02-23 00:03:50 +00:00
parent f05219476d
commit 28439f5ef7
66 changed files with 801 additions and 906 deletions

View File

@ -68,18 +68,8 @@
#include "gdb_string.h"
extern struct target_ops sol_thread_ops; /* Forward declaration */
extern struct target_ops sol_core_ops; /* Forward declaration */
/* place to store core_ops before we overwrite it */
static struct target_ops orig_core_ops;
struct target_ops sol_thread_ops;
struct target_ops sol_core_ops;
extern int procfs_suppress_run;
extern struct target_ops procfs_ops; /* target vector for procfs.c */
extern struct target_ops core_ops; /* target vector for corelow.c */
extern char *procfs_pid_to_str (struct target_ops *ops, ptid_t ptid);
/* Prototypes for supply_gregset etc. */
@ -104,12 +94,7 @@ static struct ps_prochandle main_ph;
static td_thragent_t *main_ta;
static int sol_thread_active = 0;
static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo);
static int sol_thread_alive (ptid_t ptid);
static void sol_core_close (int quitting);
static void init_sol_thread_ops (void);
static void init_sol_core_ops (void);
/* Default definitions: These must be defined in tm.h if they are to
be shared with a process module such as procfs. */
@ -309,7 +294,7 @@ lwp_to_thread (ptid_t lwp)
/* It's an LWP. Convert it to a thread ID. */
if (!sol_thread_alive (lwp))
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);
@ -335,41 +320,8 @@ lwp_to_thread (ptid_t lwp)
/* Most target vector functions from here on actually just pass
through to procfs.c, as they don't need to do anything specific for
threads. */
static void
sol_thread_open (char *arg, int from_tty)
{
procfs_ops.to_open (arg, from_tty);
}
/* Attach to process PID, then initialize for debugging it and wait
for the trace-trap that results from attaching. */
static void
sol_thread_attach (struct target_ops *ops, char *args, int from_tty)
{
sol_thread_active = 0;
procfs_ops.to_attach (&procfs_ops, args, from_tty);
/* Must get symbols from shared libraries before libthread_db can run! */
solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
if (sol_thread_active)
{
ptid_t ptid;
printf_filtered ("sol-thread active.\n");
main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
push_target (&sol_thread_ops);
ptid = lwp_to_thread (inferior_ptid);
if (PIDGET (ptid) != -1)
thread_change_ptid (inferior_ptid, ptid);
}
/* FIXME: Might want to iterate over all the threads and register
them. */
}
through to the layer beneath, as they don't need to do anything
specific for threads. */
/* Take a program previously attached to and detaches it. The program
resumes execution and will no longer stop on signals, etc. We'd
@ -381,10 +333,12 @@ sol_thread_attach (struct target_ops *ops, char *args, int from_tty)
static void
sol_thread_detach (struct target_ops *ops, 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));
unpush_target (&sol_thread_ops);
procfs_ops.to_detach (&procfs_ops, args, from_tty);
unpush_target (ops);
beneath->to_detach (beneath, args, from_tty);
}
/* Resume execution of process PTID. If STEP is nozero, then just
@ -393,9 +347,11 @@ sol_thread_detach (struct target_ops *ops, char *args, int from_tty)
ID for procfs. */
static void
sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
sol_thread_resume (struct target_ops *ops,
ptid_t ptid, int step, enum target_signal signo)
{
struct cleanup *old_chain;
struct target_ops *beneath = find_target_beneath (ops);
old_chain = save_inferior_ptid ();
@ -415,7 +371,7 @@ sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
GET_THREAD (save_ptid));
}
procfs_ops.to_resume (ptid, step, signo);
beneath->to_resume (beneath, ptid, step, signo);
do_cleanups (old_chain);
}
@ -429,6 +385,7 @@ sol_thread_wait (struct target_ops *ops,
{
ptid_t rtnval;
ptid_t save_ptid;
struct target_ops *beneath = find_target_beneath (ops);
struct cleanup *old_chain;
save_ptid = inferior_ptid;
@ -450,7 +407,7 @@ sol_thread_wait (struct target_ops *ops,
GET_THREAD (save_ptid));
}
rtnval = procfs_ops.to_wait (&procfs_ops, ptid, ourstatus);
rtnval = beneath->to_wait (beneath, ptid, ourstatus);
if (ourstatus->kind != TARGET_WAITKIND_EXITED)
{
@ -477,7 +434,8 @@ sol_thread_wait (struct target_ops *ops,
}
static void
sol_thread_fetch_registers (struct regcache *regcache, int regnum)
sol_thread_fetch_registers (struct target_ops *ops,
struct regcache *regcache, int regnum)
{
thread_t thread;
td_thrhandle_t thandle;
@ -486,6 +444,7 @@ sol_thread_fetch_registers (struct regcache *regcache, int regnum)
prfpregset_t fpregset;
gdb_gregset_t *gregset_p = &gregset;
gdb_fpregset_t *fpregset_p = &fpregset;
struct target_ops *beneath = find_target_beneath (ops);
#if 0
int xregsize;
@ -494,11 +453,8 @@ sol_thread_fetch_registers (struct regcache *regcache, int regnum)
if (!is_thread (inferior_ptid))
{
/* It's an LWP; pass the request on to procfs. */
if (target_has_execution)
procfs_ops.to_fetch_registers (regcache, regnum);
else
orig_core_ops.to_fetch_registers (regcache, regnum);
/* It's an LWP; pass the request on to the layer beneath. */
beneath->to_fetch_registers (beneath, regcache, regnum);
return;
}
@ -555,7 +511,8 @@ sol_thread_fetch_registers (struct regcache *regcache, int regnum)
}
static void
sol_thread_store_registers (struct regcache *regcache, int regnum)
sol_thread_store_registers (struct target_ops *ops,
struct regcache *regcache, int regnum)
{
thread_t thread;
td_thrhandle_t thandle;
@ -569,8 +526,10 @@ sol_thread_store_registers (struct regcache *regcache, int regnum)
if (!is_thread (inferior_ptid))
{
/* It's an LWP; pass the request on to procfs.c. */
procfs_ops.to_store_registers (regcache, regnum);
struct target_ops *beneath = find_target_beneath (ops);
/* It's an LWP; pass the request on to the layer beneath. */
beneath->to_store_registers (beneath, regcache, regnum);
return;
}
@ -644,56 +603,6 @@ sol_thread_store_registers (struct regcache *regcache, int regnum)
#endif
}
/* Get ready to modify the registers array. On machines which store
individual registers, this doesn't need to do anything. On
machines which store all the registers in one fell swoop, this
makes sure that registers contains all the registers from the
program being debugged. */
static void
sol_thread_prepare_to_store (struct regcache *regcache)
{
procfs_ops.to_prepare_to_store (regcache);
}
/* Transfer LEN bytes between GDB address MYADDR and target address
MEMADDR. If DOWRITE is non-zero, transfer them to the target,
otherwise transfer them from the target. TARGET is unused.
Returns the number of bytes transferred. */
static int
sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
int dowrite, struct mem_attrib *attrib,
struct target_ops *target)
{
int retval;
struct cleanup *old_chain;
old_chain = save_inferior_ptid ();
if (is_thread (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.
NOTE: We don't need to call switch_to_thread; we're just
reading memory. */
inferior_ptid = procfs_first_available ();
}
if (target_has_execution)
retval = procfs_ops.deprecated_xfer_memory (memaddr, myaddr, len,
dowrite, attrib, target);
else
retval = orig_core_ops.deprecated_xfer_memory (memaddr, myaddr, len,
dowrite, attrib, target);
do_cleanups (old_chain);
return retval;
}
/* Perform partial transfers on OBJECT. See target_read_partial and
target_write_partial for details of each variant. One, and only
one, of readbuf or writebuf must be non-NULL. */
@ -706,6 +615,7 @@ sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
{
int retval;
struct cleanup *old_chain;
struct target_ops *beneath = find_target_beneath (ops);
old_chain = save_inferior_ptid ();
@ -719,59 +629,67 @@ sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
inferior_ptid = procfs_first_available ();
}
if (target_has_execution)
retval = procfs_ops.to_xfer_partial (ops, object, annex,
readbuf, writebuf, offset, len);
else
retval = orig_core_ops.to_xfer_partial (ops, object, annex,
readbuf, writebuf, offset, len);
retval = beneath->to_xfer_partial (beneath, object, annex,
readbuf, writebuf, offset, len);
do_cleanups (old_chain);
return retval;
}
/* Print status information about what we're accessing. */
static void
sol_thread_files_info (struct target_ops *ignore)
check_for_thread_db (void)
{
procfs_ops.to_files_info (ignore);
}
td_err_e err;
ptid_t ptid;
static void
sol_thread_kill_inferior (void)
{
procfs_ops.to_kill ();
}
/* Do nothing if we couldn't load libthread_db.so.1. */
if (p_td_ta_new == NULL)
return;
static void
sol_thread_notice_signals (ptid_t ptid)
{
procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
}
if (sol_thread_active)
/* Nothing to do. The thread library was already detected and the
target vector was already activated. */
return;
/* Fork an inferior process, and start debugging it with /proc. */
/* Now, initialize libthread_db. This needs to be done after the
shared libraries are located because it needs information from
the user's thread library. */
static void
sol_thread_create_inferior (struct target_ops *ops, char *exec_file,
char *allargs, char **env, int from_tty)
{
sol_thread_active = 0;
procfs_ops.to_create_inferior (&procfs_ops, exec_file, allargs, env, from_tty);
if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
err = p_td_init ();
if (err != TD_OK)
{
ptid_t ptid;
warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
return;
}
/* Save for xfer_memory. */
main_ph.ptid = inferior_ptid;
/* Now attempt to open a connection to the thread library. */
err = p_td_ta_new (&main_ph, &main_ta);
switch (err)
{
case TD_NOLIBTHREAD:
/* No thread library was detected. */
break;
case TD_OK:
printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
/* The thread library was detected. Activate the sol_thread target. */
push_target (&sol_thread_ops);
sol_thread_active = 1;
main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
ptid = lwp_to_thread (inferior_ptid);
if (PIDGET (ptid) != -1)
thread_change_ptid (inferior_ptid, ptid);
inferior_ptid = ptid;
target_find_new_threads ();
break;
default:
warning (_("Cannot initialize thread debugging library: %s"),
td_err_string (err));
break;
}
}
@ -784,40 +702,8 @@ sol_thread_create_inferior (struct target_ops *ops, char *exec_file,
static void
sol_thread_new_objfile (struct objfile *objfile)
{
td_err_e val;
if (!objfile)
{
sol_thread_active = 0;
return;
}
/* Don't do anything if init failed to resolve the libthread_db
library. */
if (!procfs_suppress_run)
return;
/* Now, initialize libthread_db. This needs to be done after the
shared libraries are located because it needs information from
the user's thread library. */
val = p_td_init ();
if (val != TD_OK)
{
warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val));
return;
}
val = p_td_ta_new (&main_ph, &main_ta);
if (val == TD_NOLIBTHREAD)
return;
else if (val != TD_OK)
{
warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val));
return;
}
sol_thread_active = 1;
if (objfile != NULL)
check_for_thread_db ();
}
/* Clean up after the inferior dies. */
@ -825,40 +711,19 @@ sol_thread_new_objfile (struct objfile *objfile)
static void
sol_thread_mourn_inferior (struct target_ops *ops)
{
struct target_ops *beneath = find_target_beneath (ops);
sol_thread_active = 0;
unpush_target (&sol_thread_ops);
procfs_ops.to_mourn_inferior (&procfs_ops);
unpush_target (ops);
beneath->to_mourn_inferior (beneath);
}
/* Mark our target-struct as eligible for stray "run" and "attach"
commands. */
static int
sol_thread_can_run (void)
{
return procfs_suppress_run;
}
/*
LOCAL FUNCTION
sol_thread_alive - test thread for "aliveness"
SYNOPSIS
static bool sol_thread_alive (ptid_t ptid);
DESCRIPTION
returns true if thread still active in inferior.
*/
/* Return true if PTID is still active in the inferior. */
static int
sol_thread_alive (ptid_t ptid)
sol_thread_alive (struct target_ops *ops, ptid_t ptid)
{
if (is_thread (ptid))
{
@ -876,19 +741,13 @@ sol_thread_alive (ptid_t ptid)
}
else
{
/* It's an LPW; pass the request on to procfs. */
if (target_has_execution)
return procfs_ops.to_thread_alive (ptid);
else
return orig_core_ops.to_thread_alive (ptid);
struct target_ops *beneath = find_target_beneath (ops);
/* It's an LPW; pass the request on to the layer below. */
return beneath->to_thread_alive (beneath, ptid);
}
}
static void
sol_thread_stop (ptid_t ptid)
{
procfs_ops.to_stop (ptid);
}
/* These routines implement the lower half of the thread_db interface,
i.e. the ps_* routines. */
@ -980,6 +839,7 @@ static ps_err_e
rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
char *buf, int size)
{
int ret;
struct cleanup *old_chain;
old_chain = save_inferior_ptid ();
@ -1001,50 +861,14 @@ rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
addr &= 0xffffffff;
#endif
while (size > 0)
{
int cc;
/* FIXME: passing 0 as attrib argument. */
if (target_has_execution)
cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
dowrite, 0, &procfs_ops);
else
cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
dowrite, 0, &core_ops);
if (cc < 0)
{
if (dowrite == 0)
print_sys_errmsg ("rw_common (): read", errno);
else
print_sys_errmsg ("rw_common (): write", errno);
do_cleanups (old_chain);
return PS_ERR;
}
else if (cc == 0)
{
if (dowrite == 0)
warning (_("rw_common (): unable to read at addr 0x%lx"),
(long) addr);
else
warning (_("rw_common (): unable to write at addr 0x%lx"),
(long) addr);
do_cleanups (old_chain);
return PS_ERR;
}
size -= cc;
buf += cc;
}
if (dowrite)
ret = target_write_memory (addr, buf, size);
else
ret = target_read_memory (addr, buf, size);
do_cleanups (old_chain);
return PS_OK;
return (ret == 0 ? PS_OK : PS_ERR);
}
/* Copies SIZE bytes from target process .data segment to debugger memory. */
@ -1096,10 +920,7 @@ ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
regcache = get_thread_regcache (inferior_ptid);
if (target_has_execution)
procfs_ops.to_fetch_registers (regcache, -1);
else
orig_core_ops.to_fetch_registers (regcache, -1);
target_fetch_registers (regcache, -1);
fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
do_cleanups (old_chain);
@ -1122,10 +943,7 @@ ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
regcache = get_thread_regcache (inferior_ptid);
supply_gregset (regcache, (const gdb_gregset_t *) gregset);
if (target_has_execution)
procfs_ops.to_store_registers (regcache, -1);
else
orig_core_ops.to_store_registers (regcache, -1);
target_store_registers (regcache, -1);
do_cleanups (old_chain);
@ -1232,10 +1050,7 @@ ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
regcache = get_thread_regcache (inferior_ptid);
if (target_has_execution)
procfs_ops.to_fetch_registers (regcache, -1);
else
orig_core_ops.to_fetch_registers (regcache, -1);
target_fetch_registers (regcache, -1);
fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
do_cleanups (old_chain);
@ -1258,10 +1073,7 @@ ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
regcache = get_thread_regcache (inferior_ptid);
supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
if (target_has_execution)
procfs_ops.to_store_registers (regcache, -1);
else
orig_core_ops.to_store_registers (regcache, -1);
target_store_registers (regcache, -1);
do_cleanups (old_chain);
@ -1328,10 +1140,6 @@ solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
static char buf[100];
/* In case init failed to resolve the libthread_db library. */
if (!procfs_suppress_run)
return procfs_pid_to_str (&procfs_ops, ptid);
if (is_thread (ptid))
{
ptid_t lwp;
@ -1377,21 +1185,13 @@ sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
}
static void
sol_find_new_threads (void)
sol_find_new_threads (struct target_ops *ops)
{
/* Don't do anything if init failed to resolve the libthread_db
library. */
if (!procfs_suppress_run)
return;
if (PIDGET (inferior_ptid) == -1)
{
printf_filtered ("No process.\n");
return;
}
struct target_ops *beneath = find_target_beneath (ops);
/* First Find any new LWP's. */
procfs_ops.to_find_new_threads ();
if (beneath->to_find_new_threads != NULL)
beneath->to_find_new_threads (beneath);
/* Then find any new user-level threads. */
p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
@ -1399,31 +1199,6 @@ sol_find_new_threads (void)
TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}
static void
sol_core_open (char *filename, int from_tty)
{
orig_core_ops.to_open (filename, from_tty);
}
static void
sol_core_close (int quitting)
{
orig_core_ops.to_close (quitting);
}
static void
sol_core_detach (struct target_ops *ops, char *args, int from_tty)
{
unpush_target (&core_ops);
orig_core_ops.to_detach (&orig_core_ops, args, from_tty);
}
static void
sol_core_files_info (struct target_ops *t)
{
orig_core_ops.to_files_info (t);
}
/* Worker bee for the "info sol-thread" command. This is a callback
function that gets called once for each Solaris user-level thread
(i.e. not for LWPs) in the inferior. Print anything interesting
@ -1511,119 +1286,32 @@ info_solthreads (char *args, int from_tty)
TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}
static int
sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
int, int, int, void *),
void *data)
{
return procfs_ops.to_find_memory_regions (func, data);
}
static char *
sol_make_note_section (bfd *obfd, int *note_size)
{
return procfs_ops.to_make_corefile_notes (obfd, note_size);
}
static int
ignore (struct bp_target_info *bp_tgt)
{
return 0;
}
static void
init_sol_thread_ops (void)
{
sol_thread_ops.to_shortname = "solaris-threads";
sol_thread_ops.to_longname = "Solaris threads and pthread.";
sol_thread_ops.to_doc = "Solaris threads and pthread support.";
sol_thread_ops.to_open = sol_thread_open;
sol_thread_ops.to_attach = sol_thread_attach;
sol_thread_ops.to_detach = sol_thread_detach;
sol_thread_ops.to_resume = sol_thread_resume;
sol_thread_ops.to_wait = sol_thread_wait;
sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
sol_thread_ops.to_store_registers = sol_thread_store_registers;
sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
sol_thread_ops.to_files_info = sol_thread_files_info;
sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
sol_thread_ops.to_terminal_init = terminal_init_inferior;
sol_thread_ops.to_terminal_inferior = terminal_inferior;
sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
sol_thread_ops.to_terminal_ours = terminal_ours;
sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
sol_thread_ops.to_terminal_info = child_terminal_info;
sol_thread_ops.to_kill = sol_thread_kill_inferior;
sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
sol_thread_ops.to_can_run = sol_thread_can_run;
sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
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_stop = sol_thread_stop;
sol_thread_ops.to_stratum = process_stratum;
sol_thread_ops.to_has_all_memory = 1;
sol_thread_ops.to_has_memory = 1;
sol_thread_ops.to_has_stack = 1;
sol_thread_ops.to_has_registers = 1;
sol_thread_ops.to_has_execution = 1;
sol_thread_ops.to_has_thread_control = tc_none;
sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
sol_thread_ops.to_stratum = thread_stratum;
sol_thread_ops.to_magic = OPS_MAGIC;
}
static void
init_sol_core_ops (void)
{
sol_core_ops.to_shortname = "solaris-core";
sol_core_ops.to_longname = "Solaris core threads and pthread.";
sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
sol_core_ops.to_open = sol_core_open;
sol_core_ops.to_close = sol_core_close;
sol_core_ops.to_attach = sol_thread_attach;
sol_core_ops.to_detach = sol_core_detach;
sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
sol_core_ops.to_files_info = sol_core_files_info;
sol_core_ops.to_insert_breakpoint = ignore;
sol_core_ops.to_remove_breakpoint = ignore;
sol_core_ops.to_create_inferior = sol_thread_create_inferior;
sol_core_ops.to_stratum = core_stratum;
sol_core_ops.to_has_memory = 1;
sol_core_ops.to_has_stack = 1;
sol_core_ops.to_has_registers = 1;
sol_core_ops.to_has_thread_control = tc_none;
sol_core_ops.to_thread_alive = sol_thread_alive;
sol_core_ops.to_pid_to_str = solaris_pid_to_str;
/* On Solaris/x86, when debugging a threaded core file from process
<n>, the following causes "info threads" to produce "procfs:
couldn't find pid <n> in procinfo list" where <n> is the pid of
the process that produced the core file. Disable it for now. */
#if 0
sol_core_ops.to_find_new_threads = sol_find_new_threads;
#endif
sol_core_ops.to_magic = OPS_MAGIC;
}
/* We suppress the call to add_target of core_ops in corelow because
if there are two targets in the stratum core_stratum,
find_core_target won't know which one to return. See corelow.c for
an additonal comment on coreops_suppress_target. */
int coreops_suppress_target = 1;
void
_initialize_sol_thread (void)
{
void *dlhandle;
init_sol_thread_ops ();
init_sol_core_ops ();
dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
if (!dlhandle)
@ -1659,19 +1347,9 @@ _initialize_sol_thread (void)
add_target (&sol_thread_ops);
procfs_suppress_run = 1;
add_cmd ("sol-threads", class_maintenance, info_solthreads,
_("Show info on Solaris user threads."), &maintenanceinfolist);
/* FIXME: This code takes errant advantage of the order in which
initialization routines are run. _initialize_corelow must run before
this one otherwise orig_core_ops will still contain zeros and the work
of init_sol_core_ops will be undone. */
memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
add_target (&core_ops);
/* Hook into new_objfile notification. */
observer_attach_new_objfile (sol_thread_new_objfile);
return;
@ -1683,8 +1361,5 @@ _initialize_sol_thread (void)
if (dlhandle)
dlclose (dlhandle);
/* Allow the user to debug non-threaded core files. */
add_target (&core_ops);
return;
}