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) {
 
 |