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)); }
ps_err_e ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); supply_gregset ((gdb_gregset_t *) gregset); target_store_registers (-1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lgetxmmregs (struct ps_prochandle *ph, lwpid_t lwpid, char *xmmregs) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); target_fetch_registers (-1); i387_fill_fxsave (xmmregs, -1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, prfpregset_t *fpregset) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); target_fetch_registers (-1); fill_fpregset (fpregset, -1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lsetxmmregs (struct ps_prochandle *ph, lwpid_t lwpid, const char *xmmregs) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); i387_supply_fxsave (current_regcache, -1, xmmregs); target_store_registers (-1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) { struct cleanup *old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, ph->pid); target_fetch_registers (-1); fill_gregset ((gdb_gregset_t *) gregset, -1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset) { struct cleanup *old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, ph->pid); /* FIXME: We should really make supply_gregset const-correct. */ supply_gregset ((gdb_gregset_t *) gregset); target_store_registers (-1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); /* XXX: Target operation isn't lwp aware: replace pid with lwp */ inferior_ptid = BUILD_LWP (0, lwpid); target_fetch_registers (-1); fill_gregset (gregset, -1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lgetxmmregs (struct ps_prochandle *ph, lwpid_t lwpid, char *xmmregs) { struct cleanup *old_chain; struct regcache *regcache; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, ph->pid); regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); target_fetch_registers (regcache, -1); i387_collect_fxsave (regcache, -1, xmmregs); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, prfpregset_t *fpregset) { struct cleanup *old_chain; struct regcache *regcache; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, ph->pid); regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); target_fetch_registers (regcache, -1); fill_fpregset (regcache, fpregset, -1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset) { struct cleanup *old_chain; struct regcache *regcache; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, ph->pid); regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); supply_gregset (regcache, gregset); target_store_registers (regcache, -1); do_cleanups (old_chain); return PS_OK; }
static void get_current_thread () { td_thrhandle_t th; td_thrinfo_t ti; long lwp; ptid_t tmp, ptid; lwp = get_current_lwp (proc_handle.pid); tmp = BUILD_LWP (lwp, proc_handle.pid); ptid = thread_from_lwp (tmp, &th, &ti); if (!in_thread_list (ptid)) { attach_thread (ptid, &th, &ti, 1); } inferior_ptid = ptid; }
static ptid_t fbsd_thread_wait (struct target_ops *ops, ptid_t ptid, struct target_waitstatus *ourstatus, int options) { struct target_ops *beneath = find_target_beneath (ops); ptid_t ret; long lwp; CORE_ADDR stop_pc; td_thrhandle_t th; td_thrinfo_t ti; ret = beneath->to_wait (beneath, ptid, ourstatus, options); if (GET_PID(ret) >= 0 && ourstatus->kind == TARGET_WAITKIND_STOPPED) { lwp = get_current_lwp (GET_PID(ret)); ret = thread_from_lwp (BUILD_LWP(lwp, GET_PID(ret)), &th, &ti); if (!in_thread_list(ret)) { /* * We have to enable event reporting for initial thread * which was not mapped before. */ attach_thread(ret, &th, &ti, 1); } if (ourstatus->value.sig == TARGET_SIGNAL_TRAP) check_event(ret); /* this is a hack, if an event won't cause gdb to stop, for example, SIGALRM, gdb resumes the process immediatly without setting inferior_ptid to the new thread returned here, this is a bug because inferior_ptid may already not exist there, and passing a non-existing thread to fbsd_thread_resume causes error. However, if the exiting thread is the currently selected thread, then that is handled later in handle_inferior_event(), and we must not delete the currently selected thread. */ if (!fbsd_thread_alive (ops, inferior_ptid) && !ptid_equal(inferior_ptid, ret)) { delete_thread (inferior_ptid); inferior_ptid = ret; } } return (ret); }
ps_err_e ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); if (target_has_execution) procfs_ops.to_fetch_registers (-1); else orig_core_ops.to_fetch_registers (-1); fill_gregset ((gdb_gregset_t *) gregset, -1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prfpregset_t * fpregset) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); supply_fpregset ((gdb_fpregset_t *) fpregset); if (target_has_execution) procfs_ops.to_store_registers (-1); else orig_core_ops.to_store_registers (-1); do_cleanups (old_chain); return PS_OK; }
/* Convert LWP to user-level thread id. */ static ptid_t thread_from_lwp (ptid_t ptid, td_thrhandle_t *th, td_thrinfo_t *ti) { td_err_e err; gdb_assert (IS_LWP (ptid)); if (fbsd_thread_active) { err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), th); if (err == TD_OK) { err = td_thr_get_info_p (th, ti); if (err != TD_OK) error ("Cannot get thread info: %s", thread_db_err_str (err)); return BUILD_THREAD (ti->ti_tid, GET_PID (ptid)); } } /* the LWP is not mapped to user thread */ return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid)); }
static ptid_t fbsd_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { ptid_t ret; long lwp; CORE_ADDR stop_pc; td_thrhandle_t th; td_thrinfo_t ti; ret = child_ops.to_wait (ptid, ourstatus); if (GET_PID(ret) >= 0 && ourstatus->kind == TARGET_WAITKIND_STOPPED) { lwp = get_current_lwp (GET_PID(ret)); ret = thread_from_lwp (BUILD_LWP(lwp, GET_PID(ret)), &th, &ti); if (!in_thread_list(ret)) { /* * We have to enable event reporting for initial thread * which was not mapped before. */ attach_thread(ret, &th, &ti, 1); } if (ourstatus->value.sig == TARGET_SIGNAL_TRAP) check_event(ret); /* this is a hack, if an event won't cause gdb to stop, for example, SIGARLM, gdb resumes the process immediatly without setting inferior_ptid to the new thread returned here, this is a bug because inferior_ptid may already not exist there, and passing a none existing thread to fbsd_thread_resume causes error. */ if (!fbsd_thread_alive (inferior_ptid)) { delete_thread (inferior_ptid); inferior_ptid = ret; } } return (ret); }
ps_err_e ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid, struct ssd *pldt) { /* NOTE: only used on Solaris, therefore OK to refer to procfs.c */ extern struct ssd *procfs_find_LDT_entry (ptid_t); struct ssd *ret; /* FIXME: can't I get the process ID from the prochandle or something? */ if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0) return PS_BADLID; ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid))); if (ret) { memcpy (pldt, ret, sizeof (struct ssd)); return PS_OK; } else /* LDT not found. */ return PS_ERR; }