#include "gdbcmd.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;
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 PARAMS ((int pid));
/* Note that these prototypes differ slightly from those used in procfs.c
enum target_signal signo));
static int lwp_to_thread PARAMS ((int lwp));
static int sol_thread_alive PARAMS ((int pid));
+static void sol_core_close PARAMS ((int quitting));
#define THREAD_FLAG 0x80000000
#define is_thread(ARG) (((ARG) & THREAD_FLAG) != 0)
if (!is_thread (inferior_pid))
{ /* LWP: pass the request on to procfs.c */
- procfs_ops.to_fetch_registers (regno);
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (regno);
+ else
+ orig_core_ops.to_fetch_registers (regno);
return;
}
inferior_pid = procfs_first_available (); /* Find any live lwp. */
/* Note: don't need to call switch_to_thread; we're just reading memory. */
- retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target);
+ if (target_has_execution)
+ retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target);
+ else
+ retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len,
+ dowrite, target);
do_cleanups (old_chain);
return 1; /* known thread: return true */
}
else /* kernel thread (LWP): let procfs test it */
- return procfs_ops.to_thread_alive (pid);
+ {
+ if (target_has_execution)
+ return procfs_ops.to_thread_alive (pid);
+ else
+ return orig_core_ops.to_thread_alive (pid);
+ }
}
static void
{
int cc;
- cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, &procfs_ops);
+ if (target_has_execution)
+ cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, &procfs_ops);
+ else
+ cc = orig_core_ops.to_xfer_memory (addr, buf, size, dowrite, &core_ops);
if (cc < 0)
{
inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
- procfs_ops.to_fetch_registers (-1);
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (-1);
+ else
+ orig_core_ops.to_fetch_registers (-1);
fill_gregset (gregset, -1);
do_cleanups (old_chain);
inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
supply_gregset (gregset);
- procfs_ops.to_store_registers (-1);
+ if (target_has_execution)
+ procfs_ops.to_store_registers (-1);
+ else
+ orig_core_ops.to_store_registers (-1);
do_cleanups (old_chain);
inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
- procfs_ops.to_fetch_registers (-1);
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (-1);
+ else
+ orig_core_ops.to_fetch_registers (-1);
fill_fpregset (*fpregset, -1);
do_cleanups (old_chain);
inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));
supply_fpregset (*fpregset);
- procfs_ops.to_store_registers (-1);
+ if (target_has_execution)
+ procfs_ops.to_store_registers (-1);
+ else
+ orig_core_ops.to_store_registers (-1);
do_cleanups (old_chain);
TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}
+static void
+sol_core_open (filename, from_tty)
+ char *filename;
+ int from_tty;
+{
+ orig_core_ops.to_open (filename, from_tty);
+}
+
+static void
+sol_core_close (quitting)
+ int quitting;
+{
+ orig_core_ops.to_close (quitting);
+}
+
+static void
+sol_core_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ unpush_target (&core_ops);
+ orig_core_ops.to_detach (args, from_tty);
+}
+
+static void
+sol_core_files_info (t)
+ struct target_ops *t;
+{
+ orig_core_ops.to_files_info (t);
+}
+
#ifdef MAINTENANCE_CMDS
/* Worker bee for info sol-thread command. This is a callback function that
gets called once for each Solaris thread (ie. not kernel thread) in the
}
#endif /* MAINTENANCE_CMDS */
+static int
+ignore (addr, contents)
+ CORE_ADDR addr;
+ char *contents;
+{
+ return 0;
+}
+
struct target_ops sol_thread_ops = {
"solaris-threads", /* to_shortname */
"Solaris threads and pthread.", /* to_longname */
OPS_MAGIC /* to_magic */
};
+struct target_ops sol_core_ops = {
+ "solaris-core", /* to_shortname */
+ "Solaris core threads and pthread.", /* to_longname */
+ "Solaris threads and pthread support for core files.", /* to_doc */
+ sol_core_open, /* to_open */
+ sol_core_close, /* to_close */
+ sol_thread_attach, /* XXX to_attach */
+ sol_core_detach, /* to_detach */
+ 0, /* to_resume */
+ 0, /* to_wait */
+ sol_thread_fetch_registers, /* to_fetch_registers */
+ 0, /* to_store_registers */
+ 0, /* to_prepare_to_store */
+ sol_thread_xfer_memory, /* XXX to_xfer_memory */
+ sol_core_files_info, /* to_files_info */
+ ignore, /* to_insert_breakpoint */
+ ignore, /* to_remove_breakpoint */
+ 0, /* to_terminal_init */
+ 0, /* to_terminal_inferior */
+ 0, /* to_terminal_ours_for_output */
+ 0, /* to_terminal_ours */
+ 0, /* to_terminal_info */
+ 0, /* to_kill */
+ 0, /* to_load */
+ 0, /* to_lookup_symbol */
+ sol_thread_create_inferior, /* XXX to_create_inferior */
+ 0, /* to_mourn_inferior */
+ 0, /* to_can_run */
+ 0, /* to_notice_signals */
+ 0, /* to_thread_alive */
+ 0, /* to_stop */
+ core_stratum, /* to_stratum */
+ 0, /* to_next */
+ 0, /* to_has_all_memory */
+ 1, /* to_has_memory */
+ 1, /* to_has_stack */
+ 1, /* to_has_registers */
+ 0, /* to_has_execution */
+ 0, /* sections */
+ 0, /* sections_end */
+ OPS_MAGIC /* to_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 ()
{
"Show info on Solaris user threads.\n", &maintenanceinfolist);
#endif /* MAINTENANCE_CMDS */
+ memcpy(&orig_core_ops, &core_ops, sizeof (struct target_ops));
+ memcpy(&core_ops, &sol_core_ops, sizeof (struct target_ops));
+ add_target (&core_ops);
+
return;
die:
if (dlhandle)
dlclose (dlhandle);
+ /* allow the user to debug non-threaded core files */
+ add_target(&core_ops);
+
return;
}