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