1*5e53a4f9SPedro F. Giffuni /*- 2*5e53a4f9SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*5e53a4f9SPedro F. Giffuni * 43c1e38eaSMarcel Moolenaar * Copyright (c) 2004 David Xu <davidxu@freebsd.org> 53c1e38eaSMarcel Moolenaar * All rights reserved. 63c1e38eaSMarcel Moolenaar * 73c1e38eaSMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 83c1e38eaSMarcel Moolenaar * modification, are permitted provided that the following conditions 93c1e38eaSMarcel Moolenaar * are met: 103c1e38eaSMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 113c1e38eaSMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 123c1e38eaSMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 133c1e38eaSMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 143c1e38eaSMarcel Moolenaar * documentation and/or other materials provided with the distribution. 153c1e38eaSMarcel Moolenaar * 163c1e38eaSMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 173c1e38eaSMarcel Moolenaar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 183c1e38eaSMarcel Moolenaar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 193c1e38eaSMarcel Moolenaar * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 203c1e38eaSMarcel Moolenaar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 213c1e38eaSMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 223c1e38eaSMarcel Moolenaar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 233c1e38eaSMarcel Moolenaar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 243c1e38eaSMarcel Moolenaar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 253c1e38eaSMarcel Moolenaar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 263c1e38eaSMarcel Moolenaar * SUCH DAMAGE. 273c1e38eaSMarcel Moolenaar */ 283c1e38eaSMarcel Moolenaar 293c1e38eaSMarcel Moolenaar #include <sys/cdefs.h> 303c1e38eaSMarcel Moolenaar __FBSDID("$FreeBSD$"); 313c1e38eaSMarcel Moolenaar 323c1e38eaSMarcel Moolenaar #include <proc_service.h> 333c1e38eaSMarcel Moolenaar #include <stddef.h> 343c1e38eaSMarcel Moolenaar #include <thread_db.h> 353c1e38eaSMarcel Moolenaar #include <unistd.h> 3620b94d80SDavid Xu #include <sys/cdefs.h> 378d4e4b79SMarcel Moolenaar #include <sys/endian.h> 388d4e4b79SMarcel Moolenaar #include <sys/errno.h> 3920b94d80SDavid Xu #include <sys/linker_set.h> 403c1e38eaSMarcel Moolenaar 413c1e38eaSMarcel Moolenaar #include "thread_db_int.h" 423c1e38eaSMarcel Moolenaar 433c1e38eaSMarcel Moolenaar struct td_thragent 443c1e38eaSMarcel Moolenaar { 453c1e38eaSMarcel Moolenaar TD_THRAGENT_FIELDS; 463c1e38eaSMarcel Moolenaar }; 473c1e38eaSMarcel Moolenaar 483c1e38eaSMarcel Moolenaar static TAILQ_HEAD(, td_thragent) proclist = TAILQ_HEAD_INITIALIZER(proclist); 493c1e38eaSMarcel Moolenaar 5020b94d80SDavid Xu SET_DECLARE(__ta_ops, struct ta_ops); 513c1e38eaSMarcel Moolenaar 523c1e38eaSMarcel Moolenaar td_err_e 533c1e38eaSMarcel Moolenaar td_init(void) 543c1e38eaSMarcel Moolenaar { 553c1e38eaSMarcel Moolenaar td_err_e ret, tmp; 5620b94d80SDavid Xu struct ta_ops *ops_p, **ops_pp; 573c1e38eaSMarcel Moolenaar 583c1e38eaSMarcel Moolenaar ret = 0; 5920b94d80SDavid Xu SET_FOREACH(ops_pp, __ta_ops) { 6020b94d80SDavid Xu ops_p = *ops_pp; 6120b94d80SDavid Xu if (ops_p->to_init != NULL) { 6220b94d80SDavid Xu tmp = ops_p->to_init(); 633c1e38eaSMarcel Moolenaar if (tmp != TD_OK) 643c1e38eaSMarcel Moolenaar ret = tmp; 653c1e38eaSMarcel Moolenaar } 663c1e38eaSMarcel Moolenaar } 673c1e38eaSMarcel Moolenaar return (ret); 683c1e38eaSMarcel Moolenaar } 693c1e38eaSMarcel Moolenaar 703c1e38eaSMarcel Moolenaar td_err_e 713c1e38eaSMarcel Moolenaar td_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *events) 723c1e38eaSMarcel Moolenaar { 733c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_clear_event(ta, events)); 743c1e38eaSMarcel Moolenaar } 753c1e38eaSMarcel Moolenaar 763c1e38eaSMarcel Moolenaar td_err_e 773c1e38eaSMarcel Moolenaar td_ta_delete(td_thragent_t *ta) 783c1e38eaSMarcel Moolenaar { 793c1e38eaSMarcel Moolenaar TAILQ_REMOVE(&proclist, ta, ta_next); 803c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_delete(ta)); 813c1e38eaSMarcel Moolenaar } 823c1e38eaSMarcel Moolenaar 833c1e38eaSMarcel Moolenaar td_err_e 843c1e38eaSMarcel Moolenaar td_ta_event_addr(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr) 853c1e38eaSMarcel Moolenaar { 863c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_event_addr(ta, event, ptr)); 873c1e38eaSMarcel Moolenaar } 883c1e38eaSMarcel Moolenaar 893c1e38eaSMarcel Moolenaar td_err_e 903c1e38eaSMarcel Moolenaar td_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg) 913c1e38eaSMarcel Moolenaar { 923c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_event_getmsg(ta, msg)); 933c1e38eaSMarcel Moolenaar } 943c1e38eaSMarcel Moolenaar 953c1e38eaSMarcel Moolenaar td_err_e 963c1e38eaSMarcel Moolenaar td_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th) 973c1e38eaSMarcel Moolenaar { 983c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_map_id2thr(ta, id, th)); 993c1e38eaSMarcel Moolenaar } 1003c1e38eaSMarcel Moolenaar 1013c1e38eaSMarcel Moolenaar td_err_e 1023c1e38eaSMarcel Moolenaar td_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) 1033c1e38eaSMarcel Moolenaar { 1043c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_map_lwp2thr(ta, lwpid, th)); 1053c1e38eaSMarcel Moolenaar } 1063c1e38eaSMarcel Moolenaar 1073c1e38eaSMarcel Moolenaar td_err_e 1083c1e38eaSMarcel Moolenaar td_ta_new(struct ps_prochandle *ph, td_thragent_t **pta) 1093c1e38eaSMarcel Moolenaar { 11020b94d80SDavid Xu struct ta_ops *ops_p, **ops_pp; 1113c1e38eaSMarcel Moolenaar 11220b94d80SDavid Xu SET_FOREACH(ops_pp, __ta_ops) { 11320b94d80SDavid Xu ops_p = *ops_pp; 11420b94d80SDavid Xu if (ops_p->to_ta_new(ph, pta) == TD_OK) { 1153c1e38eaSMarcel Moolenaar TAILQ_INSERT_HEAD(&proclist, *pta, ta_next); 11620b94d80SDavid Xu (*pta)->ta_ops = ops_p; 1173c1e38eaSMarcel Moolenaar return (TD_OK); 1183c1e38eaSMarcel Moolenaar } 1193c1e38eaSMarcel Moolenaar } 1203c1e38eaSMarcel Moolenaar return (TD_NOLIBTHREAD); 1213c1e38eaSMarcel Moolenaar } 1223c1e38eaSMarcel Moolenaar 1233c1e38eaSMarcel Moolenaar td_err_e 1243c1e38eaSMarcel Moolenaar td_ta_set_event(const td_thragent_t *ta, td_thr_events_t *events) 1253c1e38eaSMarcel Moolenaar { 1263c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_set_event(ta, events)); 1273c1e38eaSMarcel Moolenaar } 1283c1e38eaSMarcel Moolenaar 1293c1e38eaSMarcel Moolenaar td_err_e 1303c1e38eaSMarcel Moolenaar td_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *callback, 1313c1e38eaSMarcel Moolenaar void *cbdata_p, td_thr_state_e state, int ti_pri, sigset_t *ti_sigmask_p, 1323c1e38eaSMarcel Moolenaar unsigned int ti_user_flags) 1333c1e38eaSMarcel Moolenaar { 1343c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_thr_iter(ta, callback, cbdata_p, state, 1353c1e38eaSMarcel Moolenaar ti_pri, ti_sigmask_p, ti_user_flags)); 1363c1e38eaSMarcel Moolenaar } 1373c1e38eaSMarcel Moolenaar 1383c1e38eaSMarcel Moolenaar td_err_e 1393c1e38eaSMarcel Moolenaar td_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *callback, 1403c1e38eaSMarcel Moolenaar void *cbdata_p) 1413c1e38eaSMarcel Moolenaar { 1423c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_ta_tsd_iter(ta, callback, cbdata_p)); 1433c1e38eaSMarcel Moolenaar } 1443c1e38eaSMarcel Moolenaar 1453c1e38eaSMarcel Moolenaar td_err_e 1463c1e38eaSMarcel Moolenaar td_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *events) 1473c1e38eaSMarcel Moolenaar { 1483c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 1493c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_clear_event(th, events)); 1503c1e38eaSMarcel Moolenaar } 1513c1e38eaSMarcel Moolenaar 1523c1e38eaSMarcel Moolenaar td_err_e 1533c1e38eaSMarcel Moolenaar td_thr_dbresume(const td_thrhandle_t *th) 1543c1e38eaSMarcel Moolenaar { 1553c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 1563c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_dbresume(th)); 1573c1e38eaSMarcel Moolenaar } 1583c1e38eaSMarcel Moolenaar 1593c1e38eaSMarcel Moolenaar td_err_e 1603c1e38eaSMarcel Moolenaar td_thr_dbsuspend(const td_thrhandle_t *th) 1613c1e38eaSMarcel Moolenaar { 1623c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 1633c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_dbsuspend(th)); 1643c1e38eaSMarcel Moolenaar } 1653c1e38eaSMarcel Moolenaar 1663c1e38eaSMarcel Moolenaar td_err_e 1673c1e38eaSMarcel Moolenaar td_thr_event_enable(const td_thrhandle_t *th, int en) 1683c1e38eaSMarcel Moolenaar { 1693c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 1703c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_event_enable(th, en)); 1713c1e38eaSMarcel Moolenaar } 1723c1e38eaSMarcel Moolenaar 1733c1e38eaSMarcel Moolenaar td_err_e 1743c1e38eaSMarcel Moolenaar td_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg) 1753c1e38eaSMarcel Moolenaar { 1763c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 1773c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_event_getmsg(th, msg)); 1783c1e38eaSMarcel Moolenaar } 1793c1e38eaSMarcel Moolenaar 1803c1e38eaSMarcel Moolenaar td_err_e 181098d0537SKonstantin Belousov td_thr_old_get_info(const td_thrhandle_t *th, td_old_thrinfo_t *info) 182098d0537SKonstantin Belousov { 183098d0537SKonstantin Belousov const td_thragent_t *ta = th->th_ta; 184098d0537SKonstantin Belousov return (ta->ta_ops->to_thr_old_get_info(th, info)); 185098d0537SKonstantin Belousov } 186098d0537SKonstantin Belousov __sym_compat(td_thr_get_info, td_thr_old_get_info, FBSD_1.0); 187098d0537SKonstantin Belousov 188098d0537SKonstantin Belousov td_err_e 1893c1e38eaSMarcel Moolenaar td_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info) 1903c1e38eaSMarcel Moolenaar { 1913c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 1923c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_get_info(th, info)); 1933c1e38eaSMarcel Moolenaar } 1943c1e38eaSMarcel Moolenaar 1958d7681bbSDoug Rabson #ifdef __i386__ 1968d7681bbSDoug Rabson td_err_e 1978d7681bbSDoug Rabson td_thr_getxmmregs(const td_thrhandle_t *th, char *fxsave) 1988d7681bbSDoug Rabson { 1998d7681bbSDoug Rabson const td_thragent_t *ta = th->th_ta; 2008d7681bbSDoug Rabson return (ta->ta_ops->to_thr_getxmmregs(th, fxsave)); 2018d7681bbSDoug Rabson } 2028d7681bbSDoug Rabson #endif 2038d7681bbSDoug Rabson 2048d7681bbSDoug Rabson 2053c1e38eaSMarcel Moolenaar td_err_e 2063c1e38eaSMarcel Moolenaar td_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregset) 2073c1e38eaSMarcel Moolenaar { 2083c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 2093c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_getfpregs(th, fpregset)); 2103c1e38eaSMarcel Moolenaar } 2113c1e38eaSMarcel Moolenaar 2123c1e38eaSMarcel Moolenaar td_err_e 2133c1e38eaSMarcel Moolenaar td_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs) 2143c1e38eaSMarcel Moolenaar { 2153c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 2163c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_getgregs(th, gregs)); 2173c1e38eaSMarcel Moolenaar } 2183c1e38eaSMarcel Moolenaar 2193c1e38eaSMarcel Moolenaar td_err_e 2203c1e38eaSMarcel Moolenaar td_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *events) 2213c1e38eaSMarcel Moolenaar { 2223c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 2233c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_set_event(th, events)); 2243c1e38eaSMarcel Moolenaar } 2253c1e38eaSMarcel Moolenaar 2268d7681bbSDoug Rabson #ifdef __i386__ 2278d7681bbSDoug Rabson td_err_e 2288d7681bbSDoug Rabson td_thr_setxmmregs(const td_thrhandle_t *th, const char *fxsave) 2298d7681bbSDoug Rabson { 2308d7681bbSDoug Rabson const td_thragent_t *ta = th->th_ta; 2318d7681bbSDoug Rabson return (ta->ta_ops->to_thr_setxmmregs(th, fxsave)); 2328d7681bbSDoug Rabson } 2338d7681bbSDoug Rabson #endif 2348d7681bbSDoug Rabson 2353c1e38eaSMarcel Moolenaar td_err_e 2363c1e38eaSMarcel Moolenaar td_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs) 2373c1e38eaSMarcel Moolenaar { 2383c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 2393c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_setfpregs(th, fpregs)); 2403c1e38eaSMarcel Moolenaar } 2413c1e38eaSMarcel Moolenaar 2423c1e38eaSMarcel Moolenaar td_err_e 2433c1e38eaSMarcel Moolenaar td_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs) 2443c1e38eaSMarcel Moolenaar { 2453c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 2463c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_setgregs(th, gregs)); 2473c1e38eaSMarcel Moolenaar } 2483c1e38eaSMarcel Moolenaar 2493c1e38eaSMarcel Moolenaar td_err_e 2503c1e38eaSMarcel Moolenaar td_thr_validate(const td_thrhandle_t *th) 2513c1e38eaSMarcel Moolenaar { 2523c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 2533c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_validate(th)); 2543c1e38eaSMarcel Moolenaar } 2553c1e38eaSMarcel Moolenaar 2563e93cc3aSDavid Xu td_err_e 25716b0c20cSMarcel Moolenaar td_thr_tls_get_addr(const td_thrhandle_t *th, psaddr_t linkmap, size_t offset, 25816b0c20cSMarcel Moolenaar psaddr_t *address) 2593e93cc3aSDavid Xu { 2603e93cc3aSDavid Xu const td_thragent_t *ta = th->th_ta; 2613e93cc3aSDavid Xu return (ta->ta_ops->to_thr_tls_get_addr(th, linkmap, offset, address)); 2623e93cc3aSDavid Xu } 2633e93cc3aSDavid Xu 2643c1e38eaSMarcel Moolenaar /* FreeBSD specific extensions. */ 2653c1e38eaSMarcel Moolenaar 2663c1e38eaSMarcel Moolenaar td_err_e 2673c1e38eaSMarcel Moolenaar td_thr_sstep(const td_thrhandle_t *th, int step) 2683c1e38eaSMarcel Moolenaar { 2693c1e38eaSMarcel Moolenaar const td_thragent_t *ta = th->th_ta; 2703c1e38eaSMarcel Moolenaar return (ta->ta_ops->to_thr_sstep(th, step)); 2713c1e38eaSMarcel Moolenaar } 2728d4e4b79SMarcel Moolenaar 2738d4e4b79SMarcel Moolenaar /* 2748d4e4b79SMarcel Moolenaar * Support functions for reading from and writing to the target 2758d4e4b79SMarcel Moolenaar * address space. 2768d4e4b79SMarcel Moolenaar */ 2778d4e4b79SMarcel Moolenaar 2788d4e4b79SMarcel Moolenaar static int 2798d4e4b79SMarcel Moolenaar thr_pread(struct ps_prochandle *ph, psaddr_t addr, uint64_t *val, 2808d4e4b79SMarcel Moolenaar u_int size, u_int byteorder) 2818d4e4b79SMarcel Moolenaar { 2828d4e4b79SMarcel Moolenaar uint8_t buf[sizeof(*val)]; 2838d4e4b79SMarcel Moolenaar ps_err_e err; 2848d4e4b79SMarcel Moolenaar 2858d4e4b79SMarcel Moolenaar if (size > sizeof(buf)) 2868d4e4b79SMarcel Moolenaar return (EOVERFLOW); 2878d4e4b79SMarcel Moolenaar 2888d4e4b79SMarcel Moolenaar err = ps_pread(ph, addr, buf, size); 2898d4e4b79SMarcel Moolenaar if (err != PS_OK) 2908d4e4b79SMarcel Moolenaar return (EFAULT); 2918d4e4b79SMarcel Moolenaar 2928d4e4b79SMarcel Moolenaar switch (byteorder) { 2938d4e4b79SMarcel Moolenaar case BIG_ENDIAN: 2948d4e4b79SMarcel Moolenaar switch (size) { 2958d4e4b79SMarcel Moolenaar case 1: 2968d4e4b79SMarcel Moolenaar *val = buf[0]; 2978d4e4b79SMarcel Moolenaar break; 2988d4e4b79SMarcel Moolenaar case 2: 2998d4e4b79SMarcel Moolenaar *val = be16dec(buf); 3008d4e4b79SMarcel Moolenaar break; 3018d4e4b79SMarcel Moolenaar case 4: 3028d4e4b79SMarcel Moolenaar *val = be32dec(buf); 3038d4e4b79SMarcel Moolenaar break; 3048d4e4b79SMarcel Moolenaar case 8: 3058d4e4b79SMarcel Moolenaar *val = be64dec(buf); 3068d4e4b79SMarcel Moolenaar break; 3078d4e4b79SMarcel Moolenaar default: 3088d4e4b79SMarcel Moolenaar return (EINVAL); 3098d4e4b79SMarcel Moolenaar } 3108d4e4b79SMarcel Moolenaar break; 3118d4e4b79SMarcel Moolenaar case LITTLE_ENDIAN: 3128d4e4b79SMarcel Moolenaar switch (size) { 3138d4e4b79SMarcel Moolenaar case 1: 3148d4e4b79SMarcel Moolenaar *val = buf[0]; 3158d4e4b79SMarcel Moolenaar break; 3168d4e4b79SMarcel Moolenaar case 2: 3178d4e4b79SMarcel Moolenaar *val = le16dec(buf); 3188d4e4b79SMarcel Moolenaar break; 3198d4e4b79SMarcel Moolenaar case 4: 3208d4e4b79SMarcel Moolenaar *val = le32dec(buf); 3218d4e4b79SMarcel Moolenaar break; 3228d4e4b79SMarcel Moolenaar case 8: 3238d4e4b79SMarcel Moolenaar *val = le64dec(buf); 3248d4e4b79SMarcel Moolenaar break; 3258d4e4b79SMarcel Moolenaar default: 3268d4e4b79SMarcel Moolenaar return (EINVAL); 3278d4e4b79SMarcel Moolenaar } 3288d4e4b79SMarcel Moolenaar break; 3298d4e4b79SMarcel Moolenaar default: 3308d4e4b79SMarcel Moolenaar return (EINVAL); 3318d4e4b79SMarcel Moolenaar } 3328d4e4b79SMarcel Moolenaar 3338d4e4b79SMarcel Moolenaar return (0); 3348d4e4b79SMarcel Moolenaar } 3358d4e4b79SMarcel Moolenaar 3368d4e4b79SMarcel Moolenaar int 33703fad2adSMarcel Moolenaar thr_pread_int(const struct td_thragent *ta, psaddr_t addr, uint32_t *val) 3388d4e4b79SMarcel Moolenaar { 3398d4e4b79SMarcel Moolenaar uint64_t tmp; 3408d4e4b79SMarcel Moolenaar int error; 3418d4e4b79SMarcel Moolenaar 3428d4e4b79SMarcel Moolenaar error = thr_pread(ta->ph, addr, &tmp, sizeof(int), BYTE_ORDER); 3438d4e4b79SMarcel Moolenaar if (!error) 3448d4e4b79SMarcel Moolenaar *val = tmp; 3458d4e4b79SMarcel Moolenaar 3468d4e4b79SMarcel Moolenaar return (error); 3478d4e4b79SMarcel Moolenaar } 3488d4e4b79SMarcel Moolenaar 3498d4e4b79SMarcel Moolenaar int 35003fad2adSMarcel Moolenaar thr_pread_long(const struct td_thragent *ta, psaddr_t addr, uint64_t *val) 3518d4e4b79SMarcel Moolenaar { 3528d4e4b79SMarcel Moolenaar 3538d4e4b79SMarcel Moolenaar return (thr_pread(ta->ph, addr, val, sizeof(long), BYTE_ORDER)); 3548d4e4b79SMarcel Moolenaar } 3558d4e4b79SMarcel Moolenaar 3568d4e4b79SMarcel Moolenaar int 35703fad2adSMarcel Moolenaar thr_pread_ptr(const struct td_thragent *ta, psaddr_t addr, psaddr_t *val) 3588d4e4b79SMarcel Moolenaar { 35903fad2adSMarcel Moolenaar uint64_t tmp; 36003fad2adSMarcel Moolenaar int error; 3618d4e4b79SMarcel Moolenaar 36203fad2adSMarcel Moolenaar error = thr_pread(ta->ph, addr, &tmp, sizeof(void *), BYTE_ORDER); 36303fad2adSMarcel Moolenaar if (!error) 36403fad2adSMarcel Moolenaar *val = tmp; 36503fad2adSMarcel Moolenaar 36603fad2adSMarcel Moolenaar return (error); 3678d4e4b79SMarcel Moolenaar } 3688d4e4b79SMarcel Moolenaar 3698d4e4b79SMarcel Moolenaar static int 3708d4e4b79SMarcel Moolenaar thr_pwrite(struct ps_prochandle *ph, psaddr_t addr, uint64_t val, 3718d4e4b79SMarcel Moolenaar u_int size, u_int byteorder) 3728d4e4b79SMarcel Moolenaar { 3738d4e4b79SMarcel Moolenaar uint8_t buf[sizeof(val)]; 3748d4e4b79SMarcel Moolenaar ps_err_e err; 3758d4e4b79SMarcel Moolenaar 3768d4e4b79SMarcel Moolenaar if (size > sizeof(buf)) 3778d4e4b79SMarcel Moolenaar return (EOVERFLOW); 3788d4e4b79SMarcel Moolenaar 3798d4e4b79SMarcel Moolenaar switch (byteorder) { 3808d4e4b79SMarcel Moolenaar case BIG_ENDIAN: 3818d4e4b79SMarcel Moolenaar switch (size) { 3828d4e4b79SMarcel Moolenaar case 1: 3838d4e4b79SMarcel Moolenaar buf[0] = (uint8_t)val; 3848d4e4b79SMarcel Moolenaar break; 3858d4e4b79SMarcel Moolenaar case 2: 3868d4e4b79SMarcel Moolenaar be16enc(buf, (uint16_t)val); 3878d4e4b79SMarcel Moolenaar break; 3888d4e4b79SMarcel Moolenaar case 4: 3898d4e4b79SMarcel Moolenaar be32enc(buf, (uint32_t)val); 3908d4e4b79SMarcel Moolenaar break; 3918d4e4b79SMarcel Moolenaar case 8: 3928d4e4b79SMarcel Moolenaar be64enc(buf, (uint64_t)val); 3938d4e4b79SMarcel Moolenaar break; 3948d4e4b79SMarcel Moolenaar default: 3958d4e4b79SMarcel Moolenaar return (EINVAL); 3968d4e4b79SMarcel Moolenaar } 3978d4e4b79SMarcel Moolenaar break; 3988d4e4b79SMarcel Moolenaar case LITTLE_ENDIAN: 3998d4e4b79SMarcel Moolenaar switch (size) { 4008d4e4b79SMarcel Moolenaar case 1: 4018d4e4b79SMarcel Moolenaar buf[0] = (uint8_t)val; 4028d4e4b79SMarcel Moolenaar break; 4038d4e4b79SMarcel Moolenaar case 2: 4048d4e4b79SMarcel Moolenaar le16enc(buf, (uint16_t)val); 4058d4e4b79SMarcel Moolenaar break; 4068d4e4b79SMarcel Moolenaar case 4: 4078d4e4b79SMarcel Moolenaar le32enc(buf, (uint32_t)val); 4088d4e4b79SMarcel Moolenaar break; 4098d4e4b79SMarcel Moolenaar case 8: 4108d4e4b79SMarcel Moolenaar le64enc(buf, (uint64_t)val); 4118d4e4b79SMarcel Moolenaar break; 4128d4e4b79SMarcel Moolenaar default: 4138d4e4b79SMarcel Moolenaar return (EINVAL); 4148d4e4b79SMarcel Moolenaar } 4158d4e4b79SMarcel Moolenaar break; 4168d4e4b79SMarcel Moolenaar default: 4178d4e4b79SMarcel Moolenaar return (EINVAL); 4188d4e4b79SMarcel Moolenaar } 4198d4e4b79SMarcel Moolenaar 4208d4e4b79SMarcel Moolenaar err = ps_pwrite(ph, addr, buf, size); 4218d4e4b79SMarcel Moolenaar return ((err != PS_OK) ? EFAULT : 0); 4228d4e4b79SMarcel Moolenaar } 4238d4e4b79SMarcel Moolenaar 4248d4e4b79SMarcel Moolenaar int 42503fad2adSMarcel Moolenaar thr_pwrite_int(const struct td_thragent *ta, psaddr_t addr, uint32_t val) 4268d4e4b79SMarcel Moolenaar { 4278d4e4b79SMarcel Moolenaar 4288d4e4b79SMarcel Moolenaar return (thr_pwrite(ta->ph, addr, val, sizeof(int), BYTE_ORDER)); 4298d4e4b79SMarcel Moolenaar } 4308d4e4b79SMarcel Moolenaar 4318d4e4b79SMarcel Moolenaar int 43203fad2adSMarcel Moolenaar thr_pwrite_long(const struct td_thragent *ta, psaddr_t addr, uint64_t val) 4338d4e4b79SMarcel Moolenaar { 4348d4e4b79SMarcel Moolenaar 4358d4e4b79SMarcel Moolenaar return (thr_pwrite(ta->ph, addr, val, sizeof(long), BYTE_ORDER)); 4368d4e4b79SMarcel Moolenaar } 4378d4e4b79SMarcel Moolenaar 4388d4e4b79SMarcel Moolenaar int 43903fad2adSMarcel Moolenaar thr_pwrite_ptr(const struct td_thragent *ta, psaddr_t addr, psaddr_t val) 4408d4e4b79SMarcel Moolenaar { 4418d4e4b79SMarcel Moolenaar 4428d4e4b79SMarcel Moolenaar return (thr_pwrite(ta->ph, addr, val, sizeof(void *), BYTE_ORDER)); 4438d4e4b79SMarcel Moolenaar } 4448d4e4b79SMarcel Moolenaar 445