17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*a727d47aSjwadams * Common Development and Distribution License (the "License"). 6*a727d47aSjwadams * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*a727d47aSjwadams * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * Format String Decoder 307c478bd9Sstevel@tonic-gate * 317c478bd9Sstevel@tonic-gate * This file provides the core engine for converting strings of format 327c478bd9Sstevel@tonic-gate * characters into formatted output. The various format dcmds invoke the 337c478bd9Sstevel@tonic-gate * mdb_fmt_print() function below with a target, address space identifier, 347c478bd9Sstevel@tonic-gate * address, count, and format character, and it reads the required data from 357c478bd9Sstevel@tonic-gate * the target and prints the formatted output to stdout. Since nearly two 367c478bd9Sstevel@tonic-gate * thirds of the format characters can be expressed as simple printf format 377c478bd9Sstevel@tonic-gate * strings, we implement the engine using the lookup table below. Each entry 387c478bd9Sstevel@tonic-gate * provides either a pointer to a printf format string or a pointer to a 397c478bd9Sstevel@tonic-gate * function to perform special processing. For the printf case, the 407c478bd9Sstevel@tonic-gate * corresponding data size in bytes is also supplied. The printf processing 417c478bd9Sstevel@tonic-gate * code handles 1, 2, 4, and 8-byte reads into an unsigned integer container 427c478bd9Sstevel@tonic-gate * of the given size, and then simply calls mdb_iob_printf with the integer 437c478bd9Sstevel@tonic-gate * and format string. This handles all printf cases, except when unsigned 447c478bd9Sstevel@tonic-gate * promotion of an integer type in the varargs list does not perform the 457c478bd9Sstevel@tonic-gate * conversion we require to get the proper result. With the current set of 467c478bd9Sstevel@tonic-gate * format characters, this case only occurs twice: we need a 4-byte float 477c478bd9Sstevel@tonic-gate * to get promoted to 8-byte double for the 'f' format so it can be 487c478bd9Sstevel@tonic-gate * correctly formatted by %f, and we need a 1-byte int8_t to get promoted 497c478bd9Sstevel@tonic-gate * with sign extension to a 4-byte int32_t for the 'v' format so it can be 507c478bd9Sstevel@tonic-gate * correctly formatted by %d. We provide explicit functions to handle these 517c478bd9Sstevel@tonic-gate * cases, as well as to handle special format characters such as 'i', etc. 527c478bd9Sstevel@tonic-gate * We also provide a cmd_formats() dcmd function below which prints a table 537c478bd9Sstevel@tonic-gate * of the output formats and their sizes. Format characters that provide 547c478bd9Sstevel@tonic-gate * custom functions provide their help description string explicitly. All 557c478bd9Sstevel@tonic-gate * the printf formats have their help strings generated automatically by 567c478bd9Sstevel@tonic-gate * our printf "unparser" mdb_iob_format2str(). 577c478bd9Sstevel@tonic-gate */ 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate #include <mdb/mdb_types.h> 607c478bd9Sstevel@tonic-gate #include <mdb/mdb_target.h> 617c478bd9Sstevel@tonic-gate #include <mdb/mdb_io.h> 627c478bd9Sstevel@tonic-gate #include <mdb/mdb_err.h> 637c478bd9Sstevel@tonic-gate #include <mdb/mdb_string.h> 647c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 657c478bd9Sstevel@tonic-gate #include <mdb/mdb.h> 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate #define FUNCP(p) ((void *)(p)) /* Cast to f_ptr type */ 687c478bd9Sstevel@tonic-gate #define SZ_NONE ((size_t)-1L) /* Format does not change dot */ 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate typedef mdb_tgt_addr_t mdb_fmt_func_f(mdb_tgt_t *, 717c478bd9Sstevel@tonic-gate mdb_tgt_as_t, mdb_tgt_addr_t, size_t); 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* 747c478bd9Sstevel@tonic-gate * There are several 'special' characters that are handled outside of 757c478bd9Sstevel@tonic-gate * mdb_fmt_print(). These are characters that write (vwWZ) and characters that 767c478bd9Sstevel@tonic-gate * match (lLM). We include them here so that ::formats can display an 777c478bd9Sstevel@tonic-gate * appropriate message, but they are handled specially by write_arglist() and 787c478bd9Sstevel@tonic-gate * match_arglist() in mdb_cmds.c. 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate #define FMT_NONE 0x0 /* Format character is not supported */ 817c478bd9Sstevel@tonic-gate #define FMT_FUNC 0x1 /* f_ptr is a mdb_fmt_func_f to call */ 827c478bd9Sstevel@tonic-gate #define FMT_PRINTF 0x2 /* f_ptr is a const char * format string */ 837c478bd9Sstevel@tonic-gate #define FMT_MATCH 0x4 /* Match command (not supported here) */ 847c478bd9Sstevel@tonic-gate #define FMT_WRITE 0x8 /* Command writes to address space */ 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate #define FMT_TYPE(x) ((x) & 0x7) /* Excludes modifying flags (FMT_WRITE) */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate typedef struct mdb_fmt_desc { 897c478bd9Sstevel@tonic-gate int f_type; /* Type of format (see above) */ 907c478bd9Sstevel@tonic-gate void *f_ptr; /* Data pointer (see above) */ 917c478bd9Sstevel@tonic-gate const char *f_help; /* Additional help string */ 927c478bd9Sstevel@tonic-gate size_t f_size; /* Size of type in bytes, or SZ_NONE */ 937c478bd9Sstevel@tonic-gate } mdb_fmt_desc_t; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate static const char help_plus[] = "increment dot by the count"; 967c478bd9Sstevel@tonic-gate static const char help_minus[] = "decrement dot by the count"; 977c478bd9Sstevel@tonic-gate static const char help_escchr[] = "character using C character notation"; 987c478bd9Sstevel@tonic-gate static const char help_swapint[] = "swap bytes and shorts"; 997c478bd9Sstevel@tonic-gate static const char help_dotinstr[] = "address and disassembled instruction"; 1007c478bd9Sstevel@tonic-gate static const char help_instr[] = "disassembled instruction"; 1017c478bd9Sstevel@tonic-gate static const char help_escstr[] = "string using C string notation"; 1027c478bd9Sstevel@tonic-gate static const char help_time32[] = "decoded time32_t"; 1037c478bd9Sstevel@tonic-gate static const char help_carat[] = "decrement dot by increment * count"; 1047c478bd9Sstevel@tonic-gate static const char help_dot[] = "dot as symbol+offset"; 1057c478bd9Sstevel@tonic-gate #ifndef _KMDB 1067c478bd9Sstevel@tonic-gate static const char help_f[] = "float"; 1077c478bd9Sstevel@tonic-gate #endif 1087c478bd9Sstevel@tonic-gate static const char help_swapshort[] = "swap bytes"; 1097c478bd9Sstevel@tonic-gate static const char help_nl[] = "newline"; 1107c478bd9Sstevel@tonic-gate static const char help_ws[] = "whitespace"; 1117c478bd9Sstevel@tonic-gate static const char help_rawstr[] = "raw string"; 1127c478bd9Sstevel@tonic-gate static const char help_tab[] = "horizontal tab"; 1137c478bd9Sstevel@tonic-gate static const char help_sdbyte[] = "decimal signed int"; 1147c478bd9Sstevel@tonic-gate static const char help_time64[] = "decoded time64_t"; 1157c478bd9Sstevel@tonic-gate static const char help_binary[] = "binary unsigned long long"; 1167c478bd9Sstevel@tonic-gate static const char help_hex64[] = "hexadecimal long long"; 1177c478bd9Sstevel@tonic-gate static const char help_match32[] = "int"; 1187c478bd9Sstevel@tonic-gate static const char help_match64[] = "long long"; 1197c478bd9Sstevel@tonic-gate static const char help_match16[] = "short"; 1207c478bd9Sstevel@tonic-gate static const char help_uintptr[] = "hexadecimal uintptr_t"; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1237c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 1247c478bd9Sstevel@tonic-gate fmt_dot(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 1257c478bd9Sstevel@tonic-gate { 1267c478bd9Sstevel@tonic-gate uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_INDENT; 1277c478bd9Sstevel@tonic-gate char buf[24]; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate mdb_iob_clrflags(mdb.m_out, oflags); 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate if (mdb.m_flags & MDB_FL_PSYM) { 1327c478bd9Sstevel@tonic-gate while (cnt-- != 0) 1337c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%-#16lla%16T", addr); 1347c478bd9Sstevel@tonic-gate } else { 1357c478bd9Sstevel@tonic-gate (void) mdb_iob_snprintf(buf, sizeof (buf), 1367c478bd9Sstevel@tonic-gate "%#llx:", (u_longlong_t)addr); 1377c478bd9Sstevel@tonic-gate while (cnt-- != 0) 1387c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%-16s%16T", buf); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate mdb_iob_setflags(mdb.m_out, oflags); 1427c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, addr); 1437c478bd9Sstevel@tonic-gate return (addr); 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate #ifndef _KMDB 1477c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 1487c478bd9Sstevel@tonic-gate fmt_float(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 1497c478bd9Sstevel@tonic-gate { 1507c478bd9Sstevel@tonic-gate float f; 1517c478bd9Sstevel@tonic-gate /* 1527c478bd9Sstevel@tonic-gate * We need to handle float as a special case because we need it to be 1537c478bd9Sstevel@tonic-gate * promoted to a double by virtue of appearing as a parameter, and all 1547c478bd9Sstevel@tonic-gate * our generic format handling below is based on integer types. 1557c478bd9Sstevel@tonic-gate */ 1567c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 1577c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &f, sizeof (f), addr) != sizeof (f)) { 1587c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 1597c478bd9Sstevel@tonic-gate break; 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%e", f); 1627c478bd9Sstevel@tonic-gate addr += sizeof (f); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate return (addr); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate #endif 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1697c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 1707c478bd9Sstevel@tonic-gate fmt_plus(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 1717c478bd9Sstevel@tonic-gate { 1727c478bd9Sstevel@tonic-gate return (addr + cnt); 1737c478bd9Sstevel@tonic-gate } 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1767c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 1777c478bd9Sstevel@tonic-gate fmt_minus(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 1787c478bd9Sstevel@tonic-gate { 1797c478bd9Sstevel@tonic-gate return (addr - cnt); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1837c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 1847c478bd9Sstevel@tonic-gate fmt_carat(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 1857c478bd9Sstevel@tonic-gate { 1867c478bd9Sstevel@tonic-gate return (addr - (mdb.m_incr * cnt)); 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1907c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 1917c478bd9Sstevel@tonic-gate fmt_nl(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 1927c478bd9Sstevel@tonic-gate { 1937c478bd9Sstevel@tonic-gate while (cnt-- != 0) 1947c478bd9Sstevel@tonic-gate mdb_iob_nl(mdb.m_out); 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate return (addr); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2007c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 2017c478bd9Sstevel@tonic-gate fmt_ws(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 2027c478bd9Sstevel@tonic-gate { 2037c478bd9Sstevel@tonic-gate mdb_iob_ws(mdb.m_out, cnt); 2047c478bd9Sstevel@tonic-gate return (addr); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2087c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 2097c478bd9Sstevel@tonic-gate fmt_tab(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 2107c478bd9Sstevel@tonic-gate { 2117c478bd9Sstevel@tonic-gate size_t ts = mdb_iob_gettabstop(mdb.m_out); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate mdb_iob_tabstop(mdb.m_out, cnt); 2147c478bd9Sstevel@tonic-gate mdb_iob_tab(mdb.m_out); 2157c478bd9Sstevel@tonic-gate mdb_iob_tabstop(mdb.m_out, ts); 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate return (addr); 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 2217c478bd9Sstevel@tonic-gate fmt_rawstr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_INDENT; 2247c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 2257c478bd9Sstevel@tonic-gate ssize_t nbytes; 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate mdb_iob_clrflags(mdb.m_out, oflags); 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate for (; cnt-- != 0; addr++) { 2307c478bd9Sstevel@tonic-gate do { 2317c478bd9Sstevel@tonic-gate nbytes = mdb_tgt_readstr(t, as, buf, BUFSIZ, addr); 2327c478bd9Sstevel@tonic-gate if (nbytes > 0) { 2337c478bd9Sstevel@tonic-gate mdb_iob_puts(mdb.m_out, buf); 2347c478bd9Sstevel@tonic-gate addr += MIN(nbytes, BUFSIZ - 1); 2357c478bd9Sstevel@tonic-gate } else if (nbytes < 0) { 2367c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 2377c478bd9Sstevel@tonic-gate goto out; 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate } while (nbytes == BUFSIZ); 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate if (cnt != 0) 2427c478bd9Sstevel@tonic-gate mdb_iob_puts(mdb.m_out, "\\0"); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate out: 2457c478bd9Sstevel@tonic-gate mdb_iob_setflags(mdb.m_out, oflags); 2467c478bd9Sstevel@tonic-gate return (addr); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 2507c478bd9Sstevel@tonic-gate fmt_escstr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 2517c478bd9Sstevel@tonic-gate { 2527c478bd9Sstevel@tonic-gate uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_INDENT; 2537c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 2547c478bd9Sstevel@tonic-gate ssize_t nbytes; 2557c478bd9Sstevel@tonic-gate char *s; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate mdb_iob_clrflags(mdb.m_out, oflags); 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate for (; cnt-- != 0; addr++) { 2607c478bd9Sstevel@tonic-gate do { 2617c478bd9Sstevel@tonic-gate nbytes = mdb_tgt_readstr(t, as, buf, BUFSIZ, addr); 2627c478bd9Sstevel@tonic-gate if (nbytes > 0) { 2637c478bd9Sstevel@tonic-gate s = strchr2esc(buf, strlen(buf)); 2647c478bd9Sstevel@tonic-gate mdb_iob_puts(mdb.m_out, s); 2657c478bd9Sstevel@tonic-gate strfree(s); 2667c478bd9Sstevel@tonic-gate addr += MIN(nbytes, BUFSIZ - 1); 2677c478bd9Sstevel@tonic-gate } else if (nbytes < 0) { 2687c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 2697c478bd9Sstevel@tonic-gate goto out; 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate } while (nbytes == BUFSIZ); 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate if (cnt != 0) 2747c478bd9Sstevel@tonic-gate mdb_iob_puts(mdb.m_out, "\\0"); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate out: 2777c478bd9Sstevel@tonic-gate mdb_iob_setflags(mdb.m_out, oflags); 2787c478bd9Sstevel@tonic-gate return (addr); 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 2827c478bd9Sstevel@tonic-gate fmt_escchr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 2837c478bd9Sstevel@tonic-gate { 2847c478bd9Sstevel@tonic-gate char *(*convert)(const char *, size_t); 2857c478bd9Sstevel@tonic-gate ssize_t nbytes; 2867c478bd9Sstevel@tonic-gate char *buf, *s; 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate if (mdb.m_flags & MDB_FL_ADB) 2897c478bd9Sstevel@tonic-gate convert = &strchr2adb; 2907c478bd9Sstevel@tonic-gate else 2917c478bd9Sstevel@tonic-gate convert = &strchr2esc; 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate buf = mdb_alloc(cnt + 1, UM_SLEEP); 2947c478bd9Sstevel@tonic-gate buf[cnt] = 0; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate if ((nbytes = mdb_tgt_aread(t, as, buf, cnt, addr)) > 0) { 2977c478bd9Sstevel@tonic-gate s = convert(buf, nbytes); 2987c478bd9Sstevel@tonic-gate mdb_iob_puts(mdb.m_out, s); 2997c478bd9Sstevel@tonic-gate strfree(s); 3007c478bd9Sstevel@tonic-gate addr += nbytes; 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate mdb_free(buf, cnt + 1); 3047c478bd9Sstevel@tonic-gate return (addr); 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 3087c478bd9Sstevel@tonic-gate fmt_swapshort(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 3097c478bd9Sstevel@tonic-gate { 3107c478bd9Sstevel@tonic-gate ushort_t x; 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 3137c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) { 3147c478bd9Sstevel@tonic-gate x = (x << 8) | (x >> 8); 3157c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%-8x", x); 3167c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, x); 3177c478bd9Sstevel@tonic-gate addr += sizeof (x); 3187c478bd9Sstevel@tonic-gate } else { 3197c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 3207c478bd9Sstevel@tonic-gate break; 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate } 3237c478bd9Sstevel@tonic-gate return (addr); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 3277c478bd9Sstevel@tonic-gate fmt_swapint(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 3287c478bd9Sstevel@tonic-gate { 3297c478bd9Sstevel@tonic-gate uint_t x; 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 3327c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) { 3337c478bd9Sstevel@tonic-gate x = ((x << 24) | ((x << 8) & 0xff0000) | 3347c478bd9Sstevel@tonic-gate ((x >> 8) & 0xff00) | ((x >> 24) & 0xff)); 3357c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%-16x", x); 3367c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, x); 3377c478bd9Sstevel@tonic-gate addr += sizeof (x); 3387c478bd9Sstevel@tonic-gate } else { 3397c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 3407c478bd9Sstevel@tonic-gate break; 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate return (addr); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 3477c478bd9Sstevel@tonic-gate fmt_time32(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 3487c478bd9Sstevel@tonic-gate { 349*a727d47aSjwadams int32_t x; 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 3527c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) { 3537c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%-24Y", (time_t)x); 3547c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, x); 3557c478bd9Sstevel@tonic-gate addr += sizeof (x); 3567c478bd9Sstevel@tonic-gate } else { 3577c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 3587c478bd9Sstevel@tonic-gate break; 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate return (addr); 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 3657c478bd9Sstevel@tonic-gate fmt_time64(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 3667c478bd9Sstevel@tonic-gate { 367*a727d47aSjwadams int64_t x; 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 3707c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) { 371*a727d47aSjwadams if ((time_t)x == x) 3727c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%-24Y", (time_t)x); 373*a727d47aSjwadams else 374*a727d47aSjwadams mdb_iob_printf(mdb.m_out, "%-24llR", x); 375*a727d47aSjwadams 3767c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, x); 3777c478bd9Sstevel@tonic-gate addr += sizeof (x); 3787c478bd9Sstevel@tonic-gate } else { 3797c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 3807c478bd9Sstevel@tonic-gate break; 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate return (addr); 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 3877c478bd9Sstevel@tonic-gate fmt_sdbyte(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 3887c478bd9Sstevel@tonic-gate { 3897c478bd9Sstevel@tonic-gate int8_t x; 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 3927c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) { 3937c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%-8d", (int32_t)x); 3947c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, (uint8_t)x); 3957c478bd9Sstevel@tonic-gate addr += sizeof (x); 3967c478bd9Sstevel@tonic-gate } else { 3977c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 3987c478bd9Sstevel@tonic-gate break; 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate return (addr); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 4057c478bd9Sstevel@tonic-gate fmt_instr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 4067c478bd9Sstevel@tonic-gate { 4077c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 4087c478bd9Sstevel@tonic-gate uintptr_t naddr; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 4117c478bd9Sstevel@tonic-gate naddr = mdb_dis_ins2str(mdb.m_disasm, t, as, 4127c478bd9Sstevel@tonic-gate buf, sizeof (buf), addr); 4137c478bd9Sstevel@tonic-gate if (naddr == addr) 4147c478bd9Sstevel@tonic-gate return (addr); /* If we didn't move, we failed */ 4157c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%s\n", buf); 4167c478bd9Sstevel@tonic-gate addr = naddr; 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate return (addr); 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 4227c478bd9Sstevel@tonic-gate fmt_dotinstr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 4237c478bd9Sstevel@tonic-gate { 4247c478bd9Sstevel@tonic-gate uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_INDENT; 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 4277c478bd9Sstevel@tonic-gate uintptr_t naddr; 4287c478bd9Sstevel@tonic-gate uint32_t i; 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate for (mdb_iob_clrflags(mdb.m_out, oflags); cnt-- != 0; addr = naddr) { 4317c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &i, sizeof (i), addr) != sizeof (i)) { 4327c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 4337c478bd9Sstevel@tonic-gate break; /* Fail if we can't read instruction */ 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate naddr = mdb_dis_ins2str(mdb.m_disasm, t, as, 4367c478bd9Sstevel@tonic-gate buf, sizeof (buf), addr); 4377c478bd9Sstevel@tonic-gate if (naddr == addr) 4387c478bd9Sstevel@tonic-gate break; /* Fail if we didn't advance */ 4397c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%lx %x: %s\n", (long)addr, i, buf); 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate mdb_iob_setflags(mdb.m_out, oflags); 4437c478bd9Sstevel@tonic-gate return (addr); 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 4477c478bd9Sstevel@tonic-gate fmt_binary(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 4487c478bd9Sstevel@tonic-gate { 4497c478bd9Sstevel@tonic-gate uint64_t x; 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 4527c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) { 4537c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, "%-64s", 4547c478bd9Sstevel@tonic-gate numtostr(x, 2, NTOS_UNSIGNED)); 4557c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, x); 4567c478bd9Sstevel@tonic-gate addr += sizeof (x); 4577c478bd9Sstevel@tonic-gate } else { 4587c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 4597c478bd9Sstevel@tonic-gate break; 4607c478bd9Sstevel@tonic-gate } 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate return (addr); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate static mdb_tgt_addr_t 4667c478bd9Sstevel@tonic-gate fmt_hex64(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) 4677c478bd9Sstevel@tonic-gate { 4687c478bd9Sstevel@tonic-gate const char *fmts[] = { "%-16llx", "%-17llx" }; 4697c478bd9Sstevel@tonic-gate const uint64_t mask = 0xf000000000000000ull; 4707c478bd9Sstevel@tonic-gate uint64_t x; 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 4737c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) { 4747c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, fmts[(x & mask) != 0], x); 4757c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, x); 4767c478bd9Sstevel@tonic-gate addr += sizeof (x); 4777c478bd9Sstevel@tonic-gate } else { 4787c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 4797c478bd9Sstevel@tonic-gate break; 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate return (addr); 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate static const mdb_fmt_desc_t fmttab[] = { 4867c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 0 = NUL */ 4877c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 1 = SOH */ 4887c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 2 = STX */ 4897c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 3 = ETX */ 4907c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 4 = EOT */ 4917c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 5 = ENQ */ 4927c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 6 = ACK */ 4937c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 7 = BEL */ 4947c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 8 = BS */ 4957c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 9 = \t */ 4967c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 10 = \n */ 4977c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 11 = VT */ 4987c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 12 = FF */ 4997c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 13 = \r */ 5007c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 14 = SO */ 5017c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 15 = SI */ 5027c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 16 = DLE */ 5037c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 17 = DC1 */ 5047c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 18 = DC2 */ 5057c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 19 = DC3 */ 5067c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 20 = DC4 */ 5077c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 21 = NAK */ 5087c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 22 = EYC */ 5097c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 23 = ETB */ 5107c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 24 = CAN */ 5117c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 25 = EM */ 5127c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 26 = SUB */ 5137c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 27 = ESC */ 5147c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 28 = FS */ 5157c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 29 = GS */ 5167c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 30 = RS */ 5177c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 31 = US */ 5187c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 32 = SPACE */ 5197c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 33 = ! */ 5207c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 34 = " */ 5217c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 35 = # */ 5227c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 36 = $ */ 5237c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 37 = % */ 5247c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 38 = & */ 5257c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 39 = ' */ 5267c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 40 = ( */ 5277c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 41 = ) */ 5287c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 42 = * */ 5297c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_plus), help_plus, 0 }, /* 43 = + */ 5307c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 44 = , */ 5317c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_minus), help_minus, 0 }, /* 45 = - */ 5327c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 46 = . */ 5337c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 47 = / */ 5347c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 48 = 0 */ 5357c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 49 = 1 */ 5367c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 50 = 2 */ 5377c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 51 = 3 */ 5387c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 52 = 4 */ 5397c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 53 = 5 */ 5407c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 54 = 6 */ 5417c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 55 = 7 */ 5427c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 56 = 8 */ 5437c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 57 = 9 */ 5447c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 58 = : */ 5457c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 59 = ; */ 5467c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 60 = < */ 5477c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 61 = = */ 5487c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 62 = > */ 5497c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 63 = ? */ 5507c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 64 = @ */ 5517c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 65 = A */ 5527c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-8x", NULL, 1 }, /* 66 = B */ 5537c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_escchr), help_escchr, 1 }, /* 67 = C */ 5547c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16d", NULL, 4 }, /* 68 = D */ 5557c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16llu", NULL, 8 }, /* 69 = E */ 5567c478bd9Sstevel@tonic-gate #ifdef _KMDB 5577c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 70 = F */ 5587c478bd9Sstevel@tonic-gate #else 5597c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%g", NULL, sizeof (double) }, /* 70 = F */ 5607c478bd9Sstevel@tonic-gate #endif 5617c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16llo", NULL, 8 }, /* 71 = G */ 5627c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_swapint), help_swapint, 4 }, /* 72 = H */ 5637c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_dotinstr), help_dotinstr, 0 }, /* 73 = I */ 5647c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_hex64), help_hex64, 8 }, /* 74 = J */ 5657c478bd9Sstevel@tonic-gate #ifdef _LP64 5667c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_hex64), help_uintptr, 8 }, /* 75 = K (J) */ 5677c478bd9Sstevel@tonic-gate #else 5687c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16x", help_uintptr, 4 }, /* 75 = K (X) */ 5697c478bd9Sstevel@tonic-gate #endif 5707c478bd9Sstevel@tonic-gate { FMT_MATCH, NULL, help_match32, 4 }, /* 76 = L */ 5717c478bd9Sstevel@tonic-gate { FMT_MATCH, NULL, help_match64, 8 }, /* 77 = M */ 5727c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_nl), help_nl, SZ_NONE }, /* 78 = N */ 5737c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-#16o", NULL, 4 }, /* 79 = O */ 5747c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16a", NULL, sizeof (uintptr_t) }, /* 80 = P */ 5757c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-#16q", NULL, 4 }, /* 81 = Q */ 5767c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_binary), help_binary, 8 }, /* 82 = R */ 5777c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_escstr), help_escstr, 0 }, /* 83 = S */ 5787c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_tab), help_tab, SZ_NONE }, /* 84 = T */ 5797c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16u", NULL, 4 }, /* 85 = U */ 5807c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-8u", NULL, 1 }, /* 86 = V */ 5817c478bd9Sstevel@tonic-gate { FMT_PRINTF|FMT_WRITE, "%-16r", NULL, 4 }, /* 87 = W */ 5827c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16x", NULL, 4 }, /* 88 = X */ 5837c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_time32), help_time32, 4 }, /* 89 = Y */ 5847c478bd9Sstevel@tonic-gate { FMT_FUNC|FMT_WRITE, FUNCP(fmt_hex64), help_hex64, 8 }, /* 90 = Z */ 5857c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 91 = [ */ 5867c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 92 = \ */ 5877c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 93 = ] */ 5887c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_carat), help_carat, 0 }, /* 94 = ^ */ 5897c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 95 = _ */ 5907c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 96 = ` */ 5917c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_dot), help_dot, SZ_NONE }, /* 97 = a */ 5927c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-#8o", NULL, 1 }, /* 98 = b */ 5937c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%c", NULL, 1 }, /* 99 = c */ 5947c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-8hd", NULL, 2 }, /* 100 = d */ 5957c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16lld", NULL, 8 }, /* 101 = e */ 5967c478bd9Sstevel@tonic-gate #ifdef _KMDB 5977c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 102 = f */ 5987c478bd9Sstevel@tonic-gate #else 5997c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_float), help_f, sizeof (float) }, /* 102 = f */ 6007c478bd9Sstevel@tonic-gate #endif 6017c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16llq", NULL, 8 }, /* 103 = g */ 6027c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_swapshort), help_swapshort, 2 }, /* 104 = h */ 6037c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_instr), help_instr, 0 }, /* 105 = i */ 6047c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 106 = j */ 6057c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 107 = k */ 6067c478bd9Sstevel@tonic-gate { FMT_MATCH, NULL, help_match16, 2 }, /* 108 = l */ 6077c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 109 = m */ 6087c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_nl), help_nl, SZ_NONE }, /* 110 = n */ 6097c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-#8ho", NULL, 2 }, /* 111 = o */ 6107c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-16a", NULL, sizeof (uintptr_t) }, /* 112 = p */ 6117c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-#8hq", NULL, 2 }, /* 113 = q */ 6127c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_ws), help_ws, SZ_NONE }, /* 114 = r */ 6137c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_rawstr), help_rawstr, 0 }, /* 115 = s */ 6147c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_tab), help_tab, SZ_NONE }, /* 116 = t */ 6157c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-8hu", NULL, 2 }, /* 117 = u */ 6167c478bd9Sstevel@tonic-gate { FMT_FUNC|FMT_WRITE, FUNCP(fmt_sdbyte), help_sdbyte, 1 }, /* 118 = v */ 6177c478bd9Sstevel@tonic-gate { FMT_PRINTF|FMT_WRITE, "%-8hr", NULL, 2 }, /* 119 = w */ 6187c478bd9Sstevel@tonic-gate { FMT_PRINTF, "%-8hx", NULL, 2 }, /* 120 = x */ 6197c478bd9Sstevel@tonic-gate { FMT_FUNC, FUNCP(fmt_time64), help_time64, 8 }, /* 121 = y */ 6207c478bd9Sstevel@tonic-gate { FMT_NONE, NULL, NULL, 0 }, /* 122 = z */ 6217c478bd9Sstevel@tonic-gate }; 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate mdb_tgt_addr_t 6247c478bd9Sstevel@tonic-gate mdb_fmt_print(mdb_tgt_t *t, mdb_tgt_as_t as, 6257c478bd9Sstevel@tonic-gate mdb_tgt_addr_t addr, size_t cnt, char fmt) 6267c478bd9Sstevel@tonic-gate { 6277c478bd9Sstevel@tonic-gate const mdb_fmt_desc_t *fp = &fmttab[fmt]; 6287c478bd9Sstevel@tonic-gate mdb_fmt_func_f *funcp; 6297c478bd9Sstevel@tonic-gate uintmax_t rvalue; 6307c478bd9Sstevel@tonic-gate void *buf; 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate union { 6337c478bd9Sstevel@tonic-gate uint64_t i8; 6347c478bd9Sstevel@tonic-gate uint32_t i4; 6357c478bd9Sstevel@tonic-gate uint16_t i2; 6367c478bd9Sstevel@tonic-gate uint8_t i1; 6377c478bd9Sstevel@tonic-gate } u; 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate if (fmt < 0 || fmt > (sizeof (fmttab) / sizeof (fmttab[0]))) { 6407c478bd9Sstevel@tonic-gate warn("invalid format character -- '%c'\n", fmt); 6417c478bd9Sstevel@tonic-gate return (addr); 6427c478bd9Sstevel@tonic-gate } 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate switch (FMT_TYPE(fp->f_type)) { 6457c478bd9Sstevel@tonic-gate case FMT_FUNC: 6467c478bd9Sstevel@tonic-gate funcp = (mdb_fmt_func_f *)fp->f_ptr; 6477c478bd9Sstevel@tonic-gate addr = funcp(t, as, addr, cnt); 6487c478bd9Sstevel@tonic-gate break; 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate case FMT_PRINTF: 6517c478bd9Sstevel@tonic-gate switch (fp->f_size) { 6527c478bd9Sstevel@tonic-gate case 1: 6537c478bd9Sstevel@tonic-gate buf = &u.i1; 6547c478bd9Sstevel@tonic-gate break; 6557c478bd9Sstevel@tonic-gate case 2: 6567c478bd9Sstevel@tonic-gate buf = &u.i2; 6577c478bd9Sstevel@tonic-gate break; 6587c478bd9Sstevel@tonic-gate case 4: 6597c478bd9Sstevel@tonic-gate buf = &u.i4; 6607c478bd9Sstevel@tonic-gate break; 6617c478bd9Sstevel@tonic-gate case 8: 6627c478bd9Sstevel@tonic-gate buf = &u.i8; 6637c478bd9Sstevel@tonic-gate break; 6647c478bd9Sstevel@tonic-gate default: 6657c478bd9Sstevel@tonic-gate fail("format %c is defined using illegal size\n", fmt); 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate while (cnt-- != 0) { 6697c478bd9Sstevel@tonic-gate if (mdb_tgt_aread(t, as, buf, fp->f_size, addr) != 6707c478bd9Sstevel@tonic-gate fp->f_size) { 6717c478bd9Sstevel@tonic-gate warn("failed to read data from target"); 6727c478bd9Sstevel@tonic-gate return (addr); 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate switch (fp->f_size) { 6767c478bd9Sstevel@tonic-gate case 1: 6777c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, fp->f_ptr, u.i1); 6787c478bd9Sstevel@tonic-gate rvalue = u.i1; 6797c478bd9Sstevel@tonic-gate break; 6807c478bd9Sstevel@tonic-gate case 2: 6817c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, fp->f_ptr, u.i2); 6827c478bd9Sstevel@tonic-gate rvalue = u.i2; 6837c478bd9Sstevel@tonic-gate break; 6847c478bd9Sstevel@tonic-gate case 4: 6857c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, fp->f_ptr, u.i4); 6867c478bd9Sstevel@tonic-gate rvalue = u.i4; 6877c478bd9Sstevel@tonic-gate break; 6887c478bd9Sstevel@tonic-gate case 8: 6897c478bd9Sstevel@tonic-gate mdb_iob_printf(mdb.m_out, fp->f_ptr, u.i8); 6907c478bd9Sstevel@tonic-gate rvalue = u.i8; 6917c478bd9Sstevel@tonic-gate break; 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate mdb_nv_set_value(mdb.m_rvalue, rvalue); 6957c478bd9Sstevel@tonic-gate addr += fp->f_size; 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate break; 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate default: 7007c478bd9Sstevel@tonic-gate warn("invalid format character -- '%c'\n", fmt); 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate return (addr); 7047c478bd9Sstevel@tonic-gate } 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 7077c478bd9Sstevel@tonic-gate int 7087c478bd9Sstevel@tonic-gate cmd_formats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 7097c478bd9Sstevel@tonic-gate { 7107c478bd9Sstevel@tonic-gate const mdb_fmt_desc_t *fp = &fmttab[0]; 7117c478bd9Sstevel@tonic-gate int i; 7127c478bd9Sstevel@tonic-gate const char *write; 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate if ((flags & DCMD_ADDRSPEC) || argc != 0) 7157c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate for (i = 0; i < (sizeof (fmttab) / sizeof (fmttab[0])); i++, fp++) { 7187c478bd9Sstevel@tonic-gate if (fp->f_type == FMT_NONE) 7197c478bd9Sstevel@tonic-gate continue; 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate write = (fp->f_type & FMT_WRITE) ? "write " : ""; 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate if (fp->f_type & FMT_FUNC) 7247c478bd9Sstevel@tonic-gate mdb_printf("%c - %s%s", i, write, fp->f_help); 7257c478bd9Sstevel@tonic-gate else if (fp->f_type & FMT_MATCH) 7267c478bd9Sstevel@tonic-gate mdb_printf("%c - match %s", i, fp->f_help); 7277c478bd9Sstevel@tonic-gate else if (fp->f_help != NULL) 7287c478bd9Sstevel@tonic-gate mdb_printf("%c - %s%s", i, write, fp->f_help); 7297c478bd9Sstevel@tonic-gate else 7307c478bd9Sstevel@tonic-gate mdb_printf("%c - %s%s", i, write, 7317c478bd9Sstevel@tonic-gate mdb_iob_format2str(fp->f_ptr)); 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate switch (fp->f_size) { 7347c478bd9Sstevel@tonic-gate case SZ_NONE: 7357c478bd9Sstevel@tonic-gate mdb_printf("\n"); 7367c478bd9Sstevel@tonic-gate break; 7377c478bd9Sstevel@tonic-gate case 0: 7387c478bd9Sstevel@tonic-gate mdb_printf(" (variable size)\n"); 7397c478bd9Sstevel@tonic-gate break; 7407c478bd9Sstevel@tonic-gate case 1: 7417c478bd9Sstevel@tonic-gate mdb_printf(" (1 byte)\n"); 7427c478bd9Sstevel@tonic-gate break; 7437c478bd9Sstevel@tonic-gate default: 7447c478bd9Sstevel@tonic-gate mdb_printf(" (%lu bytes)\n", fp->f_size); 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate } 7477c478bd9Sstevel@tonic-gate 7487c478bd9Sstevel@tonic-gate return (DCMD_OK); 7497c478bd9Sstevel@tonic-gate } 750