1*265Smws /* 2*265Smws * CDDL HEADER START 3*265Smws * 4*265Smws * The contents of this file are subject to the terms of the 5*265Smws * Common Development and Distribution License, Version 1.0 only 6*265Smws * (the "License"). You may not use this file except in compliance 7*265Smws * with the License. 8*265Smws * 9*265Smws * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*265Smws * or http://www.opensolaris.org/os/licensing. 11*265Smws * See the License for the specific language governing permissions 12*265Smws * and limitations under the License. 13*265Smws * 14*265Smws * When distributing Covered Code, include this CDDL HEADER in each 15*265Smws * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*265Smws * If applicable, add the following below this CDDL HEADER, with the 17*265Smws * fields enclosed by brackets "[]" replaced with your own identifying 18*265Smws * information: Portions Copyright [yyyy] [name of copyright owner] 19*265Smws * 20*265Smws * CDDL HEADER END 21*265Smws */ 22*265Smws /* 23*265Smws * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*265Smws * Use is subject to license terms. 25*265Smws */ 26*265Smws 27*265Smws #pragma ident "%Z%%M% %I% %E% SMI" 28*265Smws 29*265Smws #include <mdb/mdb_modapi.h> 30*265Smws #include <dtrace.h> 31*265Smws 32*265Smws #ifdef _LP64 33*265Smws #define DIFO_ADDRWIDTH 11 34*265Smws #else 35*265Smws #define DIFO_ADDRWIDTH 8 36*265Smws #endif 37*265Smws 38*265Smws extern int dof_sec(uintptr_t, uint_t, int, const mdb_arg_t *); 39*265Smws extern const char *dof_sec_name(uint32_t); 40*265Smws 41*265Smws extern const mdb_walker_t kernel_walkers[]; 42*265Smws extern const mdb_dcmd_t kernel_dcmds[]; 43*265Smws 44*265Smws /*ARGSUSED*/ 45*265Smws static void 46*265Smws dis_log(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 47*265Smws { 48*265Smws mdb_printf("%-4s %%r%u, %%r%u, %%r%u", name, 49*265Smws DIF_INSTR_R1(instr), DIF_INSTR_R2(instr), DIF_INSTR_RD(instr)); 50*265Smws } 51*265Smws 52*265Smws /*ARGSUSED*/ 53*265Smws static void 54*265Smws dis_branch(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 55*265Smws { 56*265Smws mdb_printf("%-4s %u", name, DIF_INSTR_LABEL(instr)); 57*265Smws } 58*265Smws 59*265Smws /*ARGSUSED*/ 60*265Smws static void 61*265Smws dis_load(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 62*265Smws { 63*265Smws mdb_printf("%-4s [%%r%u], %%r%u", name, 64*265Smws DIF_INSTR_R1(instr), DIF_INSTR_RD(instr)); 65*265Smws } 66*265Smws 67*265Smws /*ARGSUSED*/ 68*265Smws static void 69*265Smws dis_store(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 70*265Smws { 71*265Smws mdb_printf("%-4s %%r%u, [%%r%u]", name, 72*265Smws DIF_INSTR_R1(instr), DIF_INSTR_RD(instr)); 73*265Smws } 74*265Smws 75*265Smws /*ARGSUSED*/ 76*265Smws static void 77*265Smws dis_str(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 78*265Smws { 79*265Smws mdb_printf("%s", name); 80*265Smws } 81*265Smws 82*265Smws /*ARGSUSED*/ 83*265Smws static void 84*265Smws dis_r1rd(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 85*265Smws { 86*265Smws mdb_printf("%-4s %%r%u, %%r%u", name, 87*265Smws DIF_INSTR_R1(instr), DIF_INSTR_RD(instr)); 88*265Smws } 89*265Smws 90*265Smws /*ARGSUSED*/ 91*265Smws static void 92*265Smws dis_cmp(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 93*265Smws { 94*265Smws mdb_printf("%-4s %%r%u, %%r%u", name, 95*265Smws DIF_INSTR_R1(instr), DIF_INSTR_R2(instr)); 96*265Smws } 97*265Smws 98*265Smws /*ARGSUSED*/ 99*265Smws static void 100*265Smws dis_tst(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 101*265Smws { 102*265Smws mdb_printf("%-4s %%r%u", name, DIF_INSTR_R1(instr)); 103*265Smws } 104*265Smws 105*265Smws static const char * 106*265Smws dis_varname(const dtrace_difo_t *dp, uint_t id, uint_t scope) 107*265Smws { 108*265Smws dtrace_difv_t *dvp; 109*265Smws size_t varsize; 110*265Smws caddr_t addr = NULL, str; 111*265Smws uint_t i; 112*265Smws 113*265Smws if (dp == NULL) 114*265Smws return (NULL); 115*265Smws 116*265Smws varsize = sizeof (dtrace_difv_t) * dp->dtdo_varlen; 117*265Smws dvp = mdb_alloc(varsize, UM_SLEEP); 118*265Smws 119*265Smws if (mdb_vread(dvp, varsize, (uintptr_t)dp->dtdo_vartab) == -1) { 120*265Smws mdb_free(dvp, varsize); 121*265Smws return ("<unreadable>"); 122*265Smws } 123*265Smws 124*265Smws for (i = 0; i < dp->dtdo_varlen; i++) { 125*265Smws if (dvp[i].dtdv_id == id && dvp[i].dtdv_scope == scope) { 126*265Smws if (dvp[i].dtdv_name < dp->dtdo_strlen) 127*265Smws addr = dp->dtdo_strtab + dvp[i].dtdv_name; 128*265Smws break; 129*265Smws } 130*265Smws } 131*265Smws 132*265Smws mdb_free(dvp, varsize); 133*265Smws 134*265Smws if (addr == NULL) 135*265Smws return (NULL); 136*265Smws 137*265Smws str = mdb_zalloc(dp->dtdo_strlen + 1, UM_SLEEP | UM_GC); 138*265Smws 139*265Smws for (i = 0; i == 0 || str[i - 1] != '\0'; i++, addr++) { 140*265Smws if (mdb_vread(&str[i], sizeof (char), (uintptr_t)addr) == -1) 141*265Smws return ("<unreadable>"); 142*265Smws } 143*265Smws 144*265Smws return (str); 145*265Smws } 146*265Smws 147*265Smws static uint_t 148*265Smws dis_scope(const char *name) 149*265Smws { 150*265Smws switch (name[2]) { 151*265Smws case 'l': return (DIFV_SCOPE_LOCAL); 152*265Smws case 't': return (DIFV_SCOPE_THREAD); 153*265Smws case 'g': return (DIFV_SCOPE_GLOBAL); 154*265Smws default: return (-1u); 155*265Smws } 156*265Smws } 157*265Smws 158*265Smws static void 159*265Smws dis_lda(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 160*265Smws { 161*265Smws uint_t var = DIF_INSTR_R1(instr); 162*265Smws const char *vname; 163*265Smws 164*265Smws mdb_printf("%-4s DIF_VAR(%x), %%r%u, %%r%u", name, 165*265Smws var, DIF_INSTR_R2(instr), DIF_INSTR_RD(instr)); 166*265Smws 167*265Smws if ((vname = dis_varname(dp, var, dis_scope(name))) != NULL) 168*265Smws mdb_printf("\t\t! %s", vname); 169*265Smws } 170*265Smws 171*265Smws static void 172*265Smws dis_ldv(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 173*265Smws { 174*265Smws uint_t var = DIF_INSTR_VAR(instr); 175*265Smws const char *vname; 176*265Smws 177*265Smws mdb_printf("%-4s DIF_VAR(%x), %%r%u", name, var, DIF_INSTR_RD(instr)); 178*265Smws 179*265Smws if ((vname = dis_varname(dp, var, dis_scope(name))) != NULL) 180*265Smws mdb_printf("\t\t! %s", vname); 181*265Smws } 182*265Smws 183*265Smws static void 184*265Smws dis_stv(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 185*265Smws { 186*265Smws uint_t var = DIF_INSTR_VAR(instr); 187*265Smws const char *vname; 188*265Smws 189*265Smws mdb_printf("%-4s %%r%u, DIF_VAR(%x)", name, DIF_INSTR_RS(instr), var); 190*265Smws 191*265Smws if ((vname = dis_varname(dp, var, dis_scope(name))) != NULL) 192*265Smws mdb_printf("\t\t! %s", vname); 193*265Smws } 194*265Smws 195*265Smws static void 196*265Smws dis_setx(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 197*265Smws { 198*265Smws uint_t intptr = DIF_INSTR_INTEGER(instr); 199*265Smws 200*265Smws mdb_printf("%-4s DIF_INTEGER[%u], %%r%u", name, 201*265Smws intptr, DIF_INSTR_RD(instr)); 202*265Smws 203*265Smws if (dp != NULL && intptr < dp->dtdo_intlen) { 204*265Smws uint64_t *ip = mdb_alloc(dp->dtdo_intlen * 205*265Smws sizeof (uint64_t), UM_SLEEP | UM_GC); 206*265Smws 207*265Smws if (mdb_vread(ip, dp->dtdo_intlen * sizeof (uint64_t), 208*265Smws (uintptr_t)dp->dtdo_inttab) == -1) 209*265Smws mdb_warn("failed to read data at %p", dp->dtdo_inttab); 210*265Smws else 211*265Smws mdb_printf("\t\t! 0x%llx", ip[intptr]); 212*265Smws } 213*265Smws } 214*265Smws 215*265Smws static void 216*265Smws dis_sets(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 217*265Smws { 218*265Smws uint_t strptr = DIF_INSTR_STRING(instr); 219*265Smws 220*265Smws mdb_printf("%-4s DIF_STRING[%u], %%r%u", name, 221*265Smws strptr, DIF_INSTR_RD(instr)); 222*265Smws 223*265Smws if (dp != NULL && strptr < dp->dtdo_strlen) { 224*265Smws char *str = mdb_alloc(dp->dtdo_strlen, UM_SLEEP | UM_GC); 225*265Smws 226*265Smws if (mdb_vread(str, dp->dtdo_strlen, 227*265Smws (uintptr_t)dp->dtdo_strtab) == -1) 228*265Smws mdb_warn("failed to read data at %p", dp->dtdo_strtab); 229*265Smws else 230*265Smws mdb_printf("\t\t! \"%s\"", str + strptr); 231*265Smws } 232*265Smws } 233*265Smws 234*265Smws /*ARGSUSED*/ 235*265Smws static void 236*265Smws dis_ret(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 237*265Smws { 238*265Smws mdb_printf("%-4s %%r%u", name, DIF_INSTR_RD(instr)); 239*265Smws } 240*265Smws 241*265Smws /*ARGSUSED*/ 242*265Smws static void 243*265Smws dis_call(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 244*265Smws { 245*265Smws uint_t subr = DIF_INSTR_SUBR(instr); 246*265Smws 247*265Smws mdb_printf("%-4s DIF_SUBR(%u), %%r%u\t\t! %s", 248*265Smws name, subr, DIF_INSTR_RD(instr), dtrace_subrstr(NULL, subr)); 249*265Smws } 250*265Smws 251*265Smws /*ARGSUSED*/ 252*265Smws static void 253*265Smws dis_pushts(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 254*265Smws { 255*265Smws static const char *const tnames[] = { "TYPE_CTF", "TYPE_STRING" }; 256*265Smws uint_t type = DIF_INSTR_TYPE(instr); 257*265Smws 258*265Smws mdb_printf("%-4s DIF_TYPE(%u), %%r%u, %%r%u", 259*265Smws name, type, DIF_INSTR_R2(instr), DIF_INSTR_RS(instr)); 260*265Smws 261*265Smws if (type < sizeof (tnames) / sizeof (tnames[0])) 262*265Smws mdb_printf("\t! %s", tnames[type]); 263*265Smws } 264*265Smws 265*265Smws /*ARGSUSED*/ 266*265Smws static void 267*265Smws dis_xlate(const dtrace_difo_t *dp, const char *name, dif_instr_t instr) 268*265Smws { 269*265Smws mdb_printf("%-4s DIF_XLREF[%u], %%r%u", name, 270*265Smws DIF_INSTR_XLREF(instr), DIF_INSTR_RD(instr)); 271*265Smws } 272*265Smws 273*265Smws static char * 274*265Smws dis_typestr(const dtrace_diftype_t *t, char *buf, size_t len) 275*265Smws { 276*265Smws char kind[8]; 277*265Smws 278*265Smws switch (t->dtdt_kind) { 279*265Smws case DIF_TYPE_CTF: 280*265Smws (void) strcpy(kind, "D type"); 281*265Smws break; 282*265Smws case DIF_TYPE_STRING: 283*265Smws (void) strcpy(kind, "string"); 284*265Smws break; 285*265Smws default: 286*265Smws (void) mdb_snprintf(kind, sizeof (kind), "0x%x", t->dtdt_kind); 287*265Smws } 288*265Smws 289*265Smws if (t->dtdt_flags & DIF_TF_BYREF) { 290*265Smws (void) mdb_snprintf(buf, len, 291*265Smws "%s by ref (size %lu)", 292*265Smws kind, (ulong_t)t->dtdt_size); 293*265Smws } else { 294*265Smws (void) mdb_snprintf(buf, len, "%s (size %lu)", 295*265Smws kind, (ulong_t)t->dtdt_size); 296*265Smws } 297*265Smws 298*265Smws return (buf); 299*265Smws } 300*265Smws 301*265Smws static int 302*265Smws dis(uintptr_t addr, dtrace_difo_t *dp) 303*265Smws { 304*265Smws static const struct opent { 305*265Smws const char *op_name; 306*265Smws void (*op_func)(const dtrace_difo_t *, 307*265Smws const char *, dif_instr_t); 308*265Smws } optab[] = { 309*265Smws { "(illegal opcode)", dis_str }, 310*265Smws { "or", dis_log }, /* DIF_OP_OR */ 311*265Smws { "xor", dis_log }, /* DIF_OP_XOR */ 312*265Smws { "and", dis_log }, /* DIF_OP_AND */ 313*265Smws { "sll", dis_log }, /* DIF_OP_SLL */ 314*265Smws { "srl", dis_log }, /* DIF_OP_SRL */ 315*265Smws { "sub", dis_log }, /* DIF_OP_SUB */ 316*265Smws { "add", dis_log }, /* DIF_OP_ADD */ 317*265Smws { "mul", dis_log }, /* DIF_OP_MUL */ 318*265Smws { "sdiv", dis_log }, /* DIF_OP_SDIV */ 319*265Smws { "udiv", dis_log }, /* DIF_OP_UDIV */ 320*265Smws { "srem", dis_log }, /* DIF_OP_SREM */ 321*265Smws { "urem", dis_log }, /* DIF_OP_UREM */ 322*265Smws { "not", dis_r1rd }, /* DIF_OP_NOT */ 323*265Smws { "mov", dis_r1rd }, /* DIF_OP_MOV */ 324*265Smws { "cmp", dis_cmp }, /* DIF_OP_CMP */ 325*265Smws { "tst", dis_tst }, /* DIF_OP_TST */ 326*265Smws { "ba", dis_branch }, /* DIF_OP_BA */ 327*265Smws { "be", dis_branch }, /* DIF_OP_BE */ 328*265Smws { "bne", dis_branch }, /* DIF_OP_BNE */ 329*265Smws { "bg", dis_branch }, /* DIF_OP_BG */ 330*265Smws { "bgu", dis_branch }, /* DIF_OP_BGU */ 331*265Smws { "bge", dis_branch }, /* DIF_OP_BGE */ 332*265Smws { "bgeu", dis_branch }, /* DIF_OP_BGEU */ 333*265Smws { "bl", dis_branch }, /* DIF_OP_BL */ 334*265Smws { "blu", dis_branch }, /* DIF_OP_BLU */ 335*265Smws { "ble", dis_branch }, /* DIF_OP_BLE */ 336*265Smws { "bleu", dis_branch }, /* DIF_OP_BLEU */ 337*265Smws { "ldsb", dis_load }, /* DIF_OP_LDSB */ 338*265Smws { "ldsh", dis_load }, /* DIF_OP_LDSH */ 339*265Smws { "ldsw", dis_load }, /* DIF_OP_LDSW */ 340*265Smws { "ldub", dis_load }, /* DIF_OP_LDUB */ 341*265Smws { "lduh", dis_load }, /* DIF_OP_LDUH */ 342*265Smws { "lduw", dis_load }, /* DIF_OP_LDUW */ 343*265Smws { "ldx", dis_load }, /* DIF_OP_LDX */ 344*265Smws { "ret", dis_ret }, /* DIF_OP_RET */ 345*265Smws { "nop", dis_str }, /* DIF_OP_NOP */ 346*265Smws { "setx", dis_setx }, /* DIF_OP_SETX */ 347*265Smws { "sets", dis_sets }, /* DIF_OP_SETS */ 348*265Smws { "scmp", dis_cmp }, /* DIF_OP_SCMP */ 349*265Smws { "ldga", dis_lda }, /* DIF_OP_LDGA */ 350*265Smws { "ldgs", dis_ldv }, /* DIF_OP_LDGS */ 351*265Smws { "stgs", dis_stv }, /* DIF_OP_STGS */ 352*265Smws { "ldta", dis_lda }, /* DIF_OP_LDTA */ 353*265Smws { "ldts", dis_ldv }, /* DIF_OP_LDTS */ 354*265Smws { "stts", dis_stv }, /* DIF_OP_STTS */ 355*265Smws { "sra", dis_log }, /* DIF_OP_SRA */ 356*265Smws { "call", dis_call }, /* DIF_OP_CALL */ 357*265Smws { "pushtr", dis_pushts }, /* DIF_OP_PUSHTR */ 358*265Smws { "pushtv", dis_pushts }, /* DIF_OP_PUSHTV */ 359*265Smws { "popts", dis_str }, /* DIF_OP_POPTS */ 360*265Smws { "flushts", dis_str }, /* DIF_OP_FLUSHTS */ 361*265Smws { "ldgaa", dis_ldv }, /* DIF_OP_LDGAA */ 362*265Smws { "ldtaa", dis_ldv }, /* DIF_OP_LDTAA */ 363*265Smws { "stgaa", dis_stv }, /* DIF_OP_STGAA */ 364*265Smws { "sttaa", dis_stv }, /* DIF_OP_STTAA */ 365*265Smws { "ldls", dis_ldv }, /* DIF_OP_LDLS */ 366*265Smws { "stls", dis_stv }, /* DIF_OP_STLS */ 367*265Smws { "allocs", dis_r1rd }, /* DIF_OP_ALLOCS */ 368*265Smws { "copys", dis_log }, /* DIF_OP_COPYS */ 369*265Smws { "stb", dis_store }, /* DIF_OP_STB */ 370*265Smws { "sth", dis_store }, /* DIF_OP_STH */ 371*265Smws { "stw", dis_store }, /* DIF_OP_STW */ 372*265Smws { "stx", dis_store }, /* DIF_OP_STX */ 373*265Smws { "uldsb", dis_load }, /* DIF_OP_ULDSB */ 374*265Smws { "uldsh", dis_load }, /* DIF_OP_ULDSH */ 375*265Smws { "uldsw", dis_load }, /* DIF_OP_ULDSW */ 376*265Smws { "uldub", dis_load }, /* DIF_OP_ULDUB */ 377*265Smws { "ulduh", dis_load }, /* DIF_OP_ULDUH */ 378*265Smws { "ulduw", dis_load }, /* DIF_OP_ULDUW */ 379*265Smws { "uldx", dis_load }, /* DIF_OP_ULDX */ 380*265Smws { "rldsb", dis_load }, /* DIF_OP_RLDSB */ 381*265Smws { "rldsh", dis_load }, /* DIF_OP_RLDSH */ 382*265Smws { "rldsw", dis_load }, /* DIF_OP_RLDSW */ 383*265Smws { "rldub", dis_load }, /* DIF_OP_RLDUB */ 384*265Smws { "rlduh", dis_load }, /* DIF_OP_RLDUH */ 385*265Smws { "rlduw", dis_load }, /* DIF_OP_RLDUW */ 386*265Smws { "rldx", dis_load }, /* DIF_OP_RLDX */ 387*265Smws { "xlate", dis_xlate }, /* DIF_OP_XLATE */ 388*265Smws { "xlarg", dis_xlate }, /* DIF_OP_XLARG */ 389*265Smws }; 390*265Smws 391*265Smws dif_instr_t instr, opcode; 392*265Smws const struct opent *op; 393*265Smws 394*265Smws if (mdb_vread(&instr, sizeof (dif_instr_t), addr) == -1) { 395*265Smws mdb_warn("failed to read DIF instruction at %p", addr); 396*265Smws return (DCMD_ERR); 397*265Smws } 398*265Smws 399*265Smws opcode = DIF_INSTR_OP(instr); 400*265Smws 401*265Smws if (opcode >= sizeof (optab) / sizeof (optab[0])) 402*265Smws opcode = 0; /* force invalid opcode message */ 403*265Smws 404*265Smws op = &optab[opcode]; 405*265Smws mdb_printf("%0*p %08x ", DIFO_ADDRWIDTH, addr, instr); 406*265Smws op->op_func(dp, op->op_name, instr); 407*265Smws mdb_printf("\n"); 408*265Smws mdb_set_dot(addr + sizeof (dif_instr_t)); 409*265Smws 410*265Smws return (DCMD_OK); 411*265Smws } 412*265Smws 413*265Smws /*ARGSUSED*/ 414*265Smws int 415*265Smws difo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 416*265Smws { 417*265Smws dtrace_difo_t difo, *dp = &difo; 418*265Smws uintptr_t instr, limit; 419*265Smws dtrace_difv_t *dvp; 420*265Smws size_t varsize; 421*265Smws ulong_t i; 422*265Smws char type[64]; 423*265Smws char *str; 424*265Smws 425*265Smws if (!(flags & DCMD_ADDRSPEC)) 426*265Smws return (DCMD_USAGE); 427*265Smws 428*265Smws if (mdb_vread(dp, sizeof (dtrace_difo_t), addr) == -1) { 429*265Smws mdb_warn("couldn't read dtrace_difo_t at %p", addr); 430*265Smws return (DCMD_ERR); 431*265Smws } 432*265Smws 433*265Smws mdb_printf("%<u>DIF Object 0x%p%</u> (refcnt=%d)\n\n", 434*265Smws addr, dp->dtdo_refcnt); 435*265Smws mdb_printf("%<b>%-*s %-8s %s%</b>\n", DIFO_ADDRWIDTH, "ADDR", 436*265Smws "OPCODE", "INSTRUCTION"); 437*265Smws 438*265Smws mdb_set_dot((uintmax_t)(uintptr_t)dp->dtdo_buf); 439*265Smws limit = (uintptr_t)dp->dtdo_buf + dp->dtdo_len * sizeof (dif_instr_t); 440*265Smws 441*265Smws while ((instr = mdb_get_dot()) < limit) 442*265Smws dis(instr, dp); 443*265Smws 444*265Smws if (dp->dtdo_varlen != 0) { 445*265Smws mdb_printf("\n%<b>%-16s %-4s %-3s %-3s %-4s %s%</b>\n", 446*265Smws "NAME", "ID", "KND", "SCP", "FLAG", "TYPE"); 447*265Smws } 448*265Smws 449*265Smws varsize = sizeof (dtrace_difv_t) * dp->dtdo_varlen; 450*265Smws dvp = mdb_alloc(varsize, UM_SLEEP | UM_GC); 451*265Smws 452*265Smws if (mdb_vread(dvp, varsize, (uintptr_t)dp->dtdo_vartab) == -1) { 453*265Smws mdb_warn("couldn't read dtdo_vartab"); 454*265Smws return (DCMD_ERR); 455*265Smws } 456*265Smws 457*265Smws str = mdb_alloc(dp->dtdo_strlen, UM_SLEEP | UM_GC); 458*265Smws 459*265Smws if (mdb_vread(str, dp->dtdo_strlen, (uintptr_t)dp->dtdo_strtab) == -1) { 460*265Smws mdb_warn("couldn't read dtdo_strtab"); 461*265Smws return (DCMD_ERR); 462*265Smws } 463*265Smws 464*265Smws for (i = 0; i < dp->dtdo_varlen; i++) { 465*265Smws dtrace_difv_t *v = &dvp[i]; 466*265Smws char kind[4], scope[4], flags[16] = { 0 }; 467*265Smws 468*265Smws switch (v->dtdv_kind) { 469*265Smws case DIFV_KIND_ARRAY: 470*265Smws (void) strcpy(kind, "arr"); 471*265Smws break; 472*265Smws case DIFV_KIND_SCALAR: 473*265Smws (void) strcpy(kind, "scl"); 474*265Smws break; 475*265Smws default: 476*265Smws (void) mdb_snprintf(kind, sizeof (kind), 477*265Smws "%u", v->dtdv_kind); 478*265Smws } 479*265Smws 480*265Smws switch (v->dtdv_scope) { 481*265Smws case DIFV_SCOPE_GLOBAL: 482*265Smws (void) strcpy(scope, "glb"); 483*265Smws break; 484*265Smws case DIFV_SCOPE_THREAD: 485*265Smws (void) strcpy(scope, "tls"); 486*265Smws break; 487*265Smws case DIFV_SCOPE_LOCAL: 488*265Smws (void) strcpy(scope, "loc"); 489*265Smws break; 490*265Smws default: 491*265Smws (void) mdb_snprintf(scope, sizeof (scope), 492*265Smws "%u", v->dtdv_scope); 493*265Smws } 494*265Smws 495*265Smws if (v->dtdv_flags & ~(DIFV_F_REF | DIFV_F_MOD)) { 496*265Smws (void) mdb_snprintf(flags, sizeof (flags), "/0x%x", 497*265Smws v->dtdv_flags & ~(DIFV_F_REF | DIFV_F_MOD)); 498*265Smws } 499*265Smws 500*265Smws if (v->dtdv_flags & DIFV_F_REF) 501*265Smws (void) strcat(flags, "/r"); 502*265Smws if (v->dtdv_flags & DIFV_F_MOD) 503*265Smws (void) strcat(flags, "/w"); 504*265Smws 505*265Smws mdb_printf("%-16s %-4x %-3s %-3s %-4s %s\n", 506*265Smws &str[v->dtdv_name], 507*265Smws v->dtdv_id, kind, scope, flags + 1, 508*265Smws dis_typestr(&v->dtdv_type, type, sizeof (type))); 509*265Smws } 510*265Smws 511*265Smws mdb_printf("\n%<b>RETURN%</b>\n%s\n\n", 512*265Smws dis_typestr(&dp->dtdo_rtype, type, sizeof (type))); 513*265Smws 514*265Smws return (DCMD_OK); 515*265Smws } 516*265Smws 517*265Smws /*ARGSUSED*/ 518*265Smws int 519*265Smws difinstr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 520*265Smws { 521*265Smws if (!(flags & DCMD_ADDRSPEC)) 522*265Smws return (DCMD_USAGE); 523*265Smws 524*265Smws return (dis(addr, NULL)); 525*265Smws } 526*265Smws 527*265Smws /*ARGSUSED*/ 528*265Smws int 529*265Smws dof_hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 530*265Smws { 531*265Smws dof_hdr_t h; 532*265Smws 533*265Smws if (argc != 0) 534*265Smws return (DCMD_USAGE); 535*265Smws 536*265Smws if (!(flags & DCMD_ADDRSPEC)) 537*265Smws addr = 0; /* assume base of file in file target */ 538*265Smws 539*265Smws if (mdb_vread(&h, sizeof (h), addr) != sizeof (h)) { 540*265Smws mdb_warn("failed to read header at %p", addr); 541*265Smws return (DCMD_ERR); 542*265Smws } 543*265Smws 544*265Smws mdb_printf("dofh_ident.id_magic = 0x%x, %c, %c, %c\n", 545*265Smws h.dofh_ident[DOF_ID_MAG0], h.dofh_ident[DOF_ID_MAG1], 546*265Smws h.dofh_ident[DOF_ID_MAG2], h.dofh_ident[DOF_ID_MAG3]); 547*265Smws 548*265Smws switch (h.dofh_ident[DOF_ID_MODEL]) { 549*265Smws case DOF_MODEL_ILP32: 550*265Smws mdb_printf("dofh_ident.id_model = ILP32\n"); 551*265Smws break; 552*265Smws case DOF_MODEL_LP64: 553*265Smws mdb_printf("dofh_ident.id_model = LP64\n"); 554*265Smws break; 555*265Smws default: 556*265Smws mdb_printf("dofh_ident.id_model = 0x%x\n", 557*265Smws h.dofh_ident[DOF_ID_MODEL]); 558*265Smws } 559*265Smws 560*265Smws switch (h.dofh_ident[DOF_ID_ENCODING]) { 561*265Smws case DOF_ENCODE_LSB: 562*265Smws mdb_printf("dofh_ident.id_encoding = LSB\n"); 563*265Smws break; 564*265Smws case DOF_ENCODE_MSB: 565*265Smws mdb_printf("dofh_ident.id_encoding = MSB\n"); 566*265Smws break; 567*265Smws default: 568*265Smws mdb_printf("dofh_ident.id_encoding = 0x%x\n", 569*265Smws h.dofh_ident[DOF_ID_ENCODING]); 570*265Smws } 571*265Smws 572*265Smws mdb_printf("dofh_ident.id_version = %u\n", 573*265Smws h.dofh_ident[DOF_ID_VERSION]); 574*265Smws mdb_printf("dofh_ident.id_difvers = %u\n", 575*265Smws h.dofh_ident[DOF_ID_DIFVERS]); 576*265Smws mdb_printf("dofh_ident.id_difireg = %u\n", 577*265Smws h.dofh_ident[DOF_ID_DIFIREG]); 578*265Smws mdb_printf("dofh_ident.id_diftreg = %u\n", 579*265Smws h.dofh_ident[DOF_ID_DIFTREG]); 580*265Smws 581*265Smws mdb_printf("dofh_flags = 0x%x\n", h.dofh_flags); 582*265Smws mdb_printf("dofh_hdrsize = %u\n", h.dofh_hdrsize); 583*265Smws mdb_printf("dofh_secsize = %u\n", h.dofh_secsize); 584*265Smws mdb_printf("dofh_secnum = %u\n", h.dofh_secnum); 585*265Smws mdb_printf("dofh_secoff = %llu\n", h.dofh_secoff); 586*265Smws mdb_printf("dofh_loadsz = %llu\n", h.dofh_loadsz); 587*265Smws mdb_printf("dofh_filesz = %llu\n", h.dofh_filesz); 588*265Smws 589*265Smws return (DCMD_OK); 590*265Smws } 591*265Smws 592*265Smws /*ARGSUSED*/ 593*265Smws static int 594*265Smws dof_sec_walk(uintptr_t addr, void *ignored, int *sec) 595*265Smws { 596*265Smws mdb_printf("%3d ", (*sec)++); 597*265Smws (void) dof_sec(addr, DCMD_ADDRSPEC | DCMD_LOOP, 0, NULL); 598*265Smws return (WALK_NEXT); 599*265Smws } 600*265Smws 601*265Smws /*ARGSUSED*/ 602*265Smws int 603*265Smws dof_sec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 604*265Smws { 605*265Smws const char *name; 606*265Smws dof_sec_t s; 607*265Smws 608*265Smws if (!(flags & DCMD_ADDRSPEC)) 609*265Smws mdb_printf("%<u>%-3s ", "NDX"); 610*265Smws 611*265Smws if (!(flags & DCMD_ADDRSPEC) || DCMD_HDRSPEC(flags)) { 612*265Smws mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n", 613*265Smws "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFFSET", 614*265Smws "SIZE"); 615*265Smws } 616*265Smws 617*265Smws if (!(flags & DCMD_ADDRSPEC)) { 618*265Smws int sec = 0; 619*265Smws 620*265Smws if (mdb_walk("dof_sec", 621*265Smws (mdb_walk_cb_t)dof_sec_walk, &sec) == -1) { 622*265Smws mdb_warn("failed to walk dof_sec"); 623*265Smws return (DCMD_ERR); 624*265Smws } 625*265Smws return (DCMD_OK); 626*265Smws } 627*265Smws 628*265Smws if (argc != 0) 629*265Smws return (DCMD_USAGE); 630*265Smws 631*265Smws if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) { 632*265Smws mdb_warn("failed to read section header at %p", addr); 633*265Smws return (DCMD_ERR); 634*265Smws } 635*265Smws 636*265Smws mdb_printf("%?p ", addr); 637*265Smws 638*265Smws if ((name = dof_sec_name(s.dofs_type)) != NULL) 639*265Smws mdb_printf("%-10s ", name); 640*265Smws else 641*265Smws mdb_printf("%-10u ", s.dofs_type); 642*265Smws 643*265Smws mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s.dofs_align, 644*265Smws s.dofs_flags, s.dofs_entsize, s.dofs_offset, s.dofs_size); 645*265Smws 646*265Smws return (DCMD_OK); 647*265Smws } 648*265Smws 649*265Smws int 650*265Smws dof_sec_walk_init(mdb_walk_state_t *wsp) 651*265Smws { 652*265Smws dof_hdr_t h, *hp; 653*265Smws size_t size; 654*265Smws 655*265Smws if (mdb_vread(&h, sizeof (h), wsp->walk_addr) != sizeof (h)) { 656*265Smws mdb_warn("failed to read DOF header at %p", wsp->walk_addr); 657*265Smws return (WALK_ERR); 658*265Smws } 659*265Smws 660*265Smws size = sizeof (dof_hdr_t) + sizeof (dof_sec_t) * h.dofh_secnum; 661*265Smws hp = mdb_alloc(size, UM_SLEEP); 662*265Smws 663*265Smws if (mdb_vread(hp, size, wsp->walk_addr) != size) { 664*265Smws mdb_warn("failed to read DOF sections at %p", wsp->walk_addr); 665*265Smws mdb_free(hp, size); 666*265Smws return (WALK_ERR); 667*265Smws } 668*265Smws 669*265Smws wsp->walk_arg = (void *)0; 670*265Smws wsp->walk_data = hp; 671*265Smws 672*265Smws return (WALK_NEXT); 673*265Smws } 674*265Smws 675*265Smws int 676*265Smws dof_sec_walk_step(mdb_walk_state_t *wsp) 677*265Smws { 678*265Smws uint_t i = (uintptr_t)wsp->walk_arg; 679*265Smws size_t off = sizeof (dof_hdr_t) + sizeof (dof_sec_t) * i; 680*265Smws dof_hdr_t *hp = wsp->walk_data; 681*265Smws dof_sec_t *sp = (dof_sec_t *)((uintptr_t)hp + off); 682*265Smws 683*265Smws if (i >= hp->dofh_secnum) 684*265Smws return (WALK_DONE); 685*265Smws 686*265Smws wsp->walk_arg = (void *)(uintptr_t)(i + 1); 687*265Smws return (wsp->walk_callback(wsp->walk_addr + off, sp, wsp->walk_cbdata)); 688*265Smws } 689*265Smws 690*265Smws void 691*265Smws dof_sec_walk_fini(mdb_walk_state_t *wsp) 692*265Smws { 693*265Smws dof_hdr_t *hp = wsp->walk_data; 694*265Smws mdb_free(hp, sizeof (dof_hdr_t) + sizeof (dof_sec_t) * hp->dofh_secnum); 695*265Smws } 696*265Smws 697*265Smws /*ARGSUSED*/ 698*265Smws int 699*265Smws dof_ecbdesc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 700*265Smws { 701*265Smws dof_ecbdesc_t e; 702*265Smws 703*265Smws if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 704*265Smws return (DCMD_USAGE); 705*265Smws 706*265Smws if (mdb_vread(&e, sizeof (e), addr) != sizeof (e)) { 707*265Smws mdb_warn("failed to read ecbdesc at %p", addr); 708*265Smws return (DCMD_ERR); 709*265Smws } 710*265Smws 711*265Smws mdb_printf("dofe_probes = %d\n", e.dofe_probes); 712*265Smws mdb_printf("dofe_actions = %d\n", e.dofe_actions); 713*265Smws mdb_printf("dofe_pred = %d\n", e.dofe_pred); 714*265Smws mdb_printf("dofe_uarg = 0x%llx\n", e.dofe_uarg); 715*265Smws 716*265Smws return (DCMD_OK); 717*265Smws } 718*265Smws 719*265Smws /*ARGSUSED*/ 720*265Smws int 721*265Smws dof_probedesc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 722*265Smws { 723*265Smws dof_probedesc_t p; 724*265Smws 725*265Smws if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 726*265Smws return (DCMD_USAGE); 727*265Smws 728*265Smws if (mdb_vread(&p, sizeof (p), addr) != sizeof (p)) { 729*265Smws mdb_warn("failed to read probedesc at %p", addr); 730*265Smws return (DCMD_ERR); 731*265Smws } 732*265Smws 733*265Smws mdb_printf("dofp_strtab = %d\n", p.dofp_strtab); 734*265Smws mdb_printf("dofp_provider = %u\n", p.dofp_provider); 735*265Smws mdb_printf("dofp_mod = %u\n", p.dofp_mod); 736*265Smws mdb_printf("dofp_func = %u\n", p.dofp_func); 737*265Smws mdb_printf("dofp_name = %u\n", p.dofp_name); 738*265Smws mdb_printf("dofp_id = %u\n", p.dofp_id); 739*265Smws 740*265Smws return (DCMD_OK); 741*265Smws } 742*265Smws 743*265Smws /*ARGSUSED*/ 744*265Smws int 745*265Smws dof_actdesc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 746*265Smws { 747*265Smws dof_actdesc_t a; 748*265Smws 749*265Smws if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 750*265Smws return (DCMD_USAGE); 751*265Smws 752*265Smws if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) { 753*265Smws mdb_warn("failed to read actdesc at %p", addr); 754*265Smws return (DCMD_ERR); 755*265Smws } 756*265Smws 757*265Smws mdb_printf("dofa_difo = %d\n", a.dofa_difo); 758*265Smws mdb_printf("dofa_strtab = %d\n", a.dofa_strtab); 759*265Smws mdb_printf("dofa_kind = %u\n", a.dofa_kind); 760*265Smws mdb_printf("dofa_ntuple = %u\n", a.dofa_ntuple); 761*265Smws mdb_printf("dofa_arg = 0x%llx\n", a.dofa_arg); 762*265Smws mdb_printf("dofa_uarg = 0x%llx\n", a.dofa_uarg); 763*265Smws 764*265Smws return (DCMD_OK); 765*265Smws } 766*265Smws 767*265Smws /*ARGSUSED*/ 768*265Smws int 769*265Smws dof_relohdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 770*265Smws { 771*265Smws dof_relohdr_t r; 772*265Smws 773*265Smws if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 774*265Smws return (DCMD_USAGE); 775*265Smws 776*265Smws if (mdb_vread(&r, sizeof (r), addr) != sizeof (r)) { 777*265Smws mdb_warn("failed to read relohdr at %p", addr); 778*265Smws return (DCMD_ERR); 779*265Smws } 780*265Smws 781*265Smws mdb_printf("dofr_strtab = %d\n", r.dofr_strtab); 782*265Smws mdb_printf("dofr_relsec = %d\n", r.dofr_relsec); 783*265Smws mdb_printf("dofr_tgtsec = %d\n", r.dofr_tgtsec); 784*265Smws 785*265Smws return (DCMD_OK); 786*265Smws } 787*265Smws 788*265Smws /*ARGSUSED*/ 789*265Smws int 790*265Smws dof_relodesc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 791*265Smws { 792*265Smws dof_relodesc_t r; 793*265Smws 794*265Smws if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 795*265Smws return (DCMD_USAGE); 796*265Smws 797*265Smws if (mdb_vread(&r, sizeof (r), addr) != sizeof (r)) { 798*265Smws mdb_warn("failed to read relodesc at %p", addr); 799*265Smws return (DCMD_ERR); 800*265Smws } 801*265Smws 802*265Smws mdb_printf("dofr_name = %u\n", r.dofr_name); 803*265Smws mdb_printf("dofr_type = %u\n", r.dofr_type); 804*265Smws mdb_printf("dofr_offset = 0x%llx\n", r.dofr_offset); 805*265Smws mdb_printf("dofr_data = 0x%llx\n", r.dofr_data); 806*265Smws 807*265Smws return (DCMD_OK); 808*265Smws } 809*265Smws 810*265Smws static int 811*265Smws dof_sect_strtab(uintptr_t addr, dof_sec_t *sec) 812*265Smws { 813*265Smws char *strtab; 814*265Smws size_t sz, i; 815*265Smws 816*265Smws sz = (size_t)sec->dofs_size; 817*265Smws strtab = mdb_alloc(sz, UM_SLEEP | UM_GC); 818*265Smws if (mdb_vread(strtab, sz, addr + sec->dofs_offset) != sz) { 819*265Smws mdb_warn("failed to read string table"); 820*265Smws return (1); 821*265Smws } 822*265Smws 823*265Smws mdb_printf("size = %lx\n", sz); 824*265Smws 825*265Smws for (i = 0; i < sz; i++) { 826*265Smws if (strtab[i] == '\0') 827*265Smws mdb_printf("\\0"); 828*265Smws else 829*265Smws mdb_printf("%c", strtab[i]); 830*265Smws } 831*265Smws 832*265Smws mdb_printf("\n"); 833*265Smws 834*265Smws return (0); 835*265Smws } 836*265Smws 837*265Smws static int 838*265Smws dof_sect_provider(uintptr_t addr, dof_sec_t *sec, dof_sec_t *dofs) 839*265Smws { 840*265Smws dof_provider_t pv; 841*265Smws dof_probe_t *pb; 842*265Smws char *strtab; 843*265Smws uint32_t *offs; 844*265Smws uint8_t *args = NULL; 845*265Smws size_t sz; 846*265Smws int i, j; 847*265Smws dof_stridx_t narg, xarg; 848*265Smws 849*265Smws if (mdb_vread(&pv, sizeof (dof_provider_t), 850*265Smws addr + sec->dofs_offset) != sizeof (dof_provider_t)) { 851*265Smws mdb_warn("failed to read DOF provider"); 852*265Smws return (-1); 853*265Smws } 854*265Smws 855*265Smws sz = dofs[pv.dofpv_strtab].dofs_size; 856*265Smws strtab = mdb_alloc(sz, UM_SLEEP | UM_GC); 857*265Smws if (mdb_vread(strtab, sz, addr + 858*265Smws dofs[pv.dofpv_strtab].dofs_offset) != sz) { 859*265Smws mdb_warn("failed to read string table"); 860*265Smws return (-1); 861*265Smws } 862*265Smws 863*265Smws mdb_printf("%lx provider %s {\n", (ulong_t)(addr + sec->dofs_offset), 864*265Smws strtab + pv.dofpv_name); 865*265Smws 866*265Smws sz = dofs[pv.dofpv_prargs].dofs_size; 867*265Smws if (sz != 0) { 868*265Smws args = mdb_alloc(sz, UM_SLEEP | UM_GC); 869*265Smws if (mdb_vread(args, sz, addr + 870*265Smws dofs[pv.dofpv_prargs].dofs_offset) != sz) { 871*265Smws mdb_warn("failed to read args"); 872*265Smws return (-1); 873*265Smws } 874*265Smws } 875*265Smws 876*265Smws sz = dofs[pv.dofpv_proffs].dofs_size; 877*265Smws offs = mdb_alloc(sz, UM_SLEEP | UM_GC); 878*265Smws if (mdb_vread(offs, sz, addr + dofs[pv.dofpv_proffs].dofs_offset) 879*265Smws != sz) { 880*265Smws mdb_warn("failed to read offs"); 881*265Smws return (-1); 882*265Smws } 883*265Smws 884*265Smws sz = dofs[pv.dofpv_probes].dofs_size; 885*265Smws pb = mdb_alloc(sz, UM_SLEEP | UM_GC); 886*265Smws if (mdb_vread(pb, sz, addr + dofs[pv.dofpv_probes].dofs_offset) != sz) { 887*265Smws mdb_warn("failed to read probes"); 888*265Smws return (-1); 889*265Smws } 890*265Smws 891*265Smws (void) mdb_inc_indent(2); 892*265Smws 893*265Smws for (i = 0; i < sz / dofs[pv.dofpv_probes].dofs_entsize; i++) { 894*265Smws mdb_printf("%lx probe %s:%s {\n", (ulong_t)(addr + 895*265Smws dofs[pv.dofpv_probes].dofs_offset + 896*265Smws i * dofs[pv.dofpv_probes].dofs_entsize), 897*265Smws strtab + pb[i].dofpr_func, 898*265Smws strtab + pb[i].dofpr_name); 899*265Smws 900*265Smws (void) mdb_inc_indent(2); 901*265Smws mdb_printf("addr: %p\n", (ulong_t)pb[i].dofpr_addr); 902*265Smws mdb_printf("offs: "); 903*265Smws for (j = 0; j < pb[i].dofpr_noffs; j++) { 904*265Smws mdb_printf("%s %x", "," + (j == 0), 905*265Smws offs[pb[i].dofpr_offidx + j]); 906*265Smws } 907*265Smws mdb_printf("\n"); 908*265Smws 909*265Smws mdb_printf("nargs:"); 910*265Smws narg = pb[i].dofpr_nargv; 911*265Smws for (j = 0; j < pb[i].dofpr_nargc; j++) { 912*265Smws mdb_printf("%s %s", "," + (j == 0), strtab + narg); 913*265Smws narg += strlen(strtab + narg) + 1; 914*265Smws } 915*265Smws mdb_printf("\n"); 916*265Smws mdb_printf("xargs:"); 917*265Smws xarg = pb[i].dofpr_xargv; 918*265Smws for (j = 0; j < pb[i].dofpr_xargc; j++) { 919*265Smws mdb_printf("%s %s", "," + (j == 0), strtab + xarg); 920*265Smws xarg += strlen(strtab + xarg) + 1; 921*265Smws } 922*265Smws mdb_printf("\n"); 923*265Smws mdb_printf("map: "); 924*265Smws for (j = 0; j < pb[i].dofpr_xargc; j++) { 925*265Smws mdb_printf("%s %d->%d", "," + (j == 0), 926*265Smws args[pb[i].dofpr_argidx + j], j); 927*265Smws } 928*265Smws 929*265Smws (void) mdb_dec_indent(2); 930*265Smws mdb_printf("\n}\n"); 931*265Smws } 932*265Smws 933*265Smws (void) mdb_dec_indent(2); 934*265Smws mdb_printf("}\n"); 935*265Smws 936*265Smws return (0); 937*265Smws } 938*265Smws 939*265Smws static int 940*265Smws dof_sect_prargs(uintptr_t addr, dof_sec_t *sec) 941*265Smws { 942*265Smws int i; 943*265Smws uint8_t arg; 944*265Smws 945*265Smws for (i = 0; i < sec->dofs_size; i++) { 946*265Smws if (mdb_vread(&arg, sizeof (arg), 947*265Smws addr + sec->dofs_offset + i) != sizeof (arg)) { 948*265Smws mdb_warn("failed to read argument"); 949*265Smws return (1); 950*265Smws } 951*265Smws 952*265Smws mdb_printf("%d ", arg); 953*265Smws 954*265Smws if (i % 20 == 19) 955*265Smws mdb_printf("\n"); 956*265Smws } 957*265Smws 958*265Smws mdb_printf("\n"); 959*265Smws 960*265Smws return (0); 961*265Smws } 962*265Smws 963*265Smws /*ARGSUSED*/ 964*265Smws static int 965*265Smws dofdump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 966*265Smws { 967*265Smws dof_hdr_t dofh; 968*265Smws dof_sec_t *dofs; 969*265Smws const char *name; 970*265Smws int i; 971*265Smws 972*265Smws if (mdb_vread(&dofh, sizeof (dof_hdr_t), addr) != sizeof (dof_hdr_t)) { 973*265Smws mdb_warn("failed to read DOF header"); 974*265Smws return (DCMD_ERR); 975*265Smws } 976*265Smws 977*265Smws dofs = mdb_alloc(sizeof (dof_sec_t) * dofh.dofh_secnum, 978*265Smws UM_SLEEP | UM_GC); 979*265Smws 980*265Smws for (i = 0; i < dofh.dofh_secnum; i++) { 981*265Smws if (mdb_vread(&dofs[i], sizeof (dof_sec_t), dofh.dofh_secoff + 982*265Smws addr + i * dofh.dofh_secsize) != sizeof (dof_sec_t)) { 983*265Smws mdb_warn("failed to read DOF sections"); 984*265Smws return (DCMD_ERR); 985*265Smws } 986*265Smws } 987*265Smws 988*265Smws for (i = 0; i < dofh.dofh_secnum; i++) { 989*265Smws mdb_printf("%lx Section %d: ", (ulong_t) 990*265Smws (dofh.dofh_secoff + addr + i * dofh.dofh_secsize), i); 991*265Smws 992*265Smws if ((name = dof_sec_name(dofs[i].dofs_type)) != NULL) 993*265Smws mdb_printf("%s\n", name); 994*265Smws else 995*265Smws mdb_printf("%u\n", dofs[i].dofs_type); 996*265Smws 997*265Smws (void) mdb_inc_indent(2); 998*265Smws switch (dofs[i].dofs_type) { 999*265Smws case DOF_SECT_PROVIDER: 1000*265Smws (void) dof_sect_provider(addr, &dofs[i], dofs); 1001*265Smws break; 1002*265Smws case DOF_SECT_STRTAB: 1003*265Smws (void) dof_sect_strtab(addr, &dofs[i]); 1004*265Smws break; 1005*265Smws case DOF_SECT_PRARGS: 1006*265Smws (void) dof_sect_prargs(addr, &dofs[i]); 1007*265Smws break; 1008*265Smws } 1009*265Smws (void) mdb_dec_indent(2); 1010*265Smws 1011*265Smws mdb_printf("\n"); 1012*265Smws } 1013*265Smws 1014*265Smws return (DCMD_OK); 1015*265Smws } 1016*265Smws 1017*265Smws static const mdb_dcmd_t common_dcmds[] = { 1018*265Smws { "difinstr", ":", "disassemble a DIF instruction", difinstr }, 1019*265Smws { "difo", ":", "print a DIF object", difo }, 1020*265Smws { "dof_hdr", "?", "print a DOF header", dof_hdr }, 1021*265Smws { "dof_sec", ":", "print a DOF section header", dof_sec }, 1022*265Smws { "dof_ecbdesc", ":", "print a DOF ecbdesc", dof_ecbdesc }, 1023*265Smws { "dof_probedesc", ":", "print a DOF probedesc", dof_probedesc }, 1024*265Smws { "dof_actdesc", ":", "print a DOF actdesc", dof_actdesc }, 1025*265Smws { "dof_relohdr", ":", "print a DOF relocation header", dof_relohdr }, 1026*265Smws { "dof_relodesc", ":", "print a DOF relodesc", dof_relodesc }, 1027*265Smws { "dofdump", ":", "dump DOF", dofdump }, 1028*265Smws { NULL } 1029*265Smws }; 1030*265Smws 1031*265Smws static const mdb_walker_t common_walkers[] = { 1032*265Smws { "dof_sec", "walk DOF section header table given header address", 1033*265Smws dof_sec_walk_init, dof_sec_walk_step, dof_sec_walk_fini }, 1034*265Smws { NULL } 1035*265Smws }; 1036*265Smws 1037*265Smws static mdb_modinfo_t modinfo = { 1038*265Smws MDB_API_VERSION, NULL, NULL 1039*265Smws }; 1040*265Smws 1041*265Smws const mdb_modinfo_t * 1042*265Smws _mdb_init(void) 1043*265Smws { 1044*265Smws uint_t d = 0, kd = 0, w = 0, kw = 0; 1045*265Smws const mdb_walker_t *wp; 1046*265Smws const mdb_dcmd_t *dp; 1047*265Smws 1048*265Smws for (dp = common_dcmds; dp->dc_name != NULL; dp++) 1049*265Smws d++; /* count common dcmds */ 1050*265Smws 1051*265Smws for (wp = common_walkers; wp->walk_name != NULL; wp++) 1052*265Smws w++; /* count common walkers */ 1053*265Smws 1054*265Smws #ifdef _KERNEL 1055*265Smws for (dp = kernel_dcmds; dp->dc_name != NULL; dp++) 1056*265Smws kd++; /* count kernel dcmds */ 1057*265Smws 1058*265Smws for (wp = kernel_walkers; wp->walk_name != NULL; wp++) 1059*265Smws kw++; /* count common walkers */ 1060*265Smws #endif 1061*265Smws 1062*265Smws modinfo.mi_dcmds = mdb_zalloc(sizeof (*dp) * (d + kd + 1), UM_SLEEP); 1063*265Smws modinfo.mi_walkers = mdb_zalloc(sizeof (*wp) * (w + kw + 1), UM_SLEEP); 1064*265Smws 1065*265Smws bcopy(common_dcmds, (void *)modinfo.mi_dcmds, sizeof (*dp) * d); 1066*265Smws bcopy(common_walkers, (void *)modinfo.mi_walkers, sizeof (*wp) * w); 1067*265Smws 1068*265Smws #ifdef _KERNEL 1069*265Smws bcopy(kernel_dcmds, (void *) 1070*265Smws (modinfo.mi_dcmds + d), sizeof (*dp) * kd); 1071*265Smws bcopy(kernel_walkers, (void *) 1072*265Smws (modinfo.mi_walkers + w), sizeof (*wp) * kw); 1073*265Smws #endif 1074*265Smws return (&modinfo); 1075*265Smws } 1076*265Smws 1077*265Smws void 1078*265Smws _mdb_fini(void) 1079*265Smws { 1080*265Smws const mdb_walker_t *wp; 1081*265Smws const mdb_dcmd_t *dp; 1082*265Smws uint_t d = 0, w = 0; 1083*265Smws 1084*265Smws for (dp = modinfo.mi_dcmds; dp->dc_name != NULL; dp++) 1085*265Smws d++; 1086*265Smws 1087*265Smws for (wp = modinfo.mi_walkers; wp->walk_name != NULL; wp++) 1088*265Smws w++; 1089*265Smws 1090*265Smws mdb_free((void *)modinfo.mi_dcmds, sizeof (*dp) * (d + 1)); 1091*265Smws mdb_free((void *)modinfo.mi_walkers, sizeof (*wp) * (w + 1)); 1092*265Smws } 1093