9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <stddef.h>
34 #include <unistd.h>
35 #include <thr_uberdata.h>
36 #include <thread_db.h>
37 #include <libc_int.h>
38
39 /*
40 * Private structures.
41 */
42
43 typedef union {
44 mutex_t lock;
45 rwlock_t rwlock;
46 sema_t semaphore;
47 cond_t condition;
48 } td_so_un_t;
1972 return (TD_DBERR);
1973 }
1974
1975 if (ps_lsetfpregs(ph_p, thr_to_lwpid(th_p), fpregset) != PS_OK)
1976 return_val = TD_DBERR;
1977
1978 (void) ps_pcontinue(ph_p);
1979 ph_unlock(th_p->th_ta_p);
1980 return (return_val);
1981 }
1982
1983 /*
1984 * Get the size of the extra state register set for this architecture.
1985 * Currently unused by dbx.
1986 */
1987 #pragma weak td_thr_getxregsize = __td_thr_getxregsize
1988 /* ARGSUSED */
1989 td_err_e
1990 __td_thr_getxregsize(td_thrhandle_t *th_p, int *xregsize)
1991 {
1992 #if defined(__sparc)
1993 struct ps_prochandle *ph_p;
1994 td_err_e return_val;
1995
1996 if ((ph_p = ph_lock_th(th_p, &return_val)) == NULL)
1997 return (return_val);
1998 if (ps_pstop(ph_p) != PS_OK) {
1999 ph_unlock(th_p->th_ta_p);
2000 return (TD_DBERR);
2001 }
2002
2003 if (ps_lgetxregsize(ph_p, thr_to_lwpid(th_p), xregsize) != PS_OK)
2004 return_val = TD_DBERR;
2005
2006 (void) ps_pcontinue(ph_p);
2007 ph_unlock(th_p->th_ta_p);
2008 return (return_val);
2009 #else /* __sparc */
2010 return (TD_NOXREGS);
2011 #endif /* __sparc */
2012 }
2013
2014 /*
2015 * Get a thread's extra state register set.
2016 */
2017 #pragma weak td_thr_getxregs = __td_thr_getxregs
2018 /* ARGSUSED */
2019 td_err_e
2020 __td_thr_getxregs(td_thrhandle_t *th_p, void *xregset)
2021 {
2022 #if defined(__sparc)
2023 struct ps_prochandle *ph_p;
2024 td_err_e return_val;
2025
2026 if ((ph_p = ph_lock_th(th_p, &return_val)) == NULL)
2027 return (return_val);
2028 if (ps_pstop(ph_p) != PS_OK) {
2029 ph_unlock(th_p->th_ta_p);
2030 return (TD_DBERR);
2031 }
2032
2033 if (ps_lgetxregs(ph_p, thr_to_lwpid(th_p), (caddr_t)xregset) != PS_OK)
2034 return_val = TD_DBERR;
2035
2036 (void) ps_pcontinue(ph_p);
2037 ph_unlock(th_p->th_ta_p);
2038 return (return_val);
2039 #else /* __sparc */
2040 return (TD_NOXREGS);
2041 #endif /* __sparc */
2042 }
2043
2044 /*
2045 * Set a thread's extra state register set.
2046 */
2047 #pragma weak td_thr_setxregs = __td_thr_setxregs
2048 /* ARGSUSED */
2049 td_err_e
2050 __td_thr_setxregs(td_thrhandle_t *th_p, const void *xregset)
2051 {
2052 #if defined(__sparc)
2053 struct ps_prochandle *ph_p;
2054 td_err_e return_val;
2055
2056 if ((ph_p = ph_lock_th(th_p, &return_val)) == NULL)
2057 return (return_val);
2058 if (ps_pstop(ph_p) != PS_OK) {
2059 ph_unlock(th_p->th_ta_p);
2060 return (TD_DBERR);
2061 }
2062
2063 if (ps_lsetxregs(ph_p, thr_to_lwpid(th_p), (caddr_t)xregset) != PS_OK)
2064 return_val = TD_DBERR;
2065
2066 (void) ps_pcontinue(ph_p);
2067 ph_unlock(th_p->th_ta_p);
2068 return (return_val);
2069 #else /* __sparc */
2070 return (TD_NOXREGS);
2071 #endif /* __sparc */
2072 }
2073
2074 struct searcher {
2075 psaddr_t addr;
2076 int status;
2077 };
2078
2079 /*
2080 * Check the struct thread address in *th_p again first
2081 * value in "data". If value in data is found, set second value
2082 * in "data" to 1 and return 1 to terminate iterations.
2083 * This function is used by td_thr_validate() to verify that
2084 * a thread handle is valid.
2085 */
2086 static int
2087 td_searcher(const td_thrhandle_t *th_p, void *data)
2088 {
2089 struct searcher *searcher_data = (struct searcher *)data;
2090
2091 if (searcher_data->addr == th_p->th_unique) {
|
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
29 * Copyright 2023 Oxide Computer Company
30 */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stddef.h>
35 #include <unistd.h>
36 #include <thr_uberdata.h>
37 #include <thread_db.h>
38 #include <libc_int.h>
39
40 /*
41 * Private structures.
42 */
43
44 typedef union {
45 mutex_t lock;
46 rwlock_t rwlock;
47 sema_t semaphore;
48 cond_t condition;
49 } td_so_un_t;
1973 return (TD_DBERR);
1974 }
1975
1976 if (ps_lsetfpregs(ph_p, thr_to_lwpid(th_p), fpregset) != PS_OK)
1977 return_val = TD_DBERR;
1978
1979 (void) ps_pcontinue(ph_p);
1980 ph_unlock(th_p->th_ta_p);
1981 return (return_val);
1982 }
1983
1984 /*
1985 * Get the size of the extra state register set for this architecture.
1986 * Currently unused by dbx.
1987 */
1988 #pragma weak td_thr_getxregsize = __td_thr_getxregsize
1989 /* ARGSUSED */
1990 td_err_e
1991 __td_thr_getxregsize(td_thrhandle_t *th_p, int *xregsize)
1992 {
1993 struct ps_prochandle *ph_p;
1994 td_err_e return_val;
1995
1996 if ((ph_p = ph_lock_th(th_p, &return_val)) == NULL)
1997 return (return_val);
1998 if (ps_pstop(ph_p) != PS_OK) {
1999 ph_unlock(th_p->th_ta_p);
2000 return (TD_DBERR);
2001 }
2002
2003 if (ps_lgetxregsize(ph_p, thr_to_lwpid(th_p), xregsize) != PS_OK)
2004 return_val = TD_DBERR;
2005
2006 if (*xregsize == 0)
2007 return_val = TD_NOXREGS;
2008
2009 (void) ps_pcontinue(ph_p);
2010 ph_unlock(th_p->th_ta_p);
2011 return (return_val);
2012 }
2013
2014 /*
2015 * Get a thread's extra state register set.
2016 */
2017 #pragma weak td_thr_getxregs = __td_thr_getxregs
2018 td_err_e
2019 __td_thr_getxregs(td_thrhandle_t *th_p, void *xregset)
2020 {
2021 struct ps_prochandle *ph_p;
2022 td_err_e return_val;
2023 ps_err_e ps_err;
2024
2025 if ((ph_p = ph_lock_th(th_p, &return_val)) == NULL)
2026 return (return_val);
2027 if (ps_pstop(ph_p) != PS_OK) {
2028 ph_unlock(th_p->th_ta_p);
2029 return (TD_DBERR);
2030 }
2031
2032 ps_err = ps_lgetxregs(ph_p, thr_to_lwpid(th_p), (caddr_t)xregset);
2033 if (ps_err == PS_NOXREGS)
2034 return_val = TD_NOXREGS;
2035 else if (ps_err != PS_OK)
2036 return_val = TD_DBERR;
2037
2038 (void) ps_pcontinue(ph_p);
2039 ph_unlock(th_p->th_ta_p);
2040 return (return_val);
2041 }
2042
2043 /*
2044 * Set a thread's extra state register set.
2045 */
2046 #pragma weak td_thr_setxregs = __td_thr_setxregs
2047 /* ARGSUSED */
2048 td_err_e
2049 __td_thr_setxregs(td_thrhandle_t *th_p, const void *xregset)
2050 {
2051 struct ps_prochandle *ph_p;
2052 td_err_e return_val;
2053
2054 if ((ph_p = ph_lock_th(th_p, &return_val)) == NULL)
2055 return (return_val);
2056 if (ps_pstop(ph_p) != PS_OK) {
2057 ph_unlock(th_p->th_ta_p);
2058 return (TD_DBERR);
2059 }
2060
2061 if (ps_lsetxregs(ph_p, thr_to_lwpid(th_p), (caddr_t)xregset) != PS_OK)
2062 return_val = TD_DBERR;
2063
2064 (void) ps_pcontinue(ph_p);
2065 ph_unlock(th_p->th_ta_p);
2066 return (return_val);
2067 }
2068
2069 struct searcher {
2070 psaddr_t addr;
2071 int status;
2072 };
2073
2074 /*
2075 * Check the struct thread address in *th_p again first
2076 * value in "data". If value in data is found, set second value
2077 * in "data" to 1 and return 1 to terminate iterations.
2078 * This function is used by td_thr_validate() to verify that
2079 * a thread handle is valid.
2080 */
2081 static int
2082 td_searcher(const td_thrhandle_t *th_p, void *data)
2083 {
2084 struct searcher *searcher_data = (struct searcher *)data;
2085
2086 if (searcher_data->addr == th_p->th_unique) {
|