CORE_ADDR fbsd_thread_get_local_address(struct target_ops *ops, ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset) { td_thrhandle_t th; void *address; int ret; if (IS_THREAD (ptid)) { if (!td_thr_tls_get_addr_p) error ("Cannot find thread-local interface in thread_db library."); ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(ptid), &th); /* get the address of the variable. */ ret = td_thr_tls_get_addr_p (&th, (void *)lm, offset, &address); if (ret != TD_OK) { error ("Cannot find thread-local storage for thread %ld\n%s", (long) GET_THREAD (ptid), thread_db_err_str (ret)); } /* Cast assuming host == target. */ return extract_data_ptr (&address); } return (0); }
static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, const td_thrinfo_t *ti_p, int verbose) { td_err_e err; /* Add the thread to GDB's thread list. */ if (!in_thread_list (ptid)) { add_thread (ptid); if (verbose) printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid)); } if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE) return; /* A zombie thread -- do not attach. */ if (! IS_THREAD(ptid)) return; if (fbsd_thread_core != 0) return; /* Enable thread event reporting for this thread. */ err = td_thr_event_enable_p (th_p, 1); if (err != TD_OK) error ("Cannot enable thread event reporting for %s: %s", target_pid_to_str (ptid), thread_db_err_str (err)); }
CORE_ADDR fbsd_thread_get_local_address(ptid_t ptid, struct objfile *objfile, CORE_ADDR offset) { td_thrhandle_t th; void *address; CORE_ADDR lm; void *lm2; int ret, is_library = (objfile->flags & OBJF_SHARED); if (IS_THREAD (ptid)) { if (!td_thr_tls_get_addr_p) error ("Cannot find thread-local interface in thread_db library."); /* Get the address of the link map for this objfile. */ lm = svr4_fetch_objfile_link_map (objfile); /* Couldn't find link map. Bail out. */ if (!lm) { if (is_library) error ("Cannot find shared library `%s' link_map in dynamic" " linker's module list", objfile->name); else error ("Cannot find executable file `%s' link_map in dynamic" " linker's module list", objfile->name); } ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(ptid), &th); /* get the address of the variable. */ store_typed_address(&lm2, builtin_type_void_data_ptr, lm); ret = td_thr_tls_get_addr_p (&th, lm2, offset, &address); if (ret != TD_OK) { if (is_library) error ("Cannot find thread-local storage for thread %ld, " "shared library %s:\n%s", (long) GET_THREAD (ptid), objfile->name, thread_db_err_str (ret)); else error ("Cannot find thread-local storage for thread %ld, " "executable file %s:\n%s", (long) GET_THREAD (ptid), objfile->name, thread_db_err_str (ret)); } /* Cast assuming host == target. */ return extract_typed_address(&address, builtin_type_void_data_ptr); } return (0); }
static int fbsd_thread_alive (ptid_t ptid) { td_thrhandle_t th; td_thrinfo_t ti; td_err_e err; gregset_t gregs; lwpid_t lwp; if (IS_THREAD (ptid)) { err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th); if (err != TD_OK) return 0; err = td_thr_get_info_p (&th, &ti); if (err != TD_OK) return 0; /* A zombie thread. */ if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) return 0; return 1; } else if (GET_LWP (ptid) == 0) { /* we sometimes are called with lwp == 0 */ return 1; } if (fbsd_thread_active) { err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th); /* * if the lwp was already mapped to user thread, don't use it * directly, please use user thread id instead. */ if (err == TD_OK) return 0; } if (!target_has_execution) { lwp = GET_LWP (ptid); bfd_map_over_sections (core_bfd, fbsd_core_check_lwp, &lwp); return (lwp == 0); } /* check lwp in kernel */ return ptrace (PT_GETREGS, GET_LWP (ptid), (caddr_t)&gregs, 0) == 0; }
static void fbsd_thread_fetch_registers (struct target_ops *ops, struct regcache *regcache, int regnum) { prgregset_t gregset; prfpregset_t fpregset; td_thrhandle_t th; td_err_e err; #ifdef PT_GETXMMREGS char xmmregs[512]; #endif if (!IS_THREAD (inferior_ptid)) { fbsd_lwp_fetch_registers (ops, regcache, regnum); return; } err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th); if (err != TD_OK) error ("Cannot find thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); err = td_thr_getgregs_p (&th, gregset); if (err != TD_OK) error ("Cannot fetch general-purpose registers for thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); #ifdef PT_GETXMMREGS err = td_thr_getxmmregs_p (&th, xmmregs); if (err == TD_OK) { i387_supply_fxsave (regcache, -1, xmmregs); } else { #endif err = td_thr_getfpregs_p (&th, &fpregset); if (err != TD_OK) error ("Cannot get floating-point registers for thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); supply_fpregset (regcache, &fpregset); #ifdef PT_GETXMMREGS } #endif supply_gregset (regcache, gregset); }
static char * fbsd_thread_pid_to_str (ptid_t ptid) { static char buf[64 + MAXCOMLEN]; if (IS_THREAD (ptid)) { td_thrhandle_t th; td_thrinfo_t ti; td_err_e err; err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th); if (err != TD_OK) error ("Cannot find thread, Thread ID=%ld, %s", GET_THREAD (ptid), thread_db_err_str (err)); err = td_thr_get_info_p (&th, &ti); if (err != TD_OK) error ("Cannot get thread info, Thread ID=%ld, %s", GET_THREAD (ptid), thread_db_err_str (err)); if (ti.ti_lid != 0) { snprintf (buf, sizeof (buf), "Thread %llx (LWP %d/%s)", (unsigned long long)th.th_thread, ti.ti_lid, fbsd_thread_get_name (ti.ti_lid)); } else { snprintf (buf, sizeof (buf), "Thread %llx (%s)", (unsigned long long)th.th_thread, thread_db_state_str (ti.ti_state)); } return buf; } else if (IS_LWP (ptid)) { snprintf (buf, sizeof (buf), "LWP %d", (int) GET_LWP (ptid)); return buf; } return normal_pid_to_str (ptid); }
static void fbsd_thread_store_registers (int regno) { prgregset_t gregset; prfpregset_t fpregset; td_thrhandle_t th; td_err_e err; #ifdef PT_GETXMMREGS char xmmregs[512]; #endif if (!IS_THREAD (inferior_ptid)) { fbsd_lwp_store_registers (regno); return; } err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th); if (err != TD_OK) error ("Cannot find thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); if (regno != -1) { char old_value[MAX_REGISTER_SIZE]; regcache_collect (regno, old_value); err = td_thr_getgregs_p (&th, gregset); if (err != TD_OK) error ("%s: td_thr_getgregs %s", __func__, thread_db_err_str (err)); #ifdef PT_GETXMMREGS err = td_thr_getxmmregs_p (&th, xmmregs); if (err != TD_OK) { #endif err = td_thr_getfpregs_p (&th, &fpregset); if (err != TD_OK) error ("%s: td_thr_getfpgregs %s", __func__, thread_db_err_str (err)); #ifdef PT_GETXMMREGS } #endif supply_register (regno, old_value); } fill_gregset (gregset, regno); err = td_thr_setgregs_p (&th, gregset); if (err != TD_OK) error ("Cannot store general-purpose registers for thread %d: Thread ID=%d, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); #ifdef PT_GETXMMREGS i387_fill_fxsave (xmmregs, regno); err = td_thr_setxmmregs_p (&th, xmmregs); if (err == TD_OK) return; #endif fill_fpregset (&fpregset, regno); err = td_thr_setfpregs_p (&th, &fpregset); if (err != TD_OK) error ("Cannot store floating-point registers for thread %d: Thread ID=%d, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); }
static void fbsd_thread_signal_cmd (char *exp, int from_tty) { td_thrhandle_t th; td_thrinfo_t ti; td_err_e err; const char *code; if (!fbsd_thread_active || !IS_THREAD(inferior_ptid)) return; err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th); if (err != TD_OK) return; err = td_thr_get_info_p (&th, &ti); if (err != TD_OK) return; printf_filtered("signal mask:\n"); fbsd_print_sigset(&ti.ti_sigmask); printf_filtered("signal pending:\n"); fbsd_print_sigset(&ti.ti_pending); if (ti.ti_siginfo.si_signo != 0) { printf_filtered("si_signo %d si_errno %d", ti.ti_siginfo.si_signo, ti.ti_siginfo.si_errno); if (ti.ti_siginfo.si_errno != 0) printf_filtered(" (%s)", strerror(ti.ti_siginfo.si_errno)); printf_filtered("\n"); switch (ti.ti_siginfo.si_code) { case SI_NOINFO: code = "NOINFO"; break; case SI_USER: code = "USER"; break; case SI_QUEUE: code = "QUEUE"; break; case SI_TIMER: code = "TIMER"; break; case SI_ASYNCIO: code = "ASYNCIO"; break; case SI_MESGQ: code = "MESGQ"; break; case SI_KERNEL: code = "KERNEL"; break; default: code = "UNKNOWN"; break; } printf_filtered("si_code %s (%d) si_pid %d si_uid %d si_status %x " "si_addr %p\n", code, ti.ti_siginfo.si_code, ti.ti_siginfo.si_pid, ti.ti_siginfo.si_uid, ti.ti_siginfo.si_status, ti.ti_siginfo.si_addr); } }