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  */
  14 
  15 #include <mdb/mdb_modapi.h>
  16 #include <mdb/mdb_gcore.h>
  17 #include <mdb/mdb_debug.h>
  18 
  19 #include <sys/psw.h>
  20 #include <sys/privregs.h>
  21 
  22 uintptr_t
  23 gcore_prgetstackbase(mdb_proc_t *p)
  24 {
  25         return (p->p_usrstack - p->p_stksize);
  26 }
  27 
  28 int
  29 gcore_prfetchinstr(mdb_klwp_t *lwp, ulong_t *ip)
  30 {
  31         *ip = (ulong_t)(instr_t)lwp->lwp_pcb.pcb_instr;
  32         return (lwp->lwp_pcb.pcb_flags & INSTR_VALID);
  33 }
  34 
  35 int
  36 gcore_prisstep(mdb_klwp_t *lwp)
  37 {
  38         return ((lwp->lwp_pcb.pcb_flags &
  39             (NORMAL_STEP|WATCH_STEP|DEBUG_PENDING)) != 0);
  40 }
  41 
  42 void
  43 gcore_getgregs(mdb_klwp_t *lwp, gregset_t grp)
  44 {
  45         struct regs rgs;
  46         struct regs *rp;
  47 
  48         if (mdb_vread(&rgs, sizeof (rgs), lwp->lwp_regs) != sizeof (rgs)) {
  49                 mdb_warn("Failed to read regs from %p\n", lwp->lwp_regs);
  50                 return;
  51         }
  52         rp = &rgs;
  53 
  54 #if defined(__amd64)
  55         struct pcb *pcb = &lwp->lwp_pcb;
  56 
  57         grp[REG_RDI] = rp->r_rdi;
  58         grp[REG_RSI] = rp->r_rsi;
  59         grp[REG_RDX] = rp->r_rdx;
  60         grp[REG_RCX] = rp->r_rcx;
  61         grp[REG_R8] = rp->r_r8;
  62         grp[REG_R9] = rp->r_r9;
  63         grp[REG_RAX] = rp->r_rax;
  64         grp[REG_RBX] = rp->r_rbx;
  65         grp[REG_RBP] = rp->r_rbp;
  66         grp[REG_R10] = rp->r_r10;
  67         grp[REG_R11] = rp->r_r11;
  68         grp[REG_R12] = rp->r_r12;
  69         grp[REG_R13] = rp->r_r13;
  70         grp[REG_R14] = rp->r_r14;
  71         grp[REG_R15] = rp->r_r15;
  72         grp[REG_FSBASE] = pcb->pcb_fsbase;
  73         grp[REG_GSBASE] = pcb->pcb_gsbase;
  74         if (pcb->pcb_rupdate == 1) {
  75                 grp[REG_DS] = pcb->pcb_ds;
  76                 grp[REG_ES] = pcb->pcb_es;
  77                 grp[REG_FS] = pcb->pcb_fs;
  78                 grp[REG_GS] = pcb->pcb_gs;
  79         } else {
  80                 grp[REG_DS] = rp->r_ds;
  81                 grp[REG_ES] = rp->r_es;
  82                 grp[REG_FS] = rp->r_fs;
  83                 grp[REG_GS] = rp->r_gs;
  84         }
  85         grp[REG_TRAPNO] = rp->r_trapno;
  86         grp[REG_ERR] = rp->r_err;
  87         grp[REG_RIP] = rp->r_rip;
  88         grp[REG_CS] = rp->r_cs;
  89         grp[REG_SS] = rp->r_ss;
  90         grp[REG_RFL] = rp->r_rfl;
  91         grp[REG_RSP] = rp->r_rsp;
  92 #else
  93         bcopy(&rp->r_gs, grp, sizeof (gregset_t));
  94 #endif
  95 }
  96 
  97 int
  98 gcore_prgetrvals(mdb_klwp_t *lwp, long *rval1, long *rval2)
  99 {
 100         struct regs *r = lwptoregs(lwp);
 101 
 102         if (r->r_ps & PS_C)
 103                 return (r->r_r0);
 104         if (lwp->lwp_eosys == JUSTRETURN) {
 105                 *rval1 = 0;
 106                 *rval2 = 0;
 107         } else {
 108                 *rval1 = r->r_r0;
 109                 *rval2 = r->r_r1;
 110         }
 111         return (0);
 112 }