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 30 #ifndef _THREAD_DB_H_ 31 #define _THREAD_DB_H_ 32 33 #include <sys/procfs.h> 34 #include <pthread.h> 35 36 typedef enum { 37 TD_ERR = -1, /* Unspecified error. */ 38 TD_OK = 0, /* No error. */ 39 TD_BADKEY, 40 TD_BADPH, 41 TD_BADSH, 42 TD_BADTA, 43 TD_BADTH, 44 TD_DBERR, 45 TD_MALLOC, 46 TD_NOAPLIC, 47 TD_NOCAPAB, 48 TD_NOEVENT, 49 TD_NOFPREGS, 50 TD_NOLIBTHREAD, 51 TD_NOLWP, 52 TD_NOMSG, 53 TD_NOSV, 54 TD_NOTHR, 55 TD_NOTSD, 56 TD_NOXREGS, 57 TD_PARTIALREG 58 } td_err_e; 59 60 struct ps_prochandle; 61 typedef struct td_thragent td_thragent_t; 62 typedef long thread_t; /* Must be an integral type. */ 63 64 typedef struct { 65 const td_thragent_t *th_ta; 66 psaddr_t th_thread; 67 thread_t th_tid; 68 } td_thrhandle_t; /* Used non-opaguely. */ 69 70 /* 71 * Events. 72 */ 73 74 typedef enum { 75 TD_EVENT_NONE = 0, 76 TD_CATCHSIG = 0x0001, 77 TD_CONCURRENCY= 0x0002, 78 TD_CREATE = 0x0004, 79 TD_DEATH = 0x0008, 80 TD_IDLE = 0x0010, 81 TD_LOCK_TRY = 0x0020, 82 TD_PREEMPT = 0x0040, 83 TD_PRI_INHERIT= 0x0080, 84 TD_READY = 0x0100, 85 TD_REAP = 0x0200, 86 TD_SLEEP = 0x0400, 87 TD_SWITCHFROM = 0x0800, 88 TD_SWITCHTO = 0x1000, 89 TD_TIMEOUT = 0x2000, 90 TD_ALL_EVENTS = ~0 91 } td_thr_events_e; 92 93 /* Compatibility with Linux. */ 94 #define td_event_e td_thr_events_e 95 96 typedef struct { 97 td_thr_events_e event; 98 psaddr_t th_p; 99 uintptr_t data; 100 } td_event_msg_t; 101 102 typedef unsigned int td_thr_events_t; 103 104 typedef enum { 105 NOTIFY_BPT, /* User inserted breakpoint. */ 106 NOTIFY_AUTOBPT, /* Automatic breakpoint. */ 107 NOTIFY_SYSCALL /* Invocation of system call. */ 108 } td_notify_e; 109 110 typedef struct { 111 td_notify_e type; 112 union { 113 psaddr_t bptaddr; 114 int syscallno; 115 } u; 116 } td_notify_t; 117 118 static __inline void 119 td_event_addset(td_thr_events_t *es, td_thr_events_e e) 120 { 121 *es |= e; 122 } 123 124 static __inline void 125 td_event_delset(td_thr_events_t *es, td_thr_events_e e) 126 { 127 *es &= ~e; 128 } 129 130 static __inline void 131 td_event_emptyset(td_thr_events_t *es) 132 { 133 *es = TD_EVENT_NONE; 134 } 135 136 static __inline void 137 td_event_fillset(td_thr_events_t *es) 138 { 139 *es = TD_ALL_EVENTS; 140 } 141 142 static __inline int 143 td_eventisempty(td_thr_events_t *es) 144 { 145 return ((*es == TD_EVENT_NONE) ? 1 : 0); 146 } 147 148 static __inline int 149 td_eventismember(td_thr_events_t *es, td_thr_events_e e) 150 { 151 return ((*es & e) ? 1 : 0); 152 } 153 154 /* 155 * Thread info. 156 */ 157 158 typedef enum { 159 TD_THR_UNKNOWN = -1, 160 TD_THR_ANY_STATE = 0, 161 TD_THR_ACTIVE, 162 TD_THR_RUN, 163 TD_THR_SLEEP, 164 TD_THR_STOPPED, 165 TD_THR_STOPPED_ASLEEP, 166 TD_THR_ZOMBIE 167 } td_thr_state_e; 168 169 typedef enum 170 { 171 TD_THR_SYSTEM = 1, 172 TD_THR_USER 173 } td_thr_type_e; 174 175 typedef pthread_key_t thread_key_t; 176 177 typedef struct { 178 const td_thragent_t *ti_ta_p; 179 thread_t ti_tid; 180 psaddr_t ti_thread; 181 td_thr_state_e ti_state; 182 td_thr_type_e ti_type; 183 td_thr_events_t ti_events; 184 int ti_pri; 185 lwpid_t ti_lid; 186 char ti_db_suspended; 187 char ti_traceme; 188 sigset_t ti_sigmask; 189 sigset_t ti_pending; 190 psaddr_t ti_tls; 191 psaddr_t ti_startfunc; 192 psaddr_t ti_stkbase; 193 size_t ti_stksize; 194 siginfo_t ti_siginfo; 195 } td_thrinfo_t; 196 197 /* 198 * Prototypes. 199 */ 200 201 typedef int td_key_iter_f(thread_key_t, void (*)(void *), void *); 202 typedef int td_thr_iter_f(const td_thrhandle_t *, void *); 203 204 /* Flags for `td_ta_thr_iter'. */ 205 #define TD_THR_ANY_USER_FLAGS 0xffffffff 206 #define TD_THR_LOWEST_PRIORITY -20 207 #define TD_SIGNO_MASK NULL 208 209 __BEGIN_DECLS 210 td_err_e td_init(void); 211 212 td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *); 213 td_err_e td_ta_delete(td_thragent_t *); 214 td_err_e td_ta_event_addr(const td_thragent_t *, td_thr_events_e, 215 td_notify_t *); 216 td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *); 217 td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *); 218 td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t, td_thrhandle_t *); 219 td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **); 220 td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *); 221 td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *, 222 td_thr_state_e, int, sigset_t *, unsigned int); 223 td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *); 224 225 td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *); 226 td_err_e td_thr_dbresume(const td_thrhandle_t *); 227 td_err_e td_thr_dbsuspend(const td_thrhandle_t *); 228 td_err_e td_thr_event_enable(const td_thrhandle_t *, int); 229 td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *); 230 td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *); 231 #ifdef __i386__ 232 td_err_e td_thr_getxmmregs(const td_thrhandle_t *, char *); 233 #endif 234 td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *); 235 td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t); 236 td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *); 237 #ifdef __i386__ 238 td_err_e td_thr_setxmmregs(const td_thrhandle_t *, const char *); 239 #endif 240 td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *); 241 td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t); 242 td_err_e td_thr_validate(const td_thrhandle_t *); 243 td_err_e td_thr_tls_get_addr(const td_thrhandle_t *, psaddr_t, size_t, 244 psaddr_t *); 245 246 /* FreeBSD specific extensions. */ 247 td_err_e td_thr_sstep(const td_thrhandle_t *, int); 248 __END_DECLS 249 250 #endif /* _THREAD_DB_H_ */ 251