mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-17 12:53:17 +08:00
* 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:
515
gdb/sol-thread.c
515
gdb/sol-thread.c
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user