1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11 /*
12 * Copyright (c) 2013 by Delphix. All rights reserved.
13 * Copyright (c) 2018, Joyent, Inc.
14 */
15
16 #include <mdb/mdb_modapi.h>
17 #include <mdb/mdb_gcore.h>
18 #include <mdb/mdb_debug.h>
19
20 #include <sys/psw.h>
21 #include <sys/privregs.h>
22
23 uintptr_t
gcore_prgetstackbase(mdb_proc_t * p)24 gcore_prgetstackbase(mdb_proc_t *p)
25 {
26 return (p->p_usrstack - p->p_stksize);
27 }
28
29 int
gcore_prfetchinstr(mdb_klwp_t * lwp,ulong_t * ip)30 gcore_prfetchinstr(mdb_klwp_t *lwp, ulong_t *ip)
31 {
32 *ip = (ulong_t)(instr_t)lwp->lwp_pcb.pcb_instr;
33 return (lwp->lwp_pcb.pcb_flags & INSTR_VALID);
34 }
35
36 int
gcore_prisstep(mdb_klwp_t * lwp)37 gcore_prisstep(mdb_klwp_t *lwp)
38 {
39 return ((lwp->lwp_pcb.pcb_flags &
40 (NORMAL_STEP|WATCH_STEP|DEBUG_PENDING)) != 0);
41 }
42
43 void
gcore_getgregs(mdb_klwp_t * lwp,gregset_t grp)44 gcore_getgregs(mdb_klwp_t *lwp, gregset_t grp)
45 {
46 struct regs rgs;
47 struct regs *rp;
48
49 if (mdb_vread(&rgs, sizeof (rgs), lwp->lwp_regs) != sizeof (rgs)) {
50 mdb_warn("Failed to read regs from %p\n", lwp->lwp_regs);
51 return;
52 }
53 rp = &rgs;
54
55 #if defined(__amd64)
56 struct pcb *pcb = &lwp->lwp_pcb;
57
58 grp[REG_RDI] = rp->r_rdi;
59 grp[REG_RSI] = rp->r_rsi;
60 grp[REG_RDX] = rp->r_rdx;
61 grp[REG_RCX] = rp->r_rcx;
62 grp[REG_R8] = rp->r_r8;
63 grp[REG_R9] = rp->r_r9;
64 grp[REG_RAX] = rp->r_rax;
65 grp[REG_RBX] = rp->r_rbx;
66 grp[REG_RBP] = rp->r_rbp;
67 grp[REG_R10] = rp->r_r10;
68 grp[REG_R11] = rp->r_r11;
69 grp[REG_R12] = rp->r_r12;
70 grp[REG_R13] = rp->r_r13;
71 grp[REG_R14] = rp->r_r14;
72 grp[REG_R15] = rp->r_r15;
73 grp[REG_FSBASE] = pcb->pcb_fsbase;
74 grp[REG_GSBASE] = pcb->pcb_gsbase;
75 if (PCB_NEED_UPDATE_SEGS(pcb)) {
76 grp[REG_DS] = pcb->pcb_ds;
77 grp[REG_ES] = pcb->pcb_es;
78 grp[REG_FS] = pcb->pcb_fs;
79 grp[REG_GS] = pcb->pcb_gs;
80 } else {
81 grp[REG_DS] = rp->r_ds;
82 grp[REG_ES] = rp->r_es;
83 grp[REG_FS] = rp->r_fs;
84 grp[REG_GS] = rp->r_gs;
85 }
86 grp[REG_TRAPNO] = rp->r_trapno;
87 grp[REG_ERR] = rp->r_err;
88 grp[REG_RIP] = rp->r_rip;
89 grp[REG_CS] = rp->r_cs;
90 grp[REG_SS] = rp->r_ss;
91 grp[REG_RFL] = rp->r_rfl;
92 grp[REG_RSP] = rp->r_rsp;
93 #else
94 bcopy(&rp->r_gs, grp, sizeof (gregset_t));
95 #endif
96 }
97
98 int
gcore_prgetrvals(mdb_klwp_t * lwp,long * rval1,long * rval2)99 gcore_prgetrvals(mdb_klwp_t *lwp, long *rval1, long *rval2)
100 {
101 struct regs *r = lwptoregs(lwp);
102
103 if (r->r_ps & PS_C)
104 return (r->r_r0);
105 if (lwp->lwp_eosys == JUSTRETURN) {
106 *rval1 = 0;
107 *rval2 = 0;
108 } else {
109 *rval1 = r->r_r0;
110 *rval2 = r->r_r1;
111 }
112 return (0);
113 }
114