1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2004 David Xu <davidxu@freebsd.org> 5 * Copyright (c) 2004 Marcel Moolenaar 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #ifndef _THREAD_DB_H_ 33 #define _THREAD_DB_H_ 34 35 #include <sys/procfs.h> 36 #include <pthread.h> 37 38 typedef enum { 39 TD_ERR = -1, /* Unspecified error. */ 40 TD_OK = 0, /* No error. */ 41 TD_BADKEY, 42 TD_BADPH, 43 TD_BADSH, 44 TD_BADTA, 45 TD_BADTH, 46 TD_DBERR, 47 TD_MALLOC, 48 TD_NOAPLIC, 49 TD_NOCAPAB, 50 TD_NOEVENT, 51 TD_NOFPREGS, 52 TD_NOLIBTHREAD, 53 TD_NOLWP, 54 TD_NOMSG, 55 TD_NOSV, 56 TD_NOTHR, 57 TD_NOTSD, 58 TD_NOXREGS, 59 TD_PARTIALREG 60 } td_err_e; 61 62 struct ps_prochandle; 63 typedef struct td_thragent td_thragent_t; 64 typedef long thread_t; /* Must be an integral type. */ 65 66 typedef struct { 67 const td_thragent_t *th_ta; 68 psaddr_t th_thread; 69 thread_t th_tid; 70 } td_thrhandle_t; /* Used non-opaguely. */ 71 72 /* 73 * Events. 74 */ 75 76 typedef enum { 77 TD_EVENT_NONE = 0, 78 TD_CATCHSIG = 0x0001, 79 TD_CONCURRENCY= 0x0002, 80 TD_CREATE = 0x0004, 81 TD_DEATH = 0x0008, 82 TD_IDLE = 0x0010, 83 TD_LOCK_TRY = 0x0020, 84 TD_PREEMPT = 0x0040, 85 TD_PRI_INHERIT= 0x0080, 86 TD_READY = 0x0100, 87 TD_REAP = 0x0200, 88 TD_SLEEP = 0x0400, 89 TD_SWITCHFROM = 0x0800, 90 TD_SWITCHTO = 0x1000, 91 TD_TIMEOUT = 0x2000, 92 TD_ALL_EVENTS = ~0 93 } td_thr_events_e; 94 95 /* Compatibility with Linux. */ 96 #define td_event_e td_thr_events_e 97 98 typedef struct { 99 td_thr_events_e event; 100 psaddr_t th_p; 101 uintptr_t data; 102 } td_event_msg_t; 103 104 typedef unsigned int td_thr_events_t; 105 106 typedef enum { 107 NOTIFY_BPT, /* User inserted breakpoint. */ 108 NOTIFY_AUTOBPT, /* Automatic breakpoint. */ 109 NOTIFY_SYSCALL /* Invocation of system call. */ 110 } td_notify_e; 111 112 typedef struct { 113 td_notify_e type; 114 union { 115 psaddr_t bptaddr; 116 int syscallno; 117 } u; 118 } td_notify_t; 119 120 static __inline void 121 td_event_addset(td_thr_events_t *es, td_thr_events_e e) 122 { 123 *es |= e; 124 } 125 126 static __inline void 127 td_event_delset(td_thr_events_t *es, td_thr_events_e e) 128 { 129 *es &= ~e; 130 } 131 132 static __inline void 133 td_event_emptyset(td_thr_events_t *es) 134 { 135 *es = TD_EVENT_NONE; 136 } 137 138 static __inline void 139 td_event_fillset(td_thr_events_t *es) 140 { 141 *es = TD_ALL_EVENTS; 142 } 143 144 static __inline int 145 td_eventisempty(td_thr_events_t *es) 146 { 147 return ((*es == TD_EVENT_NONE) ? 1 : 0); 148 } 149 150 static __inline int 151 td_eventismember(td_thr_events_t *es, td_thr_events_e e) 152 { 153 return ((*es & e) ? 1 : 0); 154 } 155 156 /* 157 * Thread info. 158 */ 159 160 typedef enum { 161 TD_THR_UNKNOWN = -1, 162 TD_THR_ANY_STATE = 0, 163 TD_THR_ACTIVE, 164 TD_THR_RUN, 165 TD_THR_SLEEP, 166 TD_THR_STOPPED, 167 TD_THR_STOPPED_ASLEEP, 168 TD_THR_ZOMBIE 169 } td_thr_state_e; 170 171 typedef enum 172 { 173 TD_THR_SYSTEM = 1, 174 TD_THR_USER 175 } td_thr_type_e; 176 177 typedef pthread_key_t thread_key_t; 178 179 typedef struct { 180 const td_thragent_t *ti_ta_p; 181 thread_t ti_tid; 182 psaddr_t ti_thread; 183 td_thr_state_e ti_state; 184 td_thr_type_e ti_type; 185 td_thr_events_t ti_events; 186 int ti_pri; 187 lwpid_t ti_lid; 188 char ti_db_suspended; 189 char ti_traceme; 190 sigset_t ti_sigmask; 191 sigset_t ti_pending; 192 psaddr_t ti_tls; 193 psaddr_t ti_startfunc; 194 psaddr_t ti_stkbase; 195 size_t ti_stksize; 196 siginfo_t ti_siginfo; 197 } td_thrinfo_t; 198 199 /* 200 * Prototypes. 201 */ 202 203 typedef int td_key_iter_f(thread_key_t, void (*)(void *), void *); 204 typedef int td_thr_iter_f(const td_thrhandle_t *, void *); 205 206 /* Flags for `td_ta_thr_iter'. */ 207 #define TD_THR_ANY_USER_FLAGS 0xffffffff 208 #define TD_THR_LOWEST_PRIORITY -20 209 #define TD_SIGNO_MASK NULL 210 211 __BEGIN_DECLS 212 td_err_e td_init(void); 213 214 td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *); 215 td_err_e td_ta_delete(td_thragent_t *); 216 td_err_e td_ta_event_addr(const td_thragent_t *, td_thr_events_e, 217 td_notify_t *); 218 td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *); 219 td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *); 220 td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t, td_thrhandle_t *); 221 td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **); 222 td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *); 223 td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *, 224 td_thr_state_e, int, sigset_t *, unsigned int); 225 td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *); 226 227 td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *); 228 td_err_e td_thr_dbresume(const td_thrhandle_t *); 229 td_err_e td_thr_dbsuspend(const td_thrhandle_t *); 230 td_err_e td_thr_event_enable(const td_thrhandle_t *, int); 231 td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *); 232 td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *); 233 #ifdef __i386__ 234 td_err_e td_thr_getxmmregs(const td_thrhandle_t *, char *); 235 #endif 236 td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *); 237 td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t); 238 td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *); 239 #ifdef __i386__ 240 td_err_e td_thr_setxmmregs(const td_thrhandle_t *, const char *); 241 #endif 242 td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *); 243 td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t); 244 td_err_e td_thr_validate(const td_thrhandle_t *); 245 td_err_e td_thr_tls_get_addr(const td_thrhandle_t *, psaddr_t, size_t, 246 psaddr_t *); 247 248 /* FreeBSD specific extensions. */ 249 td_err_e td_thr_sstep(const td_thrhandle_t *, int); 250 __END_DECLS 251 252 #endif /* _THREAD_DB_H_ */ 253