169a119caSChristopher Siden /*
269a119caSChristopher Siden  * This file and its contents are supplied under the terms of the
369a119caSChristopher Siden  * Common Development and Distribution License ("CDDL"), version 1.0.
469a119caSChristopher Siden  * You may only use this file in accordance with the terms of version
569a119caSChristopher Siden  * 1.0 of the CDDL.
669a119caSChristopher Siden  *
769a119caSChristopher Siden  * A full copy of the text of the CDDL should have accompanied this
869a119caSChristopher Siden  * source.  A copy of the CDDL is also available via the Internet at
969a119caSChristopher Siden  * http://www.illumos.org/license/CDDL.
1069a119caSChristopher Siden  */
1169a119caSChristopher Siden /*
1269a119caSChristopher Siden  * Copyright (c) 2013 by Delphix. All rights reserved.
13*4c28a617SRobert Mustacchi  * Copyright (c) 2018, Joyent, Inc.
1469a119caSChristopher Siden  */
1569a119caSChristopher Siden 
1669a119caSChristopher Siden #include <mdb/mdb_modapi.h>
1769a119caSChristopher Siden #include <mdb/mdb_gcore.h>
1869a119caSChristopher Siden #include <mdb/mdb_debug.h>
1969a119caSChristopher Siden 
2069a119caSChristopher Siden #include <sys/psw.h>
2169a119caSChristopher Siden #include <sys/privregs.h>
2269a119caSChristopher Siden 
2369a119caSChristopher Siden uintptr_t
gcore_prgetstackbase(mdb_proc_t * p)2469a119caSChristopher Siden gcore_prgetstackbase(mdb_proc_t *p)
2569a119caSChristopher Siden {
2669a119caSChristopher Siden 	return (p->p_usrstack - p->p_stksize);
2769a119caSChristopher Siden }
2869a119caSChristopher Siden 
2969a119caSChristopher Siden int
gcore_prfetchinstr(mdb_klwp_t * lwp,ulong_t * ip)3069a119caSChristopher Siden gcore_prfetchinstr(mdb_klwp_t *lwp, ulong_t *ip)
3169a119caSChristopher Siden {
3269a119caSChristopher Siden 	*ip = (ulong_t)(instr_t)lwp->lwp_pcb.pcb_instr;
3369a119caSChristopher Siden 	return (lwp->lwp_pcb.pcb_flags & INSTR_VALID);
3469a119caSChristopher Siden }
3569a119caSChristopher Siden 
3669a119caSChristopher Siden int
gcore_prisstep(mdb_klwp_t * lwp)3769a119caSChristopher Siden gcore_prisstep(mdb_klwp_t *lwp)
3869a119caSChristopher Siden {
3969a119caSChristopher Siden 	return ((lwp->lwp_pcb.pcb_flags &
4069a119caSChristopher Siden 	    (NORMAL_STEP|WATCH_STEP|DEBUG_PENDING)) != 0);
4169a119caSChristopher Siden }
4269a119caSChristopher Siden 
4369a119caSChristopher Siden void
gcore_getgregs(mdb_klwp_t * lwp,gregset_t grp)4469a119caSChristopher Siden gcore_getgregs(mdb_klwp_t *lwp, gregset_t grp)
4569a119caSChristopher Siden {
4669a119caSChristopher Siden 	struct regs rgs;
4769a119caSChristopher Siden 	struct regs *rp;
4869a119caSChristopher Siden 
4969a119caSChristopher Siden 	if (mdb_vread(&rgs, sizeof (rgs), lwp->lwp_regs) != sizeof (rgs)) {
5069a119caSChristopher Siden 		mdb_warn("Failed to read regs from %p\n", lwp->lwp_regs);
5169a119caSChristopher Siden 		return;
5269a119caSChristopher Siden 	}
5369a119caSChristopher Siden 	rp = &rgs;
5469a119caSChristopher Siden 
5569a119caSChristopher Siden #if defined(__amd64)
5669a119caSChristopher Siden 	struct pcb *pcb = &lwp->lwp_pcb;
5769a119caSChristopher Siden 
5869a119caSChristopher Siden 	grp[REG_RDI] = rp->r_rdi;
5969a119caSChristopher Siden 	grp[REG_RSI] = rp->r_rsi;
6069a119caSChristopher Siden 	grp[REG_RDX] = rp->r_rdx;
6169a119caSChristopher Siden 	grp[REG_RCX] = rp->r_rcx;
6269a119caSChristopher Siden 	grp[REG_R8] = rp->r_r8;
6369a119caSChristopher Siden 	grp[REG_R9] = rp->r_r9;
6469a119caSChristopher Siden 	grp[REG_RAX] = rp->r_rax;
6569a119caSChristopher Siden 	grp[REG_RBX] = rp->r_rbx;
6669a119caSChristopher Siden 	grp[REG_RBP] = rp->r_rbp;
6769a119caSChristopher Siden 	grp[REG_R10] = rp->r_r10;
6869a119caSChristopher Siden 	grp[REG_R11] = rp->r_r11;
6969a119caSChristopher Siden 	grp[REG_R12] = rp->r_r12;
7069a119caSChristopher Siden 	grp[REG_R13] = rp->r_r13;
7169a119caSChristopher Siden 	grp[REG_R14] = rp->r_r14;
7269a119caSChristopher Siden 	grp[REG_R15] = rp->r_r15;
7369a119caSChristopher Siden 	grp[REG_FSBASE] = pcb->pcb_fsbase;
7469a119caSChristopher Siden 	grp[REG_GSBASE] = pcb->pcb_gsbase;
75*4c28a617SRobert Mustacchi 	if (PCB_NEED_UPDATE_SEGS(pcb)) {
7669a119caSChristopher Siden 		grp[REG_DS] = pcb->pcb_ds;
7769a119caSChristopher Siden 		grp[REG_ES] = pcb->pcb_es;
7869a119caSChristopher Siden 		grp[REG_FS] = pcb->pcb_fs;
7969a119caSChristopher Siden 		grp[REG_GS] = pcb->pcb_gs;
8069a119caSChristopher Siden 	} else {
8169a119caSChristopher Siden 		grp[REG_DS] = rp->r_ds;
8269a119caSChristopher Siden 		grp[REG_ES] = rp->r_es;
8369a119caSChristopher Siden 		grp[REG_FS] = rp->r_fs;
8469a119caSChristopher Siden 		grp[REG_GS] = rp->r_gs;
8569a119caSChristopher Siden 	}
8669a119caSChristopher Siden 	grp[REG_TRAPNO] = rp->r_trapno;
8769a119caSChristopher Siden 	grp[REG_ERR] = rp->r_err;
8869a119caSChristopher Siden 	grp[REG_RIP] = rp->r_rip;
8969a119caSChristopher Siden 	grp[REG_CS] = rp->r_cs;
9069a119caSChristopher Siden 	grp[REG_SS] = rp->r_ss;
9169a119caSChristopher Siden 	grp[REG_RFL] = rp->r_rfl;
9269a119caSChristopher Siden 	grp[REG_RSP] = rp->r_rsp;
9369a119caSChristopher Siden #else
9469a119caSChristopher Siden 	bcopy(&rp->r_gs, grp, sizeof (gregset_t));
9569a119caSChristopher Siden #endif
9669a119caSChristopher Siden }
9769a119caSChristopher Siden 
9869a119caSChristopher Siden int
gcore_prgetrvals(mdb_klwp_t * lwp,long * rval1,long * rval2)9969a119caSChristopher Siden gcore_prgetrvals(mdb_klwp_t *lwp, long *rval1, long *rval2)
10069a119caSChristopher Siden {
10169a119caSChristopher Siden 	struct regs *r = lwptoregs(lwp);
10269a119caSChristopher Siden 
10369a119caSChristopher Siden 	if (r->r_ps & PS_C)
10469a119caSChristopher Siden 		return (r->r_r0);
10569a119caSChristopher Siden 	if (lwp->lwp_eosys == JUSTRETURN) {
10669a119caSChristopher Siden 		*rval1 = 0;
10769a119caSChristopher Siden 		*rval2 = 0;
10869a119caSChristopher Siden 	} else {
10969a119caSChristopher Siden 		*rval1 = r->r_r0;
11069a119caSChristopher Siden 		*rval2 = r->r_r1;
11169a119caSChristopher Siden 	}
11269a119caSChristopher Siden 	return (0);
11369a119caSChristopher Siden }
114