1132332Smarcel/* 2132360Smarcel * Copyright (c) 2004 David Xu <davidxu@freebsd.org> 3132332Smarcel * Copyright (c) 2004 Marcel Moolenaar 4132332Smarcel * All rights reserved. 5132332Smarcel * 6132332Smarcel * Redistribution and use in source and binary forms, with or without 7132332Smarcel * modification, are permitted provided that the following conditions 8132332Smarcel * are met: 9132332Smarcel * 10132332Smarcel * 1. Redistributions of source code must retain the above copyright 11132332Smarcel * notice, this list of conditions and the following disclaimer. 12132332Smarcel * 2. Redistributions in binary form must reproduce the above copyright 13132332Smarcel * notice, this list of conditions and the following disclaimer in the 14132332Smarcel * documentation and/or other materials provided with the distribution. 15132332Smarcel * 16132332Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17132332Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18132332Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19132332Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20132332Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21132332Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22132332Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23132332Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24132332Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25132332Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26132332Smarcel * 27132332Smarcel * $FreeBSD$ 28132332Smarcel */ 29132332Smarcel 30132332Smarcel#ifndef _THREAD_DB_H_ 31132332Smarcel#define _THREAD_DB_H_ 32132332Smarcel 33132332Smarcel#include <sys/procfs.h> 34132332Smarcel#include <pthread.h> 35132332Smarcel 36132332Smarceltypedef enum { 37132332Smarcel TD_ERR = -1, /* Unspecified error. */ 38132332Smarcel TD_OK = 0, /* No error. */ 39132332Smarcel TD_BADKEY, 40132332Smarcel TD_BADPH, 41132332Smarcel TD_BADSH, 42132332Smarcel TD_BADTA, 43132332Smarcel TD_BADTH, 44132332Smarcel TD_DBERR, 45132332Smarcel TD_MALLOC, 46132332Smarcel TD_NOAPLIC, 47132332Smarcel TD_NOCAPAB, 48132332Smarcel TD_NOEVENT, 49132332Smarcel TD_NOFPREGS, 50132332Smarcel TD_NOLIBTHREAD, 51132332Smarcel TD_NOLWP, 52132332Smarcel TD_NOMSG, 53132332Smarcel TD_NOSV, 54132332Smarcel TD_NOTHR, 55132332Smarcel TD_NOTSD, 56132332Smarcel TD_NOXREGS, 57132332Smarcel TD_PARTIALREG 58132332Smarcel} td_err_e; 59132332Smarcel 60144922Sdavidxustruct ps_prochandle; 61132332Smarceltypedef struct td_thragent td_thragent_t; 62132332Smarceltypedef long thread_t; /* Must be an integral type. */ 63132332Smarcel 64132332Smarceltypedef struct { 65132332Smarcel const td_thragent_t *th_ta; 66132332Smarcel psaddr_t th_thread; 67132332Smarcel thread_t th_tid; 68132332Smarcel} td_thrhandle_t; /* Used non-opaguely. */ 69132332Smarcel 70132332Smarcel/* 71132332Smarcel * Events. 72132332Smarcel */ 73132332Smarcel 74132332Smarceltypedef enum { 75132332Smarcel TD_EVENT_NONE = 0, 76132360Smarcel TD_CATCHSIG = 0x0001, 77132360Smarcel TD_CONCURRENCY= 0x0002, 78132360Smarcel TD_CREATE = 0x0004, 79132360Smarcel TD_DEATH = 0x0008, 80132360Smarcel TD_IDLE = 0x0010, 81132360Smarcel TD_LOCK_TRY = 0x0020, 82132360Smarcel TD_PREEMPT = 0x0040, 83132360Smarcel TD_PRI_INHERIT= 0x0080, 84132360Smarcel TD_READY = 0x0100, 85132360Smarcel TD_REAP = 0x0200, 86132360Smarcel TD_SLEEP = 0x0400, 87132360Smarcel TD_SWITCHFROM = 0x0800, 88132360Smarcel TD_SWITCHTO = 0x1000, 89132360Smarcel TD_TIMEOUT = 0x2000, 90132332Smarcel TD_ALL_EVENTS = ~0 91132332Smarcel} td_thr_events_e; 92132332Smarcel 93132332Smarcel/* Compatibility with Linux. */ 94132332Smarcel#define td_event_e td_thr_events_e 95132332Smarcel 96132332Smarceltypedef struct { 97132332Smarcel td_thr_events_e event; 98183021Smarcel psaddr_t th_p; 99132332Smarcel uintptr_t data; 100132332Smarcel} td_event_msg_t; 101132332Smarcel 102132332Smarceltypedef unsigned int td_thr_events_t; 103132332Smarcel 104132360Smarceltypedef enum { 105132360Smarcel NOTIFY_BPT, /* User inserted breakpoint. */ 106132360Smarcel NOTIFY_AUTOBPT, /* Automatic breakpoint. */ 107132360Smarcel NOTIFY_SYSCALL /* Invocation of system call. */ 108132360Smarcel} td_notify_e; 109132360Smarcel 110132332Smarceltypedef struct { 111132360Smarcel td_notify_e type; 112132332Smarcel union { 113132332Smarcel psaddr_t bptaddr; 114132360Smarcel int syscallno; 115132332Smarcel } u; 116132332Smarcel} td_notify_t; 117132332Smarcel 118132332Smarcelstatic __inline void 119132332Smarceltd_event_addset(td_thr_events_t *es, td_thr_events_e e) 120132332Smarcel{ 121132332Smarcel *es |= e; 122132332Smarcel} 123132332Smarcel 124132332Smarcelstatic __inline void 125132332Smarceltd_event_delset(td_thr_events_t *es, td_thr_events_e e) 126132332Smarcel{ 127132332Smarcel *es &= ~e; 128132332Smarcel} 129132332Smarcel 130132332Smarcelstatic __inline void 131132332Smarceltd_event_emptyset(td_thr_events_t *es) 132132332Smarcel{ 133132332Smarcel *es = TD_EVENT_NONE; 134132332Smarcel} 135132332Smarcel 136132332Smarcelstatic __inline void 137132332Smarceltd_event_fillset(td_thr_events_t *es) 138132332Smarcel{ 139132332Smarcel *es = TD_ALL_EVENTS; 140132332Smarcel} 141132332Smarcel 142132332Smarcelstatic __inline int 143132332Smarceltd_eventisempty(td_thr_events_t *es) 144132332Smarcel{ 145132332Smarcel return ((*es == TD_EVENT_NONE) ? 1 : 0); 146132332Smarcel} 147132332Smarcel 148132332Smarcelstatic __inline int 149132332Smarceltd_eventismember(td_thr_events_t *es, td_thr_events_e e) 150132332Smarcel{ 151132332Smarcel return ((*es & e) ? 1 : 0); 152132332Smarcel} 153132332Smarcel 154132332Smarcel/* 155132332Smarcel * Thread info. 156132332Smarcel */ 157132332Smarcel 158132332Smarceltypedef enum { 159132332Smarcel TD_THR_UNKNOWN = -1, 160132332Smarcel TD_THR_ANY_STATE = 0, 161132332Smarcel TD_THR_ACTIVE, 162132332Smarcel TD_THR_RUN, 163132332Smarcel TD_THR_SLEEP, 164132332Smarcel TD_THR_STOPPED, 165132332Smarcel TD_THR_STOPPED_ASLEEP, 166132332Smarcel TD_THR_ZOMBIE 167132332Smarcel} td_thr_state_e; 168132332Smarcel 169132332Smarceltypedef enum 170132332Smarcel{ 171132332Smarcel TD_THR_SYSTEM = 1, 172132332Smarcel TD_THR_USER 173132332Smarcel} td_thr_type_e; 174132332Smarcel 175132360Smarceltypedef pthread_key_t thread_key_t; 176132332Smarcel 177132332Smarceltypedef struct { 178132332Smarcel const td_thragent_t *ti_ta_p; 179132332Smarcel thread_t ti_tid; 180144663Sdavidxu psaddr_t ti_thread; 181132332Smarcel td_thr_state_e ti_state; 182132332Smarcel td_thr_type_e ti_type; 183132332Smarcel td_thr_events_t ti_events; 184132332Smarcel int ti_pri; 185132332Smarcel lwpid_t ti_lid; 186132332Smarcel char ti_db_suspended; 187193826Sdes char ti_traceme; 188132332Smarcel sigset_t ti_sigmask; 189132332Smarcel sigset_t ti_pending; 190132332Smarcel psaddr_t ti_tls; 191132332Smarcel psaddr_t ti_startfunc; 192132332Smarcel psaddr_t ti_stkbase; 193132332Smarcel size_t ti_stksize; 194209689Skib siginfo_t ti_siginfo; 195132332Smarcel} td_thrinfo_t; 196132332Smarcel 197132332Smarcel/* 198132332Smarcel * Prototypes. 199132332Smarcel */ 200132332Smarcel 201132332Smarceltypedef int td_key_iter_f(thread_key_t, void (*)(void *), void *); 202132332Smarceltypedef int td_thr_iter_f(const td_thrhandle_t *, void *); 203132332Smarcel 204132332Smarcel/* Flags for `td_ta_thr_iter'. */ 205132332Smarcel#define TD_THR_ANY_USER_FLAGS 0xffffffff 206132332Smarcel#define TD_THR_LOWEST_PRIORITY -20 207132332Smarcel#define TD_SIGNO_MASK NULL 208132332Smarcel 209132332Smarcel__BEGIN_DECLS 210132332Smarceltd_err_e td_init(void); 211132332Smarcel 212132332Smarceltd_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *); 213132332Smarceltd_err_e td_ta_delete(td_thragent_t *); 214132332Smarceltd_err_e td_ta_event_addr(const td_thragent_t *, td_thr_events_e, 215132332Smarcel td_notify_t *); 216132332Smarceltd_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *); 217132332Smarceltd_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *); 218132332Smarceltd_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t, td_thrhandle_t *); 219132332Smarceltd_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **); 220132332Smarceltd_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *); 221132332Smarceltd_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *, 222132332Smarcel td_thr_state_e, int, sigset_t *, unsigned int); 223132332Smarceltd_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *); 224132332Smarcel 225132332Smarceltd_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *); 226132332Smarceltd_err_e td_thr_dbresume(const td_thrhandle_t *); 227132332Smarceltd_err_e td_thr_dbsuspend(const td_thrhandle_t *); 228132332Smarceltd_err_e td_thr_event_enable(const td_thrhandle_t *, int); 229132332Smarceltd_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *); 230132332Smarceltd_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *); 231146818Sdfr#ifdef __i386__ 232146818Sdfrtd_err_e td_thr_getxmmregs(const td_thrhandle_t *, char *); 233146818Sdfr#endif 234132332Smarceltd_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *); 235132332Smarceltd_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t); 236132332Smarceltd_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *); 237146818Sdfr#ifdef __i386__ 238146818Sdfrtd_err_e td_thr_setxmmregs(const td_thrhandle_t *, const char *); 239146818Sdfr#endif 240132332Smarceltd_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *); 241132332Smarceltd_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t); 242132332Smarceltd_err_e td_thr_validate(const td_thrhandle_t *); 243180982Smarceltd_err_e td_thr_tls_get_addr(const td_thrhandle_t *, psaddr_t, size_t, 244180982Smarcel psaddr_t *); 245132332Smarcel 246132332Smarcel/* FreeBSD specific extensions. */ 247132332Smarceltd_err_e td_thr_sstep(const td_thrhandle_t *, int); 248132332Smarcel__END_DECLS 249132332Smarcel 250132332Smarcel#endif /* _THREAD_DB_H_ */ 251