4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
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]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <mdb/mdb_modapi.h>
32 extern int dof_sec(uintptr_t, uint_t
, int, const mdb_arg_t
*);
33 extern const char *dof_sec_name(uint32_t);
35 extern const mdb_walker_t kernel_walkers
[];
36 extern const mdb_dcmd_t kernel_dcmds
[];
40 dis_log(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
42 mdb_printf("%-4s %%r%u, %%r%u, %%r%u", name
,
43 DIF_INSTR_R1(instr
), DIF_INSTR_R2(instr
), DIF_INSTR_RD(instr
));
48 dis_branch(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
50 mdb_printf("%-4s %u", name
, DIF_INSTR_LABEL(instr
));
55 dis_load(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
57 mdb_printf("%-4s [%%r%u], %%r%u", name
,
58 DIF_INSTR_R1(instr
), DIF_INSTR_RD(instr
));
63 dis_store(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
65 mdb_printf("%-4s %%r%u, [%%r%u]", name
,
66 DIF_INSTR_R1(instr
), DIF_INSTR_RD(instr
));
71 dis_str(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
73 mdb_printf("%s", name
);
78 dis_r1rd(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
80 mdb_printf("%-4s %%r%u, %%r%u", name
,
81 DIF_INSTR_R1(instr
), DIF_INSTR_RD(instr
));
86 dis_cmp(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
88 mdb_printf("%-4s %%r%u, %%r%u", name
,
89 DIF_INSTR_R1(instr
), DIF_INSTR_R2(instr
));
94 dis_tst(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
96 mdb_printf("%-4s %%r%u", name
, DIF_INSTR_R1(instr
));
100 dis_varname(const dtrace_difo_t
*dp
, uint_t id
, uint_t scope
)
104 caddr_t addr
= NULL
, str
;
110 varsize
= sizeof (dtrace_difv_t
) * dp
->dtdo_varlen
;
111 dvp
= mdb_alloc(varsize
, UM_SLEEP
);
113 if (mdb_vread(dvp
, varsize
, (uintptr_t)dp
->dtdo_vartab
) == -1) {
114 mdb_free(dvp
, varsize
);
115 return ("<unreadable>");
118 for (i
= 0; i
< dp
->dtdo_varlen
; i
++) {
119 if (dvp
[i
].dtdv_id
== id
&& dvp
[i
].dtdv_scope
== scope
) {
120 if (dvp
[i
].dtdv_name
< dp
->dtdo_strlen
)
121 addr
= dp
->dtdo_strtab
+ dvp
[i
].dtdv_name
;
126 mdb_free(dvp
, varsize
);
131 str
= mdb_zalloc(dp
->dtdo_strlen
+ 1, UM_SLEEP
| UM_GC
);
133 for (i
= 0; i
== 0 || str
[i
- 1] != '\0'; i
++, addr
++) {
134 if (mdb_vread(&str
[i
], sizeof (char), (uintptr_t)addr
) == -1)
135 return ("<unreadable>");
142 dis_scope(const char *name
)
145 case 'l': return (DIFV_SCOPE_LOCAL
);
146 case 't': return (DIFV_SCOPE_THREAD
);
147 case 'g': return (DIFV_SCOPE_GLOBAL
);
148 default: return (-1u);
153 dis_lda(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
155 uint_t var
= DIF_INSTR_R1(instr
);
158 mdb_printf("%-4s DIF_VAR(%x), %%r%u, %%r%u", name
,
159 var
, DIF_INSTR_R2(instr
), DIF_INSTR_RD(instr
));
161 if ((vname
= dis_varname(dp
, var
, dis_scope(name
))) != NULL
)
162 mdb_printf("\t\t! %s", vname
);
166 dis_ldv(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
168 uint_t var
= DIF_INSTR_VAR(instr
);
171 mdb_printf("%-4s DIF_VAR(%x), %%r%u", name
, var
, DIF_INSTR_RD(instr
));
173 if ((vname
= dis_varname(dp
, var
, dis_scope(name
))) != NULL
)
174 mdb_printf("\t\t! %s", vname
);
178 dis_stv(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
180 uint_t var
= DIF_INSTR_VAR(instr
);
183 mdb_printf("%-4s %%r%u, DIF_VAR(%x)", name
, DIF_INSTR_RS(instr
), var
);
185 if ((vname
= dis_varname(dp
, var
, dis_scope(name
))) != NULL
)
186 mdb_printf("\t\t! %s", vname
);
190 dis_setx(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
192 uint_t intptr
= DIF_INSTR_INTEGER(instr
);
194 mdb_printf("%-4s DIF_INTEGER[%u], %%r%u", name
,
195 intptr
, DIF_INSTR_RD(instr
));
197 if (dp
!= NULL
&& intptr
< dp
->dtdo_intlen
) {
198 uint64_t *ip
= mdb_alloc(dp
->dtdo_intlen
*
199 sizeof (uint64_t), UM_SLEEP
| UM_GC
);
201 if (mdb_vread(ip
, dp
->dtdo_intlen
* sizeof (uint64_t),
202 (uintptr_t)dp
->dtdo_inttab
) == -1)
203 mdb_warn("failed to read data at %p", dp
->dtdo_inttab
);
205 mdb_printf("\t\t! 0x%llx", ip
[intptr
]);
210 dis_sets(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
212 uint_t strptr
= DIF_INSTR_STRING(instr
);
214 mdb_printf("%-4s DIF_STRING[%u], %%r%u", name
,
215 strptr
, DIF_INSTR_RD(instr
));
217 if (dp
!= NULL
&& strptr
< dp
->dtdo_strlen
) {
218 char *str
= mdb_alloc(dp
->dtdo_strlen
, UM_SLEEP
| UM_GC
);
220 if (mdb_vread(str
, dp
->dtdo_strlen
,
221 (uintptr_t)dp
->dtdo_strtab
) == -1)
222 mdb_warn("failed to read data at %p", dp
->dtdo_strtab
);
224 mdb_printf("\t\t! \"%s\"", str
+ strptr
);
230 dis_ret(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
232 mdb_printf("%-4s %%r%u", name
, DIF_INSTR_RD(instr
));
237 dis_call(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
239 uint_t subr
= DIF_INSTR_SUBR(instr
);
241 mdb_printf("%-4s DIF_SUBR(%u), %%r%u\t\t! %s",
242 name
, subr
, DIF_INSTR_RD(instr
), dtrace_subrstr(NULL
, subr
));
247 dis_pushts(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
249 static const char *const tnames
[] = { "TYPE_CTF", "TYPE_STRING" };
250 uint_t type
= DIF_INSTR_TYPE(instr
);
252 mdb_printf("%-4s DIF_TYPE(%u), %%r%u, %%r%u",
253 name
, type
, DIF_INSTR_R2(instr
), DIF_INSTR_RS(instr
));
255 if (type
< sizeof (tnames
) / sizeof (tnames
[0]))
256 mdb_printf("\t\t! %s", tnames
[type
]);
261 dis_xlate(const dtrace_difo_t
*dp
, const char *name
, dif_instr_t instr
)
263 mdb_printf("%-4s DIF_XLREF[%u], %%r%u", name
,
264 DIF_INSTR_XLREF(instr
), DIF_INSTR_RD(instr
));
268 dis_typestr(const dtrace_diftype_t
*t
, char *buf
, size_t len
)
272 switch (t
->dtdt_kind
) {
274 (void) strcpy(kind
, "D type");
276 case DIF_TYPE_STRING
:
277 (void) strcpy(kind
, "string");
280 (void) mdb_snprintf(kind
, sizeof (kind
), "0x%x", t
->dtdt_kind
);
283 if (t
->dtdt_flags
& DIF_TF_BYREF
) {
284 (void) mdb_snprintf(buf
, len
,
285 "%s by ref (size %lu)",
286 kind
, (ulong_t
)t
->dtdt_size
);
288 (void) mdb_snprintf(buf
, len
, "%s (size %lu)",
289 kind
, (ulong_t
)t
->dtdt_size
);
296 dis(uintptr_t addr
, dtrace_difo_t
*dp
)
298 static const struct opent
{
300 void (*op_func
)(const dtrace_difo_t
*,
301 const char *, dif_instr_t
);
303 { "(illegal opcode)", dis_str
},
304 { "or", dis_log
}, /* DIF_OP_OR */
305 { "xor", dis_log
}, /* DIF_OP_XOR */
306 { "and", dis_log
}, /* DIF_OP_AND */
307 { "sll", dis_log
}, /* DIF_OP_SLL */
308 { "srl", dis_log
}, /* DIF_OP_SRL */
309 { "sub", dis_log
}, /* DIF_OP_SUB */
310 { "add", dis_log
}, /* DIF_OP_ADD */
311 { "mul", dis_log
}, /* DIF_OP_MUL */
312 { "sdiv", dis_log
}, /* DIF_OP_SDIV */
313 { "udiv", dis_log
}, /* DIF_OP_UDIV */
314 { "srem", dis_log
}, /* DIF_OP_SREM */
315 { "urem", dis_log
}, /* DIF_OP_UREM */
316 { "not", dis_r1rd
}, /* DIF_OP_NOT */
317 { "mov", dis_r1rd
}, /* DIF_OP_MOV */
318 { "cmp", dis_cmp
}, /* DIF_OP_CMP */
319 { "tst", dis_tst
}, /* DIF_OP_TST */
320 { "ba", dis_branch
}, /* DIF_OP_BA */
321 { "be", dis_branch
}, /* DIF_OP_BE */
322 { "bne", dis_branch
}, /* DIF_OP_BNE */
323 { "bg", dis_branch
}, /* DIF_OP_BG */
324 { "bgu", dis_branch
}, /* DIF_OP_BGU */
325 { "bge", dis_branch
}, /* DIF_OP_BGE */
326 { "bgeu", dis_branch
}, /* DIF_OP_BGEU */
327 { "bl", dis_branch
}, /* DIF_OP_BL */
328 { "blu", dis_branch
}, /* DIF_OP_BLU */
329 { "ble", dis_branch
}, /* DIF_OP_BLE */
330 { "bleu", dis_branch
}, /* DIF_OP_BLEU */
331 { "ldsb", dis_load
}, /* DIF_OP_LDSB */
332 { "ldsh", dis_load
}, /* DIF_OP_LDSH */
333 { "ldsw", dis_load
}, /* DIF_OP_LDSW */
334 { "ldub", dis_load
}, /* DIF_OP_LDUB */
335 { "lduh", dis_load
}, /* DIF_OP_LDUH */
336 { "lduw", dis_load
}, /* DIF_OP_LDUW */
337 { "ldx", dis_load
}, /* DIF_OP_LDX */
338 { "ret", dis_ret
}, /* DIF_OP_RET */
339 { "nop", dis_str
}, /* DIF_OP_NOP */
340 { "setx", dis_setx
}, /* DIF_OP_SETX */
341 { "sets", dis_sets
}, /* DIF_OP_SETS */
342 { "scmp", dis_cmp
}, /* DIF_OP_SCMP */
343 { "ldga", dis_lda
}, /* DIF_OP_LDGA */
344 { "ldgs", dis_ldv
}, /* DIF_OP_LDGS */
345 { "stgs", dis_stv
}, /* DIF_OP_STGS */
346 { "ldta", dis_lda
}, /* DIF_OP_LDTA */
347 { "ldts", dis_ldv
}, /* DIF_OP_LDTS */
348 { "stts", dis_stv
}, /* DIF_OP_STTS */
349 { "sra", dis_log
}, /* DIF_OP_SRA */
350 { "call", dis_call
}, /* DIF_OP_CALL */
351 { "pushtr", dis_pushts
}, /* DIF_OP_PUSHTR */
352 { "pushtv", dis_pushts
}, /* DIF_OP_PUSHTV */
353 { "popts", dis_str
}, /* DIF_OP_POPTS */
354 { "flushts", dis_str
}, /* DIF_OP_FLUSHTS */
355 { "ldgaa", dis_ldv
}, /* DIF_OP_LDGAA */
356 { "ldtaa", dis_ldv
}, /* DIF_OP_LDTAA */
357 { "stgaa", dis_stv
}, /* DIF_OP_STGAA */
358 { "sttaa", dis_stv
}, /* DIF_OP_STTAA */
359 { "ldls", dis_ldv
}, /* DIF_OP_LDLS */
360 { "stls", dis_stv
}, /* DIF_OP_STLS */
361 { "allocs", dis_r1rd
}, /* DIF_OP_ALLOCS */
362 { "copys", dis_log
}, /* DIF_OP_COPYS */
363 { "stb", dis_store
}, /* DIF_OP_STB */
364 { "sth", dis_store
}, /* DIF_OP_STH */
365 { "stw", dis_store
}, /* DIF_OP_STW */
366 { "stx", dis_store
}, /* DIF_OP_STX */
367 { "uldsb", dis_load
}, /* DIF_OP_ULDSB */
368 { "uldsh", dis_load
}, /* DIF_OP_ULDSH */
369 { "uldsw", dis_load
}, /* DIF_OP_ULDSW */
370 { "uldub", dis_load
}, /* DIF_OP_ULDUB */
371 { "ulduh", dis_load
}, /* DIF_OP_ULDUH */
372 { "ulduw", dis_load
}, /* DIF_OP_ULDUW */
373 { "uldx", dis_load
}, /* DIF_OP_ULDX */
374 { "rldsb", dis_load
}, /* DIF_OP_RLDSB */
375 { "rldsh", dis_load
}, /* DIF_OP_RLDSH */
376 { "rldsw", dis_load
}, /* DIF_OP_RLDSW */
377 { "rldub", dis_load
}, /* DIF_OP_RLDUB */
378 { "rlduh", dis_load
}, /* DIF_OP_RLDUH */
379 { "rlduw", dis_load
}, /* DIF_OP_RLDUW */
380 { "rldx", dis_load
}, /* DIF_OP_RLDX */
381 { "xlate", dis_xlate
}, /* DIF_OP_XLATE */
382 { "xlarg", dis_xlate
}, /* DIF_OP_XLARG */
385 dif_instr_t instr
, opcode
;
386 const struct opent
*op
;
388 if (mdb_vread(&instr
, sizeof (dif_instr_t
), addr
) == -1) {
389 mdb_warn("failed to read DIF instruction at %p", addr
);
393 opcode
= DIF_INSTR_OP(instr
);
395 if (opcode
>= sizeof (optab
) / sizeof (optab
[0]))
396 opcode
= 0; /* force invalid opcode message */
399 mdb_printf("%0?p %08x ", addr
, instr
);
400 op
->op_func(dp
, op
->op_name
, instr
);
402 mdb_set_dot(addr
+ sizeof (dif_instr_t
));
409 difo(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
411 dtrace_difo_t difo
, *dp
= &difo
;
412 uintptr_t instr
, limit
;
419 if (!(flags
& DCMD_ADDRSPEC
))
422 if (mdb_vread(dp
, sizeof (dtrace_difo_t
), addr
) == -1) {
423 mdb_warn("couldn't read dtrace_difo_t at %p", addr
);
427 mdb_printf("%<u>DIF Object 0x%p%</u> (refcnt=%d)\n\n",
428 addr
, dp
->dtdo_refcnt
);
429 mdb_printf("%<b>%-?s %-8s %s%</b>\n", "ADDR", "OPCODE", "INSTRUCTION");
431 mdb_set_dot((uintmax_t)(uintptr_t)dp
->dtdo_buf
);
432 limit
= (uintptr_t)dp
->dtdo_buf
+ dp
->dtdo_len
* sizeof (dif_instr_t
);
434 while ((instr
= mdb_get_dot()) < limit
)
437 if (dp
->dtdo_varlen
!= 0) {
438 mdb_printf("\n%<b>%-16s %-4s %-3s %-3s %-4s %s%</b>\n",
439 "NAME", "ID", "KND", "SCP", "FLAG", "TYPE");
442 varsize
= sizeof (dtrace_difv_t
) * dp
->dtdo_varlen
;
443 dvp
= mdb_alloc(varsize
, UM_SLEEP
| UM_GC
);
445 if (mdb_vread(dvp
, varsize
, (uintptr_t)dp
->dtdo_vartab
) == -1) {
446 mdb_warn("couldn't read dtdo_vartab");
450 str
= mdb_alloc(dp
->dtdo_strlen
, UM_SLEEP
| UM_GC
);
452 if (mdb_vread(str
, dp
->dtdo_strlen
, (uintptr_t)dp
->dtdo_strtab
) == -1) {
453 mdb_warn("couldn't read dtdo_strtab");
457 for (i
= 0; i
< dp
->dtdo_varlen
; i
++) {
458 dtrace_difv_t
*v
= &dvp
[i
];
459 char kind
[4], scope
[4], flags
[16] = { 0 };
461 switch (v
->dtdv_kind
) {
462 case DIFV_KIND_ARRAY
:
463 (void) strcpy(kind
, "arr");
465 case DIFV_KIND_SCALAR
:
466 (void) strcpy(kind
, "scl");
469 (void) mdb_snprintf(kind
, sizeof (kind
),
473 switch (v
->dtdv_scope
) {
474 case DIFV_SCOPE_GLOBAL
:
475 (void) strcpy(scope
, "glb");
477 case DIFV_SCOPE_THREAD
:
478 (void) strcpy(scope
, "tls");
480 case DIFV_SCOPE_LOCAL
:
481 (void) strcpy(scope
, "loc");
484 (void) mdb_snprintf(scope
, sizeof (scope
),
485 "%u", v
->dtdv_scope
);
488 if (v
->dtdv_flags
& ~(DIFV_F_REF
| DIFV_F_MOD
)) {
489 (void) mdb_snprintf(flags
, sizeof (flags
), "/0x%x",
490 v
->dtdv_flags
& ~(DIFV_F_REF
| DIFV_F_MOD
));
493 if (v
->dtdv_flags
& DIFV_F_REF
)
494 (void) strcat(flags
, "/r");
495 if (v
->dtdv_flags
& DIFV_F_MOD
)
496 (void) strcat(flags
, "/w");
498 mdb_printf("%-16s %-4x %-3s %-3s %-4s %s\n",
500 v
->dtdv_id
, kind
, scope
, flags
+ 1,
501 dis_typestr(&v
->dtdv_type
, type
, sizeof (type
)));
504 mdb_printf("\n%<b>RETURN%</b>\n%s\n\n",
505 dis_typestr(&dp
->dtdo_rtype
, type
, sizeof (type
)));
512 difinstr(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
514 if (!(flags
& DCMD_ADDRSPEC
))
517 return (dis(addr
, NULL
));
522 dof_hdr(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
529 if (!(flags
& DCMD_ADDRSPEC
))
530 addr
= 0; /* assume base of file in file target */
532 if (mdb_vread(&h
, sizeof (h
), addr
) != sizeof (h
)) {
533 mdb_warn("failed to read header at %p", addr
);
537 mdb_printf("dofh_ident.id_magic = 0x%x, %c, %c, %c\n",
538 h
.dofh_ident
[DOF_ID_MAG0
], h
.dofh_ident
[DOF_ID_MAG1
],
539 h
.dofh_ident
[DOF_ID_MAG2
], h
.dofh_ident
[DOF_ID_MAG3
]);
541 switch (h
.dofh_ident
[DOF_ID_MODEL
]) {
542 case DOF_MODEL_ILP32
:
543 mdb_printf("dofh_ident.id_model = ILP32\n");
546 mdb_printf("dofh_ident.id_model = LP64\n");
549 mdb_printf("dofh_ident.id_model = 0x%x\n",
550 h
.dofh_ident
[DOF_ID_MODEL
]);
553 switch (h
.dofh_ident
[DOF_ID_ENCODING
]) {
555 mdb_printf("dofh_ident.id_encoding = LSB\n");
558 mdb_printf("dofh_ident.id_encoding = MSB\n");
561 mdb_printf("dofh_ident.id_encoding = 0x%x\n",
562 h
.dofh_ident
[DOF_ID_ENCODING
]);
565 mdb_printf("dofh_ident.id_version = %u\n",
566 h
.dofh_ident
[DOF_ID_VERSION
]);
567 mdb_printf("dofh_ident.id_difvers = %u\n",
568 h
.dofh_ident
[DOF_ID_DIFVERS
]);
569 mdb_printf("dofh_ident.id_difireg = %u\n",
570 h
.dofh_ident
[DOF_ID_DIFIREG
]);
571 mdb_printf("dofh_ident.id_diftreg = %u\n",
572 h
.dofh_ident
[DOF_ID_DIFTREG
]);
574 mdb_printf("dofh_flags = 0x%x\n", h
.dofh_flags
);
575 mdb_printf("dofh_hdrsize = %u\n", h
.dofh_hdrsize
);
576 mdb_printf("dofh_secsize = %u\n", h
.dofh_secsize
);
577 mdb_printf("dofh_secnum = %u\n", h
.dofh_secnum
);
578 mdb_printf("dofh_secoff = %llu\n", h
.dofh_secoff
);
579 mdb_printf("dofh_loadsz = %llu\n", h
.dofh_loadsz
);
580 mdb_printf("dofh_filesz = %llu\n", h
.dofh_filesz
);
587 dof_sec_walk(uintptr_t addr
, void *ignored
, int *sec
)
589 mdb_printf("%3d ", (*sec
)++);
590 (void) dof_sec(addr
, DCMD_ADDRSPEC
| DCMD_LOOP
, 0, NULL
);
596 dof_sec(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
601 if (!(flags
& DCMD_ADDRSPEC
))
602 mdb_printf("%<u>%-3s ", "NDX");
604 if (!(flags
& DCMD_ADDRSPEC
) || DCMD_HDRSPEC(flags
)) {
605 mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n",
606 "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFFSET",
610 if (!(flags
& DCMD_ADDRSPEC
)) {
613 if (mdb_walk("dof_sec",
614 (mdb_walk_cb_t
)dof_sec_walk
, &sec
) == -1) {
615 mdb_warn("failed to walk dof_sec");
624 if (mdb_vread(&s
, sizeof (s
), addr
) != sizeof (s
)) {
625 mdb_warn("failed to read section header at %p", addr
);
629 mdb_printf("%?p ", addr
);
631 if ((name
= dof_sec_name(s
.dofs_type
)) != NULL
)
632 mdb_printf("%-10s ", name
);
634 mdb_printf("%-10u ", s
.dofs_type
);
636 mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s
.dofs_align
,
637 s
.dofs_flags
, s
.dofs_entsize
, s
.dofs_offset
, s
.dofs_size
);
643 dof_sec_walk_init(mdb_walk_state_t
*wsp
)
648 if (mdb_vread(&h
, sizeof (h
), wsp
->walk_addr
) != sizeof (h
)) {
649 mdb_warn("failed to read DOF header at %p", wsp
->walk_addr
);
653 size
= sizeof (dof_hdr_t
) + sizeof (dof_sec_t
) * h
.dofh_secnum
;
654 hp
= mdb_alloc(size
, UM_SLEEP
);
656 if (mdb_vread(hp
, size
, wsp
->walk_addr
) != size
) {
657 mdb_warn("failed to read DOF sections at %p", wsp
->walk_addr
);
662 wsp
->walk_arg
= NULL
;
669 dof_sec_walk_step(mdb_walk_state_t
*wsp
)
671 uint_t i
= (uintptr_t)wsp
->walk_arg
;
672 size_t off
= sizeof (dof_hdr_t
) + sizeof (dof_sec_t
) * i
;
673 dof_hdr_t
*hp
= wsp
->walk_data
;
674 dof_sec_t
*sp
= (dof_sec_t
*)((uintptr_t)hp
+ off
);
676 if (i
>= hp
->dofh_secnum
)
679 wsp
->walk_arg
= (void *)(uintptr_t)(i
+ 1);
680 return (wsp
->walk_callback(wsp
->walk_addr
+ off
, sp
, wsp
->walk_cbdata
));
684 dof_sec_walk_fini(mdb_walk_state_t
*wsp
)
686 dof_hdr_t
*hp
= wsp
->walk_data
;
687 mdb_free(hp
, sizeof (dof_hdr_t
) + sizeof (dof_sec_t
) * hp
->dofh_secnum
);
692 dof_ecbdesc(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
696 if (argc
!= 0 || !(flags
& DCMD_ADDRSPEC
))
699 if (mdb_vread(&e
, sizeof (e
), addr
) != sizeof (e
)) {
700 mdb_warn("failed to read ecbdesc at %p", addr
);
704 mdb_printf("dofe_probes = %d\n", e
.dofe_probes
);
705 mdb_printf("dofe_actions = %d\n", e
.dofe_actions
);
706 mdb_printf("dofe_pred = %d\n", e
.dofe_pred
);
707 mdb_printf("dofe_uarg = 0x%llx\n", e
.dofe_uarg
);
714 dof_probedesc(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
718 if (argc
!= 0 || !(flags
& DCMD_ADDRSPEC
))
721 if (mdb_vread(&p
, sizeof (p
), addr
) != sizeof (p
)) {
722 mdb_warn("failed to read probedesc at %p", addr
);
726 mdb_printf("dofp_strtab = %d\n", p
.dofp_strtab
);
727 mdb_printf("dofp_provider = %u\n", p
.dofp_provider
);
728 mdb_printf("dofp_mod = %u\n", p
.dofp_mod
);
729 mdb_printf("dofp_func = %u\n", p
.dofp_func
);
730 mdb_printf("dofp_name = %u\n", p
.dofp_name
);
731 mdb_printf("dofp_id = %u\n", p
.dofp_id
);
738 dof_actdesc(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
742 if (argc
!= 0 || !(flags
& DCMD_ADDRSPEC
))
745 if (mdb_vread(&a
, sizeof (a
), addr
) != sizeof (a
)) {
746 mdb_warn("failed to read actdesc at %p", addr
);
750 mdb_printf("dofa_difo = %d\n", a
.dofa_difo
);
751 mdb_printf("dofa_strtab = %d\n", a
.dofa_strtab
);
752 mdb_printf("dofa_kind = %u\n", a
.dofa_kind
);
753 mdb_printf("dofa_ntuple = %u\n", a
.dofa_ntuple
);
754 mdb_printf("dofa_arg = 0x%llx\n", a
.dofa_arg
);
755 mdb_printf("dofa_uarg = 0x%llx\n", a
.dofa_uarg
);
762 dof_relohdr(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
766 if (argc
!= 0 || !(flags
& DCMD_ADDRSPEC
))
769 if (mdb_vread(&r
, sizeof (r
), addr
) != sizeof (r
)) {
770 mdb_warn("failed to read relohdr at %p", addr
);
774 mdb_printf("dofr_strtab = %d\n", r
.dofr_strtab
);
775 mdb_printf("dofr_relsec = %d\n", r
.dofr_relsec
);
776 mdb_printf("dofr_tgtsec = %d\n", r
.dofr_tgtsec
);
783 dof_relodesc(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
787 if (argc
!= 0 || !(flags
& DCMD_ADDRSPEC
))
790 if (mdb_vread(&r
, sizeof (r
), addr
) != sizeof (r
)) {
791 mdb_warn("failed to read relodesc at %p", addr
);
795 mdb_printf("dofr_name = %u\n", r
.dofr_name
);
796 mdb_printf("dofr_type = %u\n", r
.dofr_type
);
797 mdb_printf("dofr_offset = 0x%llx\n", r
.dofr_offset
);
798 mdb_printf("dofr_data = 0x%llx\n", r
.dofr_data
);
804 dof_sect_strtab(uintptr_t addr
, dof_sec_t
*sec
)
809 sz
= (size_t)sec
->dofs_size
;
810 strtab
= mdb_alloc(sz
, UM_SLEEP
| UM_GC
);
811 if (mdb_vread(strtab
, sz
, addr
+ sec
->dofs_offset
) != sz
) {
812 mdb_warn("failed to read string table");
816 mdb_printf("size = %lx\n", sz
);
818 for (i
= 0; i
< sz
; i
++) {
819 if (strtab
[i
] == '\0')
822 mdb_printf("%c", strtab
[i
]);
831 dof_sect_provider(dof_hdr_t
*dofh
, uintptr_t addr
, dof_sec_t
*sec
,
837 uint32_t *offs
, *enoffs
;
838 uint8_t *args
= NULL
;
841 dof_stridx_t narg
, xarg
;
843 sz
= MIN(sec
->dofs_size
, sizeof (dof_provider_t
));
844 if (mdb_vread(&pv
, sz
, addr
+ sec
->dofs_offset
) != sz
) {
845 mdb_warn("failed to read DOF provider");
849 sz
= dofs
[pv
.dofpv_strtab
].dofs_size
;
850 strtab
= mdb_alloc(sz
, UM_SLEEP
| UM_GC
);
851 if (mdb_vread(strtab
, sz
, addr
+
852 dofs
[pv
.dofpv_strtab
].dofs_offset
) != sz
) {
853 mdb_warn("failed to read string table");
857 mdb_printf("%lx provider %s {\n", (ulong_t
)(addr
+ sec
->dofs_offset
),
858 strtab
+ pv
.dofpv_name
);
860 sz
= dofs
[pv
.dofpv_prargs
].dofs_size
;
862 args
= mdb_alloc(sz
, UM_SLEEP
| UM_GC
);
863 if (mdb_vread(args
, sz
, addr
+
864 dofs
[pv
.dofpv_prargs
].dofs_offset
) != sz
) {
865 mdb_warn("failed to read args");
870 sz
= dofs
[pv
.dofpv_proffs
].dofs_size
;
871 offs
= mdb_alloc(sz
, UM_SLEEP
| UM_GC
);
872 if (mdb_vread(offs
, sz
, addr
+ dofs
[pv
.dofpv_proffs
].dofs_offset
)
874 mdb_warn("failed to read offsets");
879 if (dofh
->dofh_ident
[DOF_ID_VERSION
] != DOF_VERSION_1
||
880 pv
.dofpv_prenoffs
== 0) {
881 sz
= dofs
[pv
.dofpv_prenoffs
].dofs_size
;
882 enoffs
= mdb_alloc(sz
, UM_SLEEP
| UM_GC
);
883 if (mdb_vread(enoffs
, sz
, addr
+
884 dofs
[pv
.dofpv_prenoffs
].dofs_offset
) != sz
) {
885 mdb_warn("failed to read is-enabled offsets");
890 sz
= dofs
[pv
.dofpv_probes
].dofs_size
;
891 p
= mdb_alloc(sz
, UM_SLEEP
| UM_GC
);
892 if (mdb_vread(p
, sz
, addr
+ dofs
[pv
.dofpv_probes
].dofs_offset
) != sz
) {
893 mdb_warn("failed to read probes");
897 (void) mdb_inc_indent(2);
899 for (i
= 0; i
< sz
/ dofs
[pv
.dofpv_probes
].dofs_entsize
; i
++) {
900 pb
= (dof_probe_t
*)(uintptr_t)(p
+
901 i
* dofs
[pv
.dofpv_probes
].dofs_entsize
);
903 mdb_printf("%lx probe %s:%s {\n", (ulong_t
)(addr
+
904 dofs
[pv
.dofpv_probes
].dofs_offset
+
905 i
* dofs
[pv
.dofpv_probes
].dofs_entsize
),
906 strtab
+ pb
->dofpr_func
,
907 strtab
+ pb
->dofpr_name
);
909 (void) mdb_inc_indent(2);
910 mdb_printf("addr: %p\n", (ulong_t
)pb
->dofpr_addr
);
911 mdb_printf("offs: ");
912 for (j
= 0; j
< pb
->dofpr_noffs
; j
++) {
913 mdb_printf("%s %x", "," + (j
== 0),
914 offs
[pb
->dofpr_offidx
+ j
]);
918 if (dofh
->dofh_ident
[DOF_ID_VERSION
] != DOF_VERSION_1
) {
919 mdb_printf("enoffs: ");
920 if (enoffs
== NULL
) {
921 if (pb
->dofpr_nenoffs
!= 0)
922 mdb_printf("<error>");
924 for (j
= 0; j
< pb
->dofpr_nenoffs
; j
++) {
925 mdb_printf("%s %x", "," + (j
== 0),
926 enoffs
[pb
->dofpr_enoffidx
+ j
]);
932 mdb_printf("nargs:");
933 narg
= pb
->dofpr_nargv
;
934 for (j
= 0; j
< pb
->dofpr_nargc
; j
++) {
935 mdb_printf("%s %s", "," + (j
== 0), strtab
+ narg
);
936 narg
+= strlen(strtab
+ narg
) + 1;
939 mdb_printf("xargs:");
940 xarg
= pb
->dofpr_xargv
;
941 for (j
= 0; j
< pb
->dofpr_xargc
; j
++) {
942 mdb_printf("%s %s", "," + (j
== 0), strtab
+ xarg
);
943 xarg
+= strlen(strtab
+ xarg
) + 1;
947 for (j
= 0; j
< pb
->dofpr_xargc
; j
++) {
948 mdb_printf("%s %d->%d", "," + (j
== 0),
949 args
[pb
->dofpr_argidx
+ j
], j
);
952 (void) mdb_dec_indent(2);
956 (void) mdb_dec_indent(2);
963 dof_sect_prargs(uintptr_t addr
, dof_sec_t
*sec
)
968 for (i
= 0; i
< sec
->dofs_size
; i
++) {
969 if (mdb_vread(&arg
, sizeof (arg
),
970 addr
+ sec
->dofs_offset
+ i
) != sizeof (arg
)) {
971 mdb_warn("failed to read argument");
975 mdb_printf("%d ", arg
);
988 dofdump(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
995 if (mdb_vread(&dofh
, sizeof (dof_hdr_t
), addr
) != sizeof (dof_hdr_t
)) {
996 mdb_warn("failed to read DOF header");
1000 dofs
= mdb_alloc(sizeof (dof_sec_t
) * dofh
.dofh_secnum
,
1003 for (i
= 0; i
< dofh
.dofh_secnum
; i
++) {
1004 if (mdb_vread(&dofs
[i
], sizeof (dof_sec_t
), dofh
.dofh_secoff
+
1005 addr
+ i
* dofh
.dofh_secsize
) != sizeof (dof_sec_t
)) {
1006 mdb_warn("failed to read DOF sections");
1011 for (i
= 0; i
< dofh
.dofh_secnum
; i
++) {
1012 mdb_printf("%lx Section %d: ", (ulong_t
)
1013 (dofh
.dofh_secoff
+ addr
+ i
* dofh
.dofh_secsize
), i
);
1015 if ((name
= dof_sec_name(dofs
[i
].dofs_type
)) != NULL
)
1016 mdb_printf("%s\n", name
);
1018 mdb_printf("%u\n", dofs
[i
].dofs_type
);
1020 (void) mdb_inc_indent(2);
1021 switch (dofs
[i
].dofs_type
) {
1022 case DOF_SECT_PROVIDER
:
1023 (void) dof_sect_provider(&dofh
, addr
, &dofs
[i
], dofs
);
1025 case DOF_SECT_STRTAB
:
1026 (void) dof_sect_strtab(addr
, &dofs
[i
]);
1028 case DOF_SECT_PRARGS
:
1029 (void) dof_sect_prargs(addr
, &dofs
[i
]);
1032 (void) mdb_dec_indent(2);
1040 static const mdb_dcmd_t common_dcmds
[] = {
1041 { "difinstr", ":", "disassemble a DIF instruction", difinstr
},
1042 { "difo", ":", "print a DIF object", difo
},
1043 { "dof_hdr", "?", "print a DOF header", dof_hdr
},
1044 { "dof_sec", ":", "print a DOF section header", dof_sec
},
1045 { "dof_ecbdesc", ":", "print a DOF ecbdesc", dof_ecbdesc
},
1046 { "dof_probedesc", ":", "print a DOF probedesc", dof_probedesc
},
1047 { "dof_actdesc", ":", "print a DOF actdesc", dof_actdesc
},
1048 { "dof_relohdr", ":", "print a DOF relocation header", dof_relohdr
},
1049 { "dof_relodesc", ":", "print a DOF relodesc", dof_relodesc
},
1050 { "dofdump", ":", "dump DOF", dofdump
},
1054 static const mdb_walker_t common_walkers
[] = {
1055 { "dof_sec", "walk DOF section header table given header address",
1056 dof_sec_walk_init
, dof_sec_walk_step
, dof_sec_walk_fini
},
1060 static mdb_modinfo_t modinfo
= {
1061 MDB_API_VERSION
, NULL
, NULL
1064 const mdb_modinfo_t
*
1067 uint_t d
= 0, kd
= 0, w
= 0, kw
= 0;
1068 const mdb_walker_t
*wp
;
1069 const mdb_dcmd_t
*dp
;
1071 for (dp
= common_dcmds
; dp
->dc_name
!= NULL
; dp
++)
1072 d
++; /* count common dcmds */
1074 for (wp
= common_walkers
; wp
->walk_name
!= NULL
; wp
++)
1075 w
++; /* count common walkers */
1078 for (dp
= kernel_dcmds
; dp
->dc_name
!= NULL
; dp
++)
1079 kd
++; /* count kernel dcmds */
1081 for (wp
= kernel_walkers
; wp
->walk_name
!= NULL
; wp
++)
1082 kw
++; /* count common walkers */
1085 modinfo
.mi_dcmds
= mdb_zalloc(sizeof (*dp
) * (d
+ kd
+ 1), UM_SLEEP
);
1086 modinfo
.mi_walkers
= mdb_zalloc(sizeof (*wp
) * (w
+ kw
+ 1), UM_SLEEP
);
1088 bcopy(common_dcmds
, (void *)modinfo
.mi_dcmds
, sizeof (*dp
) * d
);
1089 bcopy(common_walkers
, (void *)modinfo
.mi_walkers
, sizeof (*wp
) * w
);
1092 bcopy(kernel_dcmds
, (void *)
1093 (modinfo
.mi_dcmds
+ d
), sizeof (*dp
) * kd
);
1094 bcopy(kernel_walkers
, (void *)
1095 (modinfo
.mi_walkers
+ w
), sizeof (*wp
) * kw
);
1103 const mdb_walker_t
*wp
;
1104 const mdb_dcmd_t
*dp
;
1105 uint_t d
= 0, w
= 0;
1107 for (dp
= modinfo
.mi_dcmds
; dp
->dc_name
!= NULL
; dp
++)
1110 for (wp
= modinfo
.mi_walkers
; wp
->walk_name
!= NULL
; wp
++)
1113 mdb_free((void *)modinfo
.mi_dcmds
, sizeof (*dp
) * (d
+ 1));
1114 mdb_free((void *)modinfo
.mi_walkers
, sizeof (*wp
) * (w
+ 1));