15e53a4f9SPedro F. Giffuni /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
35e53a4f9SPedro F. Giffuni *
4a7092d30SMarcel Moolenaar * Copyright (c) 2004 David Xu <davidxu@freebsd.org>
53c1e38eaSMarcel Moolenaar * Copyright (c) 2004 Marcel Moolenaar
63c1e38eaSMarcel Moolenaar * All rights reserved.
73c1e38eaSMarcel Moolenaar *
83c1e38eaSMarcel Moolenaar * Redistribution and use in source and binary forms, with or without
93c1e38eaSMarcel Moolenaar * modification, are permitted provided that the following conditions
103c1e38eaSMarcel Moolenaar * are met:
113c1e38eaSMarcel Moolenaar *
123c1e38eaSMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright
133c1e38eaSMarcel Moolenaar * notice, this list of conditions and the following disclaimer.
143c1e38eaSMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright
153c1e38eaSMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the
163c1e38eaSMarcel Moolenaar * documentation and/or other materials provided with the distribution.
173c1e38eaSMarcel Moolenaar *
183c1e38eaSMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
193c1e38eaSMarcel Moolenaar * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
203c1e38eaSMarcel Moolenaar * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
213c1e38eaSMarcel Moolenaar * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
223c1e38eaSMarcel Moolenaar * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
233c1e38eaSMarcel Moolenaar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
243c1e38eaSMarcel Moolenaar * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
253c1e38eaSMarcel Moolenaar * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
263c1e38eaSMarcel Moolenaar * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
273c1e38eaSMarcel Moolenaar * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
283c1e38eaSMarcel Moolenaar */
293c1e38eaSMarcel Moolenaar
303c1e38eaSMarcel Moolenaar #ifndef _THREAD_DB_H_
313c1e38eaSMarcel Moolenaar #define _THREAD_DB_H_
323c1e38eaSMarcel Moolenaar
333c1e38eaSMarcel Moolenaar #include <sys/procfs.h>
343c1e38eaSMarcel Moolenaar #include <pthread.h>
353c1e38eaSMarcel Moolenaar
363c1e38eaSMarcel Moolenaar typedef enum {
373c1e38eaSMarcel Moolenaar TD_ERR = -1, /* Unspecified error. */
383c1e38eaSMarcel Moolenaar TD_OK = 0, /* No error. */
393c1e38eaSMarcel Moolenaar TD_BADKEY,
403c1e38eaSMarcel Moolenaar TD_BADPH,
413c1e38eaSMarcel Moolenaar TD_BADSH,
423c1e38eaSMarcel Moolenaar TD_BADTA,
433c1e38eaSMarcel Moolenaar TD_BADTH,
443c1e38eaSMarcel Moolenaar TD_DBERR,
453c1e38eaSMarcel Moolenaar TD_MALLOC,
463c1e38eaSMarcel Moolenaar TD_NOAPLIC,
473c1e38eaSMarcel Moolenaar TD_NOCAPAB,
483c1e38eaSMarcel Moolenaar TD_NOEVENT,
493c1e38eaSMarcel Moolenaar TD_NOFPREGS,
503c1e38eaSMarcel Moolenaar TD_NOLIBTHREAD,
513c1e38eaSMarcel Moolenaar TD_NOLWP,
523c1e38eaSMarcel Moolenaar TD_NOMSG,
533c1e38eaSMarcel Moolenaar TD_NOSV,
543c1e38eaSMarcel Moolenaar TD_NOTHR,
553c1e38eaSMarcel Moolenaar TD_NOTSD,
563c1e38eaSMarcel Moolenaar TD_NOXREGS,
573c1e38eaSMarcel Moolenaar TD_PARTIALREG
583c1e38eaSMarcel Moolenaar } td_err_e;
593c1e38eaSMarcel Moolenaar
60a80845eaSDavid Xu struct ps_prochandle;
613c1e38eaSMarcel Moolenaar typedef struct td_thragent td_thragent_t;
623c1e38eaSMarcel Moolenaar typedef long thread_t; /* Must be an integral type. */
633c1e38eaSMarcel Moolenaar
643c1e38eaSMarcel Moolenaar typedef struct {
653c1e38eaSMarcel Moolenaar const td_thragent_t *th_ta;
663c1e38eaSMarcel Moolenaar psaddr_t th_thread;
673c1e38eaSMarcel Moolenaar thread_t th_tid;
683c1e38eaSMarcel Moolenaar } td_thrhandle_t; /* Used non-opaguely. */
693c1e38eaSMarcel Moolenaar
703c1e38eaSMarcel Moolenaar /*
713c1e38eaSMarcel Moolenaar * Events.
723c1e38eaSMarcel Moolenaar */
733c1e38eaSMarcel Moolenaar
743c1e38eaSMarcel Moolenaar typedef enum {
753c1e38eaSMarcel Moolenaar TD_EVENT_NONE = 0,
76a7092d30SMarcel Moolenaar TD_CATCHSIG = 0x0001,
77a7092d30SMarcel Moolenaar TD_CONCURRENCY= 0x0002,
78a7092d30SMarcel Moolenaar TD_CREATE = 0x0004,
79a7092d30SMarcel Moolenaar TD_DEATH = 0x0008,
80a7092d30SMarcel Moolenaar TD_IDLE = 0x0010,
81a7092d30SMarcel Moolenaar TD_LOCK_TRY = 0x0020,
82a7092d30SMarcel Moolenaar TD_PREEMPT = 0x0040,
83a7092d30SMarcel Moolenaar TD_PRI_INHERIT= 0x0080,
84a7092d30SMarcel Moolenaar TD_READY = 0x0100,
85a7092d30SMarcel Moolenaar TD_REAP = 0x0200,
86a7092d30SMarcel Moolenaar TD_SLEEP = 0x0400,
87a7092d30SMarcel Moolenaar TD_SWITCHFROM = 0x0800,
88a7092d30SMarcel Moolenaar TD_SWITCHTO = 0x1000,
89a7092d30SMarcel Moolenaar TD_TIMEOUT = 0x2000,
903c1e38eaSMarcel Moolenaar TD_ALL_EVENTS = ~0
913c1e38eaSMarcel Moolenaar } td_thr_events_e;
923c1e38eaSMarcel Moolenaar
933c1e38eaSMarcel Moolenaar /* Compatibility with Linux. */
943c1e38eaSMarcel Moolenaar #define td_event_e td_thr_events_e
953c1e38eaSMarcel Moolenaar
963c1e38eaSMarcel Moolenaar typedef struct {
973c1e38eaSMarcel Moolenaar td_thr_events_e event;
9803fad2adSMarcel Moolenaar psaddr_t th_p;
993c1e38eaSMarcel Moolenaar uintptr_t data;
1003c1e38eaSMarcel Moolenaar } td_event_msg_t;
1013c1e38eaSMarcel Moolenaar
1023c1e38eaSMarcel Moolenaar typedef unsigned int td_thr_events_t;
1033c1e38eaSMarcel Moolenaar
104a7092d30SMarcel Moolenaar typedef enum {
105a7092d30SMarcel Moolenaar NOTIFY_BPT, /* User inserted breakpoint. */
106a7092d30SMarcel Moolenaar NOTIFY_AUTOBPT, /* Automatic breakpoint. */
107a7092d30SMarcel Moolenaar NOTIFY_SYSCALL /* Invocation of system call. */
108a7092d30SMarcel Moolenaar } td_notify_e;
109a7092d30SMarcel Moolenaar
1103c1e38eaSMarcel Moolenaar typedef struct {
111a7092d30SMarcel Moolenaar td_notify_e type;
1123c1e38eaSMarcel Moolenaar union {
1133c1e38eaSMarcel Moolenaar psaddr_t bptaddr;
114a7092d30SMarcel Moolenaar int syscallno;
1153c1e38eaSMarcel Moolenaar } u;
1163c1e38eaSMarcel Moolenaar } td_notify_t;
1173c1e38eaSMarcel Moolenaar
1183c1e38eaSMarcel Moolenaar static __inline void
td_event_addset(td_thr_events_t * es,td_thr_events_e e)1193c1e38eaSMarcel Moolenaar td_event_addset(td_thr_events_t *es, td_thr_events_e e)
1203c1e38eaSMarcel Moolenaar {
1213c1e38eaSMarcel Moolenaar *es |= e;
1223c1e38eaSMarcel Moolenaar }
1233c1e38eaSMarcel Moolenaar
1243c1e38eaSMarcel Moolenaar static __inline void
td_event_delset(td_thr_events_t * es,td_thr_events_e e)1253c1e38eaSMarcel Moolenaar td_event_delset(td_thr_events_t *es, td_thr_events_e e)
1263c1e38eaSMarcel Moolenaar {
1273c1e38eaSMarcel Moolenaar *es &= ~e;
1283c1e38eaSMarcel Moolenaar }
1293c1e38eaSMarcel Moolenaar
1303c1e38eaSMarcel Moolenaar static __inline void
td_event_emptyset(td_thr_events_t * es)1313c1e38eaSMarcel Moolenaar td_event_emptyset(td_thr_events_t *es)
1323c1e38eaSMarcel Moolenaar {
1333c1e38eaSMarcel Moolenaar *es = TD_EVENT_NONE;
1343c1e38eaSMarcel Moolenaar }
1353c1e38eaSMarcel Moolenaar
1363c1e38eaSMarcel Moolenaar static __inline void
td_event_fillset(td_thr_events_t * es)1373c1e38eaSMarcel Moolenaar td_event_fillset(td_thr_events_t *es)
1383c1e38eaSMarcel Moolenaar {
1393c1e38eaSMarcel Moolenaar *es = TD_ALL_EVENTS;
1403c1e38eaSMarcel Moolenaar }
1413c1e38eaSMarcel Moolenaar
1423c1e38eaSMarcel Moolenaar static __inline int
td_eventisempty(td_thr_events_t * es)1433c1e38eaSMarcel Moolenaar td_eventisempty(td_thr_events_t *es)
1443c1e38eaSMarcel Moolenaar {
1453c1e38eaSMarcel Moolenaar return ((*es == TD_EVENT_NONE) ? 1 : 0);
1463c1e38eaSMarcel Moolenaar }
1473c1e38eaSMarcel Moolenaar
1483c1e38eaSMarcel Moolenaar static __inline int
td_eventismember(td_thr_events_t * es,td_thr_events_e e)1493c1e38eaSMarcel Moolenaar td_eventismember(td_thr_events_t *es, td_thr_events_e e)
1503c1e38eaSMarcel Moolenaar {
1513c1e38eaSMarcel Moolenaar return ((*es & e) ? 1 : 0);
1523c1e38eaSMarcel Moolenaar }
1533c1e38eaSMarcel Moolenaar
1543c1e38eaSMarcel Moolenaar /*
1553c1e38eaSMarcel Moolenaar * Thread info.
1563c1e38eaSMarcel Moolenaar */
1573c1e38eaSMarcel Moolenaar
1583c1e38eaSMarcel Moolenaar typedef enum {
1593c1e38eaSMarcel Moolenaar TD_THR_UNKNOWN = -1,
1603c1e38eaSMarcel Moolenaar TD_THR_ANY_STATE = 0,
1613c1e38eaSMarcel Moolenaar TD_THR_ACTIVE,
1623c1e38eaSMarcel Moolenaar TD_THR_RUN,
1633c1e38eaSMarcel Moolenaar TD_THR_SLEEP,
1643c1e38eaSMarcel Moolenaar TD_THR_STOPPED,
1653c1e38eaSMarcel Moolenaar TD_THR_STOPPED_ASLEEP,
1663c1e38eaSMarcel Moolenaar TD_THR_ZOMBIE
1673c1e38eaSMarcel Moolenaar } td_thr_state_e;
1683c1e38eaSMarcel Moolenaar
1693c1e38eaSMarcel Moolenaar typedef enum
1703c1e38eaSMarcel Moolenaar {
1713c1e38eaSMarcel Moolenaar TD_THR_SYSTEM = 1,
1723c1e38eaSMarcel Moolenaar TD_THR_USER
1733c1e38eaSMarcel Moolenaar } td_thr_type_e;
1743c1e38eaSMarcel Moolenaar
175a7092d30SMarcel Moolenaar typedef pthread_key_t thread_key_t;
1763c1e38eaSMarcel Moolenaar
1773c1e38eaSMarcel Moolenaar typedef struct {
1783c1e38eaSMarcel Moolenaar const td_thragent_t *ti_ta_p;
1793c1e38eaSMarcel Moolenaar thread_t ti_tid;
1802ec2da86SDavid Xu psaddr_t ti_thread;
1813c1e38eaSMarcel Moolenaar td_thr_state_e ti_state;
1823c1e38eaSMarcel Moolenaar td_thr_type_e ti_type;
1833c1e38eaSMarcel Moolenaar td_thr_events_t ti_events;
1843c1e38eaSMarcel Moolenaar int ti_pri;
1853c1e38eaSMarcel Moolenaar lwpid_t ti_lid;
1863c1e38eaSMarcel Moolenaar char ti_db_suspended;
18718860a1cSDag-Erling Smørgrav char ti_traceme;
1883c1e38eaSMarcel Moolenaar sigset_t ti_sigmask;
1893c1e38eaSMarcel Moolenaar sigset_t ti_pending;
1903c1e38eaSMarcel Moolenaar psaddr_t ti_tls;
1913c1e38eaSMarcel Moolenaar psaddr_t ti_startfunc;
1923c1e38eaSMarcel Moolenaar psaddr_t ti_stkbase;
1933c1e38eaSMarcel Moolenaar size_t ti_stksize;
194098d0537SKonstantin Belousov siginfo_t ti_siginfo;
1953c1e38eaSMarcel Moolenaar } td_thrinfo_t;
1963c1e38eaSMarcel Moolenaar
1973c1e38eaSMarcel Moolenaar /*
1983c1e38eaSMarcel Moolenaar * Prototypes.
1993c1e38eaSMarcel Moolenaar */
2003c1e38eaSMarcel Moolenaar
2013c1e38eaSMarcel Moolenaar typedef int td_key_iter_f(thread_key_t, void (*)(void *), void *);
2023c1e38eaSMarcel Moolenaar typedef int td_thr_iter_f(const td_thrhandle_t *, void *);
2033c1e38eaSMarcel Moolenaar
2043c1e38eaSMarcel Moolenaar /* Flags for `td_ta_thr_iter'. */
2053c1e38eaSMarcel Moolenaar #define TD_THR_ANY_USER_FLAGS 0xffffffff
2063c1e38eaSMarcel Moolenaar #define TD_THR_LOWEST_PRIORITY -20
2073c1e38eaSMarcel Moolenaar #define TD_SIGNO_MASK NULL
2083c1e38eaSMarcel Moolenaar
2093c1e38eaSMarcel Moolenaar __BEGIN_DECLS
2103c1e38eaSMarcel Moolenaar td_err_e td_init(void);
2113c1e38eaSMarcel Moolenaar
2123c1e38eaSMarcel Moolenaar td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *);
2133c1e38eaSMarcel Moolenaar td_err_e td_ta_delete(td_thragent_t *);
2143c1e38eaSMarcel Moolenaar td_err_e td_ta_event_addr(const td_thragent_t *, td_thr_events_e,
2153c1e38eaSMarcel Moolenaar td_notify_t *);
2163c1e38eaSMarcel Moolenaar td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *);
2173c1e38eaSMarcel Moolenaar td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *);
2183c1e38eaSMarcel Moolenaar td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t, td_thrhandle_t *);
2193c1e38eaSMarcel Moolenaar td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **);
2203c1e38eaSMarcel Moolenaar td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *);
2213c1e38eaSMarcel Moolenaar td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *,
2223c1e38eaSMarcel Moolenaar td_thr_state_e, int, sigset_t *, unsigned int);
2233c1e38eaSMarcel Moolenaar td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *);
2243c1e38eaSMarcel Moolenaar
2253c1e38eaSMarcel Moolenaar td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *);
2263c1e38eaSMarcel Moolenaar td_err_e td_thr_dbresume(const td_thrhandle_t *);
2273c1e38eaSMarcel Moolenaar td_err_e td_thr_dbsuspend(const td_thrhandle_t *);
2283c1e38eaSMarcel Moolenaar td_err_e td_thr_event_enable(const td_thrhandle_t *, int);
2293c1e38eaSMarcel Moolenaar td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *);
2303c1e38eaSMarcel Moolenaar td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *);
2318d7681bbSDoug Rabson #ifdef __i386__
2328d7681bbSDoug Rabson td_err_e td_thr_getxmmregs(const td_thrhandle_t *, char *);
2338d7681bbSDoug Rabson #endif
2343c1e38eaSMarcel Moolenaar td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *);
2353c1e38eaSMarcel Moolenaar td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t);
2363c1e38eaSMarcel Moolenaar td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *);
2378d7681bbSDoug Rabson #ifdef __i386__
2388d7681bbSDoug Rabson td_err_e td_thr_setxmmregs(const td_thrhandle_t *, const char *);
2398d7681bbSDoug Rabson #endif
2403c1e38eaSMarcel Moolenaar td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *);
2413c1e38eaSMarcel Moolenaar td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t);
2423c1e38eaSMarcel Moolenaar td_err_e td_thr_validate(const td_thrhandle_t *);
24316b0c20cSMarcel Moolenaar td_err_e td_thr_tls_get_addr(const td_thrhandle_t *, psaddr_t, size_t,
24416b0c20cSMarcel Moolenaar psaddr_t *);
2453c1e38eaSMarcel Moolenaar
2463c1e38eaSMarcel Moolenaar /* FreeBSD specific extensions. */
2473c1e38eaSMarcel Moolenaar td_err_e td_thr_sstep(const td_thrhandle_t *, int);
2483c1e38eaSMarcel Moolenaar __END_DECLS
2493c1e38eaSMarcel Moolenaar
2503c1e38eaSMarcel Moolenaar #endif /* _THREAD_DB_H_ */
251