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 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2018 Joyent, Inc.
28 * Copyright (c) 2014 by Delphix. All rights reserved.
29 * Copyright 2020 Oxide Computer Company
30 */
31
32 /*
33 * User Process Target
34 *
35 * The user process target is invoked when the -u or -p command-line options
36 * are used, or when an ELF executable file or ELF core file is specified on
37 * the command-line. This target is also selected by default when no target
38 * options are present. In this case, it defaults the executable name to
39 * "a.out". If no process or core file is currently attached, the target
40 * functions as a kind of virtual /dev/zero (in accordance with adb(1)
41 * semantics); reads from the virtual address space return zeroes and writes
42 * fail silently. The proc target itself is designed as a wrapper around the
43 * services provided by libproc.so: t->t_pshandle is set to the struct
44 * ps_prochandle pointer returned as a handle by libproc. The target also
45 * opens the executable file itself using the MDB GElf services, for
46 * interpreting the .symtab and .dynsym if no libproc handle has been
47 * initialized, and for handling i/o to and from the object file. Currently,
48 * the only ISA-dependent portions of the proc target are the $r and ::fpregs
49 * dcmds, the callbacks for t_next() and t_step_out(), and the list of named
4622
4623 if (t->t_pshandle == NULL)
4624 return (set_errno(EMDB_NOPROC));
4625
4626 if ((v = mdb_nv_lookup(&pt->p_regs, rname)) != NULL) {
4627 uintmax_t rd_nval = mdb_nv_get_value(v);
4628 ushort_t rd_num = MDB_TGT_R_NUM(rd_nval);
4629 ushort_t rd_flags = MDB_TGT_R_FLAGS(rd_nval);
4630
4631 if (!MDB_TGT_R_IS_FP(rd_flags)) {
4632
4633 if (rd_flags & MDB_TGT_R_32)
4634 r &= 0xffffffffULL;
4635 else if (rd_flags & MDB_TGT_R_16)
4636 r &= 0xffffULL;
4637 else if (rd_flags & MDB_TGT_R_8H)
4638 r = (r & 0xffULL) << 8;
4639 else if (rd_flags & MDB_TGT_R_8L)
4640 r &= 0xffULL;
4641
4642 #if defined(__sparc) && defined(_ILP32)
4643 /*
4644 * If we are debugging on 32-bit SPARC, the globals and
4645 * outs can have 32 upper bits stored in the xregs.
4646 */
4647 int is_g = (rd_num == R_G0 ||
4648 rd_num >= R_G1 && rd_num <= R_G7);
4649 int is_o = (rd_num >= R_O0 && rd_num <= R_O7);
4650 prxregset_t xrs;
4651
4652 if ((is_g || is_o) && PTL_GETXREGS(t, tid, &xrs) == 0 &&
4653 xrs.pr_type == XR_TYPE_V8P) {
4654 if (is_g) {
4655 xrs.pr_un.pr_v8p.pr_xg[rd_num -
4656 R_G0 + XR_G0] = (uint32_t)(r >> 32);
4657 } else if (is_o) {
4658 xrs.pr_un.pr_v8p.pr_xo[rd_num -
4659 R_O0 + XR_O0] = (uint32_t)(r >> 32);
4660 }
4661
4662 if (PTL_SETXREGS(t, tid, &xrs) == -1)
4663 return (-1);
4664 }
4665 #endif /* __sparc && _ILP32 */
4666
4667 if (PTL_GETREGS(t, tid, grs) == 0) {
4668 grs[rd_num] = (prgreg_t)r;
4669 return (PTL_SETREGS(t, tid, grs));
4670 }
4671 return (-1);
4672 } else
4673 return (pt_putfpreg(t, tid, rd_num, rd_flags, r));
4674 }
4675
4676 return (set_errno(EMDB_BADREG));
4677 }
4678
4679 static int
4680 pt_stack_call(pt_stkarg_t *psp, const prgregset_t grs, uint_t argc, long *argv)
4681 {
4682 psp->pstk_gotpc |= (grs[R_PC] != 0);
4683
4684 if (!psp->pstk_gotpc)
4685 return (0); /* skip initial zeroed frames */
4686
4820 pt_lwp_getregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs)
4821 {
4822 if (t->t_pshandle != NULL) {
4823 return (ptl_err(Plwp_getregs(t->t_pshandle,
4824 (lwpid_t)tid, gregs)));
4825 }
4826 return (set_errno(EMDB_NOPROC));
4827 }
4828
4829 /*ARGSUSED*/
4830 static int
4831 pt_lwp_setregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs)
4832 {
4833 if (t->t_pshandle != NULL) {
4834 return (ptl_err(Plwp_setregs(t->t_pshandle,
4835 (lwpid_t)tid, gregs)));
4836 }
4837 return (set_errno(EMDB_NOPROC));
4838 }
4839
4840 #ifdef __sparc
4841
4842 /*ARGSUSED*/
4843 static int
4844 pt_lwp_getxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prxregset_t *xregs)
4845 {
4846 if (t->t_pshandle != NULL) {
4847 return (ptl_err(Plwp_getxregs(t->t_pshandle,
4848 (lwpid_t)tid, xregs)));
4849 }
4850 return (set_errno(EMDB_NOPROC));
4851 }
4852
4853 /*ARGSUSED*/
4854 static int
4855 pt_lwp_setxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
4856 const prxregset_t *xregs)
4857 {
4858 if (t->t_pshandle != NULL) {
4859 return (ptl_err(Plwp_setxregs(t->t_pshandle,
4860 (lwpid_t)tid, xregs)));
4861 }
4862 return (set_errno(EMDB_NOPROC));
4863 }
4864
4865 #endif /* __sparc */
4866
4867 /*ARGSUSED*/
4868 static int
4869 pt_lwp_getfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
4870 prfpregset_t *fpregs)
4871 {
4872 if (t->t_pshandle != NULL) {
4873 return (ptl_err(Plwp_getfpregs(t->t_pshandle,
4874 (lwpid_t)tid, fpregs)));
4875 }
4876 return (set_errno(EMDB_NOPROC));
4877 }
4878
4879 /*ARGSUSED*/
4880 static int
4881 pt_lwp_setfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
4882 const prfpregset_t *fpregs)
4883 {
4884 if (t->t_pshandle != NULL) {
4885 return (ptl_err(Plwp_setfpregs(t->t_pshandle,
4886 (lwpid_t)tid, fpregs)));
4887 }
4888 return (set_errno(EMDB_NOPROC));
4889 }
4890
4891 static const pt_ptl_ops_t proc_lwp_ops = {
4892 (int (*)())(uintptr_t)mdb_tgt_nop,
4893 (void (*)())(uintptr_t)mdb_tgt_nop,
4894 pt_lwp_tid,
4895 pt_lwp_iter,
4896 pt_lwp_getregs,
4897 pt_lwp_setregs,
4898 #ifdef __sparc
4899 pt_lwp_getxregs,
4900 pt_lwp_setxregs,
4901 #endif
4902 pt_lwp_getfpregs,
4903 pt_lwp_setfpregs
4904 };
4905
4906 static int
4907 pt_tdb_ctor(mdb_tgt_t *t)
4908 {
4909 pt_data_t *pt = t->t_data;
4910 td_thragent_t *tap;
4911 td_err_e err;
4912
4913 if ((err = pt->p_tdb_ops->td_ta_new(t->t_pshandle, &tap)) != TD_OK)
4914 return (set_errno(tdb_to_errno(err)));
4915
4916 pt->p_ptl_hdl = tap;
4917 return (0);
4918 }
4919
4920 static void
4921 pt_tdb_dtor(mdb_tgt_t *t, void *tap)
4922 {
4923 pt_data_t *pt = t->t_data;
5007 pt_tdb_setregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs)
5008 {
5009 pt_data_t *pt = t->t_data;
5010
5011 td_thrhandle_t th;
5012 td_err_e err;
5013
5014 if (t->t_pshandle == NULL)
5015 return (set_errno(EMDB_NOPROC));
5016
5017 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5018 return (set_errno(tdb_to_errno(err)));
5019
5020 err = pt->p_tdb_ops->td_thr_setgregs(&th, gregs);
5021 if (err != TD_OK && err != TD_PARTIALREG)
5022 return (set_errno(tdb_to_errno(err)));
5023
5024 return (0);
5025 }
5026
5027 #ifdef __sparc
5028
5029 static int
5030 pt_tdb_getxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prxregset_t *xregs)
5031 {
5032 pt_data_t *pt = t->t_data;
5033
5034 td_thrhandle_t th;
5035 td_err_e err;
5036
5037 if (t->t_pshandle == NULL)
5038 return (set_errno(EMDB_NOPROC));
5039
5040 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5041 return (set_errno(tdb_to_errno(err)));
5042
5043 err = pt->p_tdb_ops->td_thr_getxregs(&th, xregs);
5044 if (err != TD_OK && err != TD_PARTIALREG)
5045 return (set_errno(tdb_to_errno(err)));
5046
5047 return (0);
5048 }
5049
5050 static int
5051 pt_tdb_setxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
5052 const prxregset_t *xregs)
5053 {
5054 pt_data_t *pt = t->t_data;
5055
5056 td_thrhandle_t th;
5057 td_err_e err;
5058
5059 if (t->t_pshandle == NULL)
5060 return (set_errno(EMDB_NOPROC));
5061
5062 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5063 return (set_errno(tdb_to_errno(err)));
5064
5065 err = pt->p_tdb_ops->td_thr_setxregs(&th, xregs);
5066 if (err != TD_OK && err != TD_PARTIALREG)
5067 return (set_errno(tdb_to_errno(err)));
5068
5069 return (0);
5070 }
5071
5072 #endif /* __sparc */
5073
5074 static int
5075 pt_tdb_getfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
5076 prfpregset_t *fpregs)
5077 {
5078 pt_data_t *pt = t->t_data;
5079
5080 td_thrhandle_t th;
5081 td_err_e err;
5082
5083 if (t->t_pshandle == NULL)
5084 return (set_errno(EMDB_NOPROC));
5085
5086 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5087 return (set_errno(tdb_to_errno(err)));
5088
5089 err = pt->p_tdb_ops->td_thr_getfpregs(&th, fpregs);
5090 if (err != TD_OK && err != TD_PARTIALREG)
5091 return (set_errno(tdb_to_errno(err)));
5092
5093 return (0);
5099 {
5100 pt_data_t *pt = t->t_data;
5101
5102 td_thrhandle_t th;
5103 td_err_e err;
5104
5105 if (t->t_pshandle == NULL)
5106 return (set_errno(EMDB_NOPROC));
5107
5108 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5109 return (set_errno(tdb_to_errno(err)));
5110
5111 err = pt->p_tdb_ops->td_thr_setfpregs(&th, fpregs);
5112 if (err != TD_OK && err != TD_PARTIALREG)
5113 return (set_errno(tdb_to_errno(err)));
5114
5115 return (0);
5116 }
5117
5118 static const pt_ptl_ops_t proc_tdb_ops = {
5119 pt_tdb_ctor,
5120 pt_tdb_dtor,
5121 pt_tdb_tid,
5122 pt_tdb_iter,
5123 pt_tdb_getregs,
5124 pt_tdb_setregs,
5125 #ifdef __sparc
5126 pt_tdb_getxregs,
5127 pt_tdb_setxregs,
5128 #endif
5129 pt_tdb_getfpregs,
5130 pt_tdb_setfpregs
5131 };
5132
5133 static ssize_t
5134 pt_xd_auxv(mdb_tgt_t *t, void *buf, size_t nbytes)
5135 {
5136 struct ps_prochandle *P = t->t_pshandle;
5137 const auxv_t *auxp, *auxv = NULL;
5138 int auxn = 0;
5139
5140 if (P != NULL && (auxv = Pgetauxvec(P)) != NULL &&
5141 auxv->a_type != AT_NULL) {
5142 for (auxp = auxv, auxn = 1; auxp->a_type != 0; auxp++)
5143 auxn++;
5144 }
5145
5146 if (buf == NULL && nbytes == 0)
5147 return (sizeof (auxv_t) * auxn);
5148
5149 if (auxn == 0)
5150 return (set_errno(ENODATA));
|
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 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2018 Joyent, Inc.
28 * Copyright (c) 2014 by Delphix. All rights reserved.
29 * Copyright 2023 Oxide Computer Company
30 */
31
32 /*
33 * User Process Target
34 *
35 * The user process target is invoked when the -u or -p command-line options
36 * are used, or when an ELF executable file or ELF core file is specified on
37 * the command-line. This target is also selected by default when no target
38 * options are present. In this case, it defaults the executable name to
39 * "a.out". If no process or core file is currently attached, the target
40 * functions as a kind of virtual /dev/zero (in accordance with adb(1)
41 * semantics); reads from the virtual address space return zeroes and writes
42 * fail silently. The proc target itself is designed as a wrapper around the
43 * services provided by libproc.so: t->t_pshandle is set to the struct
44 * ps_prochandle pointer returned as a handle by libproc. The target also
45 * opens the executable file itself using the MDB GElf services, for
46 * interpreting the .symtab and .dynsym if no libproc handle has been
47 * initialized, and for handling i/o to and from the object file. Currently,
48 * the only ISA-dependent portions of the proc target are the $r and ::fpregs
49 * dcmds, the callbacks for t_next() and t_step_out(), and the list of named
4622
4623 if (t->t_pshandle == NULL)
4624 return (set_errno(EMDB_NOPROC));
4625
4626 if ((v = mdb_nv_lookup(&pt->p_regs, rname)) != NULL) {
4627 uintmax_t rd_nval = mdb_nv_get_value(v);
4628 ushort_t rd_num = MDB_TGT_R_NUM(rd_nval);
4629 ushort_t rd_flags = MDB_TGT_R_FLAGS(rd_nval);
4630
4631 if (!MDB_TGT_R_IS_FP(rd_flags)) {
4632
4633 if (rd_flags & MDB_TGT_R_32)
4634 r &= 0xffffffffULL;
4635 else if (rd_flags & MDB_TGT_R_16)
4636 r &= 0xffffULL;
4637 else if (rd_flags & MDB_TGT_R_8H)
4638 r = (r & 0xffULL) << 8;
4639 else if (rd_flags & MDB_TGT_R_8L)
4640 r &= 0xffULL;
4641
4642 if (PTL_GETREGS(t, tid, grs) == 0) {
4643 grs[rd_num] = (prgreg_t)r;
4644 return (PTL_SETREGS(t, tid, grs));
4645 }
4646 return (-1);
4647 } else
4648 return (pt_putfpreg(t, tid, rd_num, rd_flags, r));
4649 }
4650
4651 return (set_errno(EMDB_BADREG));
4652 }
4653
4654 static int
4655 pt_stack_call(pt_stkarg_t *psp, const prgregset_t grs, uint_t argc, long *argv)
4656 {
4657 psp->pstk_gotpc |= (grs[R_PC] != 0);
4658
4659 if (!psp->pstk_gotpc)
4660 return (0); /* skip initial zeroed frames */
4661
4795 pt_lwp_getregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs)
4796 {
4797 if (t->t_pshandle != NULL) {
4798 return (ptl_err(Plwp_getregs(t->t_pshandle,
4799 (lwpid_t)tid, gregs)));
4800 }
4801 return (set_errno(EMDB_NOPROC));
4802 }
4803
4804 /*ARGSUSED*/
4805 static int
4806 pt_lwp_setregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs)
4807 {
4808 if (t->t_pshandle != NULL) {
4809 return (ptl_err(Plwp_setregs(t->t_pshandle,
4810 (lwpid_t)tid, gregs)));
4811 }
4812 return (set_errno(EMDB_NOPROC));
4813 }
4814
4815
4816 /*ARGSUSED*/
4817 static int
4818 pt_lwp_getxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prxregset_t **xregs,
4819 size_t *sizep)
4820 {
4821 if (t->t_pshandle != NULL) {
4822 return (ptl_err(Plwp_getxregs(t->t_pshandle,
4823 (lwpid_t)tid, xregs, sizep)));
4824 }
4825 return (set_errno(EMDB_NOPROC));
4826 }
4827
4828 static void
4829 pt_lwp_freexregs(mdb_tgt_t *t, void *tap, prxregset_t *xregs, size_t size)
4830 {
4831 if (t->t_pshandle != NULL) {
4832 Plwp_freexregs(t->t_pshandle, xregs, size);
4833 }
4834 }
4835
4836 static int
4837 pt_lwp_setxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
4838 const prxregset_t *xregs, size_t len)
4839 {
4840 if (t->t_pshandle != NULL) {
4841 return (ptl_err(Plwp_setxregs(t->t_pshandle,
4842 (lwpid_t)tid, xregs, len)));
4843 }
4844 return (set_errno(EMDB_NOPROC));
4845 }
4846
4847 /*ARGSUSED*/
4848 static int
4849 pt_lwp_getfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
4850 prfpregset_t *fpregs)
4851 {
4852 if (t->t_pshandle != NULL) {
4853 return (ptl_err(Plwp_getfpregs(t->t_pshandle,
4854 (lwpid_t)tid, fpregs)));
4855 }
4856 return (set_errno(EMDB_NOPROC));
4857 }
4858
4859 /*ARGSUSED*/
4860 static int
4861 pt_lwp_setfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
4862 const prfpregset_t *fpregs)
4863 {
4864 if (t->t_pshandle != NULL) {
4865 return (ptl_err(Plwp_setfpregs(t->t_pshandle,
4866 (lwpid_t)tid, fpregs)));
4867 }
4868 return (set_errno(EMDB_NOPROC));
4869 }
4870
4871 static const pt_ptl_ops_t proc_lwp_ops = {
4872 .ptl_ctor = (int (*)())(uintptr_t)mdb_tgt_nop,
4873 .ptl_dtor = (void (*)())(uintptr_t)mdb_tgt_nop,
4874 .ptl_tid = pt_lwp_tid,
4875 .ptl_iter = pt_lwp_iter,
4876 .ptl_getregs = pt_lwp_getregs,
4877 .ptl_setregs = pt_lwp_setregs,
4878 .ptl_getxregs = pt_lwp_getxregs,
4879 .ptl_freexregs = pt_lwp_freexregs,
4880 .ptl_setxregs = pt_lwp_setxregs,
4881 .ptl_getfpregs = pt_lwp_getfpregs,
4882 .ptl_setfpregs = pt_lwp_setfpregs
4883 };
4884
4885 static int
4886 pt_tdb_ctor(mdb_tgt_t *t)
4887 {
4888 pt_data_t *pt = t->t_data;
4889 td_thragent_t *tap;
4890 td_err_e err;
4891
4892 if ((err = pt->p_tdb_ops->td_ta_new(t->t_pshandle, &tap)) != TD_OK)
4893 return (set_errno(tdb_to_errno(err)));
4894
4895 pt->p_ptl_hdl = tap;
4896 return (0);
4897 }
4898
4899 static void
4900 pt_tdb_dtor(mdb_tgt_t *t, void *tap)
4901 {
4902 pt_data_t *pt = t->t_data;
4986 pt_tdb_setregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs)
4987 {
4988 pt_data_t *pt = t->t_data;
4989
4990 td_thrhandle_t th;
4991 td_err_e err;
4992
4993 if (t->t_pshandle == NULL)
4994 return (set_errno(EMDB_NOPROC));
4995
4996 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
4997 return (set_errno(tdb_to_errno(err)));
4998
4999 err = pt->p_tdb_ops->td_thr_setgregs(&th, gregs);
5000 if (err != TD_OK && err != TD_PARTIALREG)
5001 return (set_errno(tdb_to_errno(err)));
5002
5003 return (0);
5004 }
5005
5006 static int
5007 pt_tdb_getxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prxregset_t **xregs,
5008 size_t *sizep)
5009 {
5010 pt_data_t *pt = t->t_data;
5011
5012 td_thrhandle_t th;
5013 td_err_e err;
5014 int xregsize;
5015 prxregset_t *pxr;
5016
5017 if (t->t_pshandle == NULL)
5018 return (set_errno(EMDB_NOPROC));
5019
5020 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5021 return (set_errno(tdb_to_errno(err)));
5022
5023 if ((err = pt->p_tdb_ops->td_thr_getxregsize(&th, &xregsize)) != TD_OK)
5024 return (set_errno(tdb_to_errno(err)));
5025
5026 if (xregsize == 0) {
5027 return (set_errno(ENODATA));
5028 }
5029
5030 pxr = mdb_alloc(xregsize, UM_SLEEP);
5031
5032 err = pt->p_tdb_ops->td_thr_getxregs(&th, pxr);
5033 if (err != TD_OK && err != TD_PARTIALREG) {
5034 mdb_free(pxr, xregsize);
5035 return (set_errno(tdb_to_errno(err)));
5036 }
5037
5038 *xregs = pxr;
5039 *sizep = xregsize;
5040 return (0);
5041 }
5042
5043 static void
5044 pt_tdb_freexregs(mdb_tgt_t *t __unused, void *tap __unused, prxregset_t *pxr,
5045 size_t size)
5046 {
5047 mdb_free(pxr, size);
5048 }
5049
5050 static int
5051 pt_tdb_setxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
5052 const prxregset_t *xregs, size_t len __unused)
5053 {
5054 pt_data_t *pt = t->t_data;
5055
5056 td_thrhandle_t th;
5057 td_err_e err;
5058
5059 if (t->t_pshandle == NULL)
5060 return (set_errno(EMDB_NOPROC));
5061
5062 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5063 return (set_errno(tdb_to_errno(err)));
5064
5065 err = pt->p_tdb_ops->td_thr_setxregs(&th, xregs);
5066 if (err != TD_OK && err != TD_PARTIALREG)
5067 return (set_errno(tdb_to_errno(err)));
5068
5069 return (0);
5070 }
5071
5072 static int
5073 pt_tdb_getfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
5074 prfpregset_t *fpregs)
5075 {
5076 pt_data_t *pt = t->t_data;
5077
5078 td_thrhandle_t th;
5079 td_err_e err;
5080
5081 if (t->t_pshandle == NULL)
5082 return (set_errno(EMDB_NOPROC));
5083
5084 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5085 return (set_errno(tdb_to_errno(err)));
5086
5087 err = pt->p_tdb_ops->td_thr_getfpregs(&th, fpregs);
5088 if (err != TD_OK && err != TD_PARTIALREG)
5089 return (set_errno(tdb_to_errno(err)));
5090
5091 return (0);
5097 {
5098 pt_data_t *pt = t->t_data;
5099
5100 td_thrhandle_t th;
5101 td_err_e err;
5102
5103 if (t->t_pshandle == NULL)
5104 return (set_errno(EMDB_NOPROC));
5105
5106 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK)
5107 return (set_errno(tdb_to_errno(err)));
5108
5109 err = pt->p_tdb_ops->td_thr_setfpregs(&th, fpregs);
5110 if (err != TD_OK && err != TD_PARTIALREG)
5111 return (set_errno(tdb_to_errno(err)));
5112
5113 return (0);
5114 }
5115
5116 static const pt_ptl_ops_t proc_tdb_ops = {
5117 .ptl_ctor = pt_tdb_ctor,
5118 .ptl_dtor = pt_tdb_dtor,
5119 .ptl_tid = pt_tdb_tid,
5120 .ptl_iter = pt_tdb_iter,
5121 .ptl_getregs = pt_tdb_getregs,
5122 .ptl_setregs = pt_tdb_setregs,
5123 .ptl_getxregs = pt_tdb_getxregs,
5124 .ptl_freexregs = pt_tdb_freexregs,
5125 .ptl_setxregs = pt_tdb_setxregs,
5126 .ptl_getfpregs = pt_tdb_getfpregs,
5127 .ptl_setfpregs = pt_tdb_setfpregs
5128 };
5129
5130 static ssize_t
5131 pt_xd_auxv(mdb_tgt_t *t, void *buf, size_t nbytes)
5132 {
5133 struct ps_prochandle *P = t->t_pshandle;
5134 const auxv_t *auxp, *auxv = NULL;
5135 int auxn = 0;
5136
5137 if (P != NULL && (auxv = Pgetauxvec(P)) != NULL &&
5138 auxv->a_type != AT_NULL) {
5139 for (auxp = auxv, auxn = 1; auxp->a_type != 0; auxp++)
5140 auxn++;
5141 }
5142
5143 if (buf == NULL && nbytes == 0)
5144 return (sizeof (auxv_t) * auxn);
5145
5146 if (auxn == 0)
5147 return (set_errno(ENODATA));
|