static ptid_t thread_to_lwp (ptid_t thread_id, int default_lwp) { td_thrinfo_t ti; td_thrhandle_t th; td_err_e val; if (is_lwp (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); if (val == TD_NOTHR) return pid_to_ptid (-1); /* thread must have terminated */ else if (val != TD_OK) error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val)); val = p_td_thr_get_info (&th, &ti); if (val == TD_NOTHR) return pid_to_ptid (-1); /* thread must have terminated */ else if (val != TD_OK) error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val)); if (ti.ti_state != TD_THR_ACTIVE) { if (default_lwp != -1) return pid_to_ptid (default_lwp); error ("thread_to_lwp: thread state not active: %s", td_state_string (ti.ti_state)); } return BUILD_LWP (ti.ti_lid, PIDGET (thread_id)); }
void sol_thread_new_objfile (struct objfile *objfile) { td_err_e val; if (!objfile) { sol_thread_active = 0; goto quit; } /* don't do anything if init failed to resolve the libthread_db library */ if (!procfs_suppress_run) 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 user's thread library. */ val = p_td_init (); if (val != TD_OK) { 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) goto quit; else if (val != TD_OK) { 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); }
static void nbsd_thread_unsuspend(void) { int i, val; for (i = 0; i < nsusp; i++) { val = td_thr_resume(susp[i]); if (val != 0) error ("nbsd_thread_unsuspend: td_thr_resume(%p): %s", susp[i], td_err_string (val)); } nsusp = 0; }
static ptid_t lwp_to_thread (ptid_t lwp) { td_thrinfo_t ti; td_thrhandle_t th; td_err_e val; if (is_thread (lwp)) return lwp; /* It's already a thread id */ /* It's an lwp. Convert it to a thread id. */ if (!sol_thread_alive (lwp)) return pid_to_ptid (-1); /* defunct lwp */ val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th); if (val == TD_NOTHR) return pid_to_ptid (-1); /* thread must have terminated */ else if (val != TD_OK) error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val)); val = p_td_thr_validate (&th); if (val == TD_NOTHR) return lwp; /* libthread doesn't know about it; just return lwp */ else if (val != TD_OK) error ("lwp_to_thread: td_thr_validate: %s.", td_err_string (val)); val = p_td_thr_get_info (&th, &ti); if (val == TD_NOTHR) return pid_to_ptid (-1); /* thread must have terminated */ 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)); }
static void nbsd_thread_new_objfile (struct objfile *objfile) { int val; if (!objfile) { nbsd_thread_active = 0; goto quit; } /* Don't do anything if we've already fired up the debugging library */ if (nbsd_thread_active) 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 user's thread library. */ val = td_open (&nbsd_thread_callbacks, &main_arg, &main_ta); if (val == TD_ERR_NOLIB) goto quit; else if (val != 0) { warning ("nbsd_thread_new_objfile: td_open: %s", td_err_string (val)); goto quit; } nbsd_thread_present = 1; if ((nbsd_thread_core == 0) && !ptid_equal (inferior_ptid, null_ptid)) { push_target (&nbsd_thread_ops); nbsd_thread_activate(); } quit: return; }
static void sol_thread_store_registers (int regno) { thread_t thread; td_thrhandle_t thandle; td_err_e val; prgregset_t gregset; prfpregset_t fpregset; #if 0 int xregsize; caddr_t xregset; #endif if (!is_thread (inferior_ptid)) { /* LWP: pass the request on to procfs.c */ procfs_ops.to_store_registers (regno); return; } /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */ thread = GET_THREAD (inferior_ptid); val = p_td_ta_map_id2thr (main_ta, thread, &thandle); if (val != TD_OK) error ("sol_thread_store_registers: td_ta_map_id2thr %s", td_err_string (val)); if (regno != -1) { /* Not writing all the regs */ char old_value[MAX_REGISTER_SIZE]; /* Save new register value. */ regcache_collect (regno, old_value); val = p_td_thr_getgregs (&thandle, gregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getgregs %s", td_err_string (val)); val = p_td_thr_getfpregs (&thandle, &fpregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getfpregs %s", td_err_string (val)); /* Restore new register value. */ supply_register (regno, old_value); #if 0 /* thread_db doesn't seem to handle this right */ val = td_thr_getxregsize (&thandle, &xregsize); if (val != TD_OK && val != TD_NOXREGS) error ("sol_thread_store_registers: td_thr_getxregsize %s", td_err_string (val)); if (val == TD_OK) { xregset = alloca (xregsize); val = td_thr_getxregs (&thandle, xregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getxregs %s", td_err_string (val)); } #endif } fill_gregset ((gdb_gregset_t *) &gregset, regno); fill_fpregset ((gdb_fpregset_t *) &fpregset, regno); val = p_td_thr_setgregs (&thandle, gregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_setgregs %s", td_err_string (val)); val = p_td_thr_setfpregs (&thandle, &fpregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_setfpregs %s", td_err_string (val)); #if 0 /* thread_db doesn't seem to handle this right */ val = td_thr_getxregsize (&thandle, &xregsize); if (val != TD_OK && val != TD_NOXREGS) error ("sol_thread_store_registers: td_thr_getxregsize %s", td_err_string (val)); /* Should probably do something about writing the xregs here, but what are they? */ #endif }
static void sol_thread_fetch_registers (int regno) { thread_t thread; td_thrhandle_t thandle; td_err_e val; prgregset_t gregset; prfpregset_t fpregset; #if 0 int xregsize; caddr_t xregset; #endif if (!is_thread (inferior_ptid)) { /* LWP: pass the request on to procfs.c */ if (target_has_execution) procfs_ops.to_fetch_registers (regno); else orig_core_ops.to_fetch_registers (regno); return; } /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */ thread = GET_THREAD (inferior_ptid); if (thread == 0) error ("sol_thread_fetch_registers: thread == 0"); val = p_td_ta_map_id2thr (main_ta, thread, &thandle); if (val != TD_OK) error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s", td_err_string (val)); /* Get the integer regs */ val = p_td_thr_getgregs (&thandle, gregset); if (val != TD_OK && val != TD_PARTIALREG) error ("sol_thread_fetch_registers: td_thr_getgregs %s", td_err_string (val)); /* For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7, pc and sp are saved (by a thread context switch). */ /* And, now the fp regs */ val = p_td_thr_getfpregs (&thandle, &fpregset); if (val != TD_OK && val != TD_NOFPREGS) error ("sol_thread_fetch_registers: td_thr_getfpregs %s", td_err_string (val)); /* Note that we must call supply_{g fp}regset *after* calling the td routines because the td routines call ps_lget* which affect the values stored in the registers array. */ supply_gregset ((gdb_gregset_t *) &gregset); supply_fpregset ((gdb_fpregset_t *) &fpregset); #if 0 /* thread_db doesn't seem to handle this right */ val = td_thr_getxregsize (&thandle, &xregsize); if (val != TD_OK && val != TD_NOXREGS) error ("sol_thread_fetch_registers: td_thr_getxregsize %s", td_err_string (val)); if (val == TD_OK) { xregset = alloca (xregsize); val = td_thr_getxregs (&thandle, xregset); if (val != TD_OK) error ("sol_thread_fetch_registers: td_thr_getxregs %s", td_err_string (val)); } #endif }