#include "target.h"
#include "inferior.h"
#include <fcntl.h>
-#include <unistd.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include "gdbcmd.h"
static void init_sol_thread_ops PARAMS ((void));
static void init_sol_core_ops PARAMS ((void));
-#define THREAD_FLAG 0x80000000
-#define is_thread(ARG) (((ARG) & THREAD_FLAG) != 0)
-#define is_lwp(ARG) (((ARG) & THREAD_FLAG) == 0)
-#define GET_LWP(LWP_ID) (TIDGET(LWP_ID))
-#define GET_THREAD(THREAD_ID) (((THREAD_ID) >> 16) & 0x7fff)
-#define BUILD_LWP(LWP_ID, PID) ((LWP_ID) << 16 | (PID))
+/* Default definitions: These must be defined in tm.h
+ if they are to be shared with a process module such as procfs. */
+
+#define THREAD_FLAG 0x80000000
+#define is_thread(ARG) (((ARG) & THREAD_FLAG) != 0)
+#define is_lwp(ARG) (((ARG) & THREAD_FLAG) == 0)
+#define GET_LWP(PID) TIDGET (PID)
+#define GET_THREAD(PID) (((PID) >> 16) & 0x7fff)
+#define BUILD_LWP(TID, PID) ((TID) << 16 | (PID))
+
#define BUILD_THREAD(THREAD_ID, PID) (THREAD_FLAG | BUILD_LWP (THREAD_ID, PID))
/* Pointers to routines from lithread_db resolved by dlopen() */
char *args;
int from_tty;
{
+ inferior_pid = PIDGET (main_ph.pid);
unpush_target (&sol_thread_ops);
procfs_ops.to_detach (args, from_tty);
}
those variables don't show up until the library gets mapped and the symbol
table is read in. */
+/* This new_objfile event is now managed by a chained function pointer.
+ * It is the callee's responsability to call the next client on the chain.
+ */
+
+/* Saved pointer to previous owner of the new_objfile event. */
+static void (*target_new_objfile_chain) PARAMS ((struct objfile *));
+
void
sol_thread_new_objfile (objfile)
struct objfile *objfile;
if (!objfile)
{
sol_thread_active = 0;
-
- return;
+ goto quit;
}
/* don't do anything if init failed to resolve the libthread_db library */
if (!procfs_suppress_run)
- return;
+ goto quit;
/* Now, initialize the thread debugging library. This needs to be done after
the shared libraries are located because it needs information from the
val = p_td_init ();
if (val != TD_OK)
- error ("target_new_objfile: td_init: %s", td_err_string (val));
+ {
+ warning ("sol_thread_new_objfile: td_init: %s", td_err_string (val));
+ goto quit;
+ }
val = p_td_ta_new (&main_ph, &main_ta);
if (val == TD_NOLIBTHREAD)
- return;
+ goto quit;
else if (val != TD_OK)
- error ("target_new_objfile: td_ta_new: %s", td_err_string (val));
+ {
+ warning ("sol_thread_new_objfile: td_ta_new: %s", td_err_string (val));
+ goto quit;
+ }
sol_thread_active = 1;
+quit:
+ /* Call predecessor on chain, if any. */
+ if (target_new_objfile_chain)
+ target_new_objfile_chain (objfile);
}
/* Clean up after the inferior dies. */
by the time we call anything in thread_db, these routines need to do
nothing. */
+/* Process stop */
+
ps_err_e
ps_pstop (gdb_ps_prochandle_t ph)
{
return PS_OK;
}
+/* Process continue */
+
ps_err_e
ps_pcontinue (gdb_ps_prochandle_t ph)
{
return PS_OK;
}
+/* LWP stop */
+
ps_err_e
ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
{
return PS_OK;
}
+/* LWP continue */
+
ps_err_e
ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
{
return PS_OK;
}
+/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
+
ps_err_e
ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
const char *ld_symbol_name, paddr_t * ld_symbol_addr)
return PS_OK;
}
+/* Copies SIZE bytes from target process .data segment to debugger memory. */
+
ps_err_e
ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr,
gdb_ps_read_buf_t buf, gdb_ps_size_t size)
return rw_common (0, ph, addr, buf, size);
}
+/* Copies SIZE bytes from debugger memory .data segment to target process. */
+
ps_err_e
ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr,
gdb_ps_write_buf_t buf, gdb_ps_size_t size)
return rw_common (1, ph, addr, (char *) buf, size);
}
+/* Copies SIZE bytes from target process .text segment to debugger memory. */
+
ps_err_e
ps_ptread (gdb_ps_prochandle_t ph, paddr_t addr,
gdb_ps_read_buf_t buf, gdb_ps_size_t size)
return rw_common (0, ph, addr, buf, size);
}
+/* Copies SIZE bytes from debugger memory .text segment to target process. */
+
ps_err_e
ps_ptwrite (gdb_ps_prochandle_t ph, paddr_t addr,
gdb_ps_write_buf_t buf, gdb_ps_size_t size)
return rw_common (1, ph, addr, (char *) buf, size);
}
-/* Get integer regs */
+/* Get integer regs for LWP */
ps_err_e
ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
return PS_OK;
}
-/* Set integer regs */
+/* Set integer regs for LWP */
ps_err_e
ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
return PS_OK;
}
+/* Log a message (sends to gdb_stderr). */
+
void
ps_plog (const char *fmt,...)
{
return PS_OK;
}
-/* Get floating-point regs. */
+/* Get floating-point regs for LWP */
ps_err_e
ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
return PS_OK;
}
-/* Set floating-point regs. */
+/* Set floating-point regs for LWP */
ps_err_e
ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
static int nldt_allocated = 0;
static struct ssd *ldt_bufp = NULL;
+/* Reads the local descriptor table of a LWP. */
+
ps_err_e
ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
struct ssd *pldt)
return 0;
}
-void
+static void
sol_find_new_threads ()
{
/* don't do anything if init failed to resolve the libthread_db library */
{
td_err_e ret;
td_thrinfo_t ti;
- struct minimal_symbol *msym;
if ((ret = p_td_thr_get_info (th, &ti)) == TD_OK)
{
}
/* Print thr_create start function: */
if (ti.ti_startfunc != 0)
- if (msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc))
- printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym));
- else
- printf_filtered (" startfunc: 0x%08x\n", ti.ti_startfunc);
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
+ if (msym)
+ printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym));
+ else
+ printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc));
+ }
/* If thread is asleep, print function that went to sleep: */
if (ti.ti_state == TD_THR_SLEEP)
- if (msym = lookup_minimal_symbol_by_pc (ti.ti_pc))
- printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym));
- else
- printf_filtered (" - Sleep func: 0x%08x\n", ti.ti_startfunc);
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
+ if (msym)
+ printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym));
+ else
+ printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
+ }
/* Wrap up line, if necessary */
if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
add_target (&core_ops);
+ /* Hook into new_objfile notification. */
+ target_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = sol_thread_new_objfile;
return;
die: