Print this page
12364 mdb trips assertion related to autowrap
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/mdb/mdb_fmt.c
+++ new/usr/src/cmd/mdb/common/mdb/mdb_fmt.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 - * Copyright 2019 Joyent, Inc.
24 + * Copyright 2020 Joyent, Inc.
25 25 * Copyright (c) 2017 by Delphix. All rights reserved.
26 26 */
27 27
28 28 /*
29 29 * Format String Decoder
30 30 *
31 31 * This file provides the core engine for converting strings of format
32 32 * characters into formatted output. The various format dcmds invoke the
33 33 * mdb_fmt_print() function below with a target, address space identifier,
34 34 * address, count, and format character, and it reads the required data from
35 35 * the target and prints the formatted output to stdout. Since nearly two
36 36 * thirds of the format characters can be expressed as simple printf format
37 37 * strings, we implement the engine using the lookup table below. Each entry
38 38 * provides either a pointer to a printf format string or a pointer to a
39 39 * function to perform special processing. For the printf case, the
40 40 * corresponding data size in bytes is also supplied. The printf processing
41 41 * code handles 1, 2, 4, and 8-byte reads into an unsigned integer container
42 42 * of the given size, and then simply calls mdb_iob_printf with the integer
43 43 * and format string. This handles all printf cases, except when unsigned
44 44 * promotion of an integer type in the varargs list does not perform the
45 45 * conversion we require to get the proper result. With the current set of
46 46 * format characters, this case only occurs twice: we need a 4-byte float
47 47 * to get promoted to 8-byte double for the 'f' format so it can be
48 48 * correctly formatted by %f, and we need a 1-byte int8_t to get promoted
49 49 * with sign extension to a 4-byte int32_t for the 'v' format so it can be
50 50 * correctly formatted by %d. We provide explicit functions to handle these
51 51 * cases, as well as to handle special format characters such as 'i', etc.
52 52 * We also provide a cmd_formats() dcmd function below which prints a table
53 53 * of the output formats and their sizes. Format characters that provide
54 54 * custom functions provide their help description string explicitly. All
55 55 * the printf formats have their help strings generated automatically by
56 56 * our printf "unparser" mdb_iob_format2str().
57 57 */
58 58
59 59 #include <mdb/mdb_types.h>
60 60 #include <mdb/mdb_target.h>
61 61 #include <mdb/mdb_io.h>
62 62 #include <mdb/mdb_err.h>
63 63 #include <mdb/mdb_string.h>
64 64 #include <mdb/mdb_modapi.h>
65 65 #include <mdb/mdb.h>
66 66
67 67 #define FUNCP(p) ((void *)(p)) /* Cast to f_ptr type */
68 68 #define SZ_NONE ((size_t)-1L) /* Format does not change dot */
69 69
70 70 typedef mdb_tgt_addr_t mdb_fmt_func_f(mdb_tgt_t *,
71 71 mdb_tgt_as_t, mdb_tgt_addr_t, size_t);
72 72
73 73 /*
74 74 * There are several 'special' characters that are handled outside of
75 75 * mdb_fmt_print(). These are characters that write (vwWZ) and characters that
76 76 * match (lLM). We include them here so that ::formats can display an
77 77 * appropriate message, but they are handled specially by write_arglist() and
78 78 * match_arglist() in mdb_cmds.c.
79 79 */
80 80 #define FMT_NONE 0x0 /* Format character is not supported */
81 81 #define FMT_FUNC 0x1 /* f_ptr is a mdb_fmt_func_f to call */
82 82 #define FMT_PRINTF 0x2 /* f_ptr is a const char * format string */
83 83 #define FMT_MATCH 0x4 /* Match command (not supported here) */
84 84 #define FMT_WRITE 0x8 /* Command writes to address space */
85 85 #define FMT_NOAUTOWRAP 0x10 /* Autowrap should not be autoenabled */
86 86
87 87 #define FMT_TYPE(x) ((x) & 0x7) /* Excludes modifying flags */
88 88
89 89 typedef struct mdb_fmt_desc {
90 90 int f_type; /* Type of format (see above) */
91 91 void *f_ptr; /* Data pointer (see above) */
92 92 const char *f_help; /* Additional help string */
93 93 size_t f_size; /* Size of type in bytes, or SZ_NONE */
94 94 boolean_t f_float; /* Is this a floating point type */
95 95 } mdb_fmt_desc_t;
96 96
97 97 static const char help_plus[] = "increment dot by the count";
98 98 static const char help_minus[] = "decrement dot by the count";
99 99 static const char help_escchr[] = "character using C character notation";
100 100 static const char help_swapint[] = "swap bytes and shorts";
101 101 static const char help_dotinstr[] = "address and disassembled instruction";
102 102 static const char help_instr[] = "disassembled instruction";
103 103 static const char help_escstr[] = "string using C string notation";
104 104 static const char help_time32[] = "decoded time32_t";
105 105 static const char help_carat[] = "decrement dot by increment * count";
106 106 static const char help_dot[] = "dot as symbol+offset";
107 107 #ifndef _KMDB
108 108 static const char help_f[] = "float";
109 109 #endif
110 110 static const char help_swapshort[] = "swap bytes";
111 111 static const char help_nl[] = "newline";
112 112 static const char help_ws[] = "whitespace";
113 113 static const char help_rawstr[] = "raw string";
114 114 static const char help_tab[] = "horizontal tab";
115 115 static const char help_sdbyte[] = "decimal signed int";
116 116 static const char help_time64[] = "decoded time64_t";
117 117 static const char help_binary[] = "binary unsigned long long";
118 118 static const char help_hex64[] = "hexadecimal long long";
119 119 static const char help_match32[] = "int";
120 120 static const char help_match64[] = "long long";
121 121 static const char help_match16[] = "short";
122 122 static const char help_uintptr[] = "hexadecimal uintptr_t";
123 123 static const char help_ctf[] = "whose size is inferred by CTF info";
124 124 static const char help_jazzed[] = "jazzed-up binary unsigned long long";
125 125
126 126 /*ARGSUSED*/
127 127 static mdb_tgt_addr_t
128 128 fmt_dot(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
129 129 {
130 130 uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_INDENT;
131 131 char buf[24];
132 132
133 133 mdb_iob_clrflags(mdb.m_out, oflags);
134 134
135 135 if (mdb.m_flags & MDB_FL_PSYM) {
136 136 while (cnt-- != 0)
137 137 mdb_iob_printf(mdb.m_out, "%-#16lla%16T", addr);
138 138 } else {
139 139 (void) mdb_iob_snprintf(buf, sizeof (buf),
140 140 "%#llx:", (u_longlong_t)addr);
141 141 while (cnt-- != 0)
142 142 mdb_iob_printf(mdb.m_out, "%-16s%16T", buf);
143 143 }
144 144
145 145 mdb_iob_setflags(mdb.m_out, oflags);
146 146 mdb_nv_set_value(mdb.m_rvalue, addr);
147 147 return (addr);
148 148 }
149 149
150 150 #ifndef _KMDB
151 151 static mdb_tgt_addr_t
152 152 fmt_float(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
153 153 {
154 154 float f;
155 155 /*
156 156 * We need to handle float as a special case because we need it to be
157 157 * promoted to a double by virtue of appearing as a parameter, and all
158 158 * our generic format handling below is based on integer types.
159 159 */
160 160 while (cnt-- != 0) {
161 161 if (mdb_tgt_aread(t, as, &f, sizeof (f), addr) != sizeof (f)) {
162 162 warn("failed to read data from target");
163 163 break;
164 164 }
165 165 mdb_iob_printf(mdb.m_out, "%e", f);
166 166 addr += sizeof (f);
167 167 }
168 168 return (addr);
169 169 }
170 170 #endif
171 171
172 172 /*ARGSUSED*/
173 173 static mdb_tgt_addr_t
174 174 fmt_plus(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
175 175 {
176 176 return (addr + cnt);
177 177 }
178 178
179 179 /*ARGSUSED*/
180 180 static mdb_tgt_addr_t
181 181 fmt_minus(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
182 182 {
183 183 return (addr - cnt);
184 184 }
185 185
186 186 /*ARGSUSED*/
187 187 static mdb_tgt_addr_t
188 188 fmt_carat(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
189 189 {
190 190 return (addr - (mdb.m_incr * cnt));
191 191 }
192 192
193 193 /*ARGSUSED*/
194 194 static mdb_tgt_addr_t
195 195 fmt_nl(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
196 196 {
197 197 while (cnt-- != 0)
198 198 mdb_iob_nl(mdb.m_out);
199 199
200 200 return (addr);
201 201 }
202 202
203 203 /*ARGSUSED*/
204 204 static mdb_tgt_addr_t
205 205 fmt_ws(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
206 206 {
207 207 mdb_iob_ws(mdb.m_out, cnt);
208 208 return (addr);
209 209 }
210 210
211 211 /*ARGSUSED*/
212 212 static mdb_tgt_addr_t
213 213 fmt_tab(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
214 214 {
215 215 size_t ts = mdb_iob_gettabstop(mdb.m_out);
216 216
217 217 mdb_iob_tabstop(mdb.m_out, cnt);
218 218 mdb_iob_tab(mdb.m_out);
219 219 mdb_iob_tabstop(mdb.m_out, ts);
220 220
221 221 return (addr);
222 222 }
223 223
224 224 static mdb_tgt_addr_t
225 225 fmt_rawstr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
226 226 {
227 227 uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_INDENT;
228 228 char buf[BUFSIZ];
229 229 ssize_t nbytes;
230 230
231 231 mdb_iob_clrflags(mdb.m_out, oflags);
232 232
233 233 for (; cnt-- != 0; addr++) {
234 234 do {
235 235 nbytes = mdb_tgt_readstr(t, as, buf, BUFSIZ, addr);
236 236 if (nbytes > 0) {
237 237 mdb_iob_puts(mdb.m_out, buf);
238 238 addr += MIN(nbytes, BUFSIZ - 1);
239 239 } else if (nbytes < 0) {
240 240 warn("failed to read data from target");
241 241 goto out;
242 242 }
243 243 } while (nbytes == BUFSIZ);
244 244
245 245 if (cnt != 0)
246 246 mdb_iob_puts(mdb.m_out, "\\0");
247 247 }
248 248 out:
249 249 mdb_iob_setflags(mdb.m_out, oflags);
250 250 return (addr);
251 251 }
252 252
253 253 static mdb_tgt_addr_t
254 254 fmt_escstr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
255 255 {
256 256 uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_INDENT;
257 257 char buf[BUFSIZ];
258 258 ssize_t nbytes;
259 259 char *s;
260 260
261 261 mdb_iob_clrflags(mdb.m_out, oflags);
262 262
263 263 for (; cnt-- != 0; addr++) {
264 264 do {
265 265 nbytes = mdb_tgt_readstr(t, as, buf, BUFSIZ, addr);
266 266 if (nbytes > 0) {
267 267 s = strchr2esc(buf, strlen(buf));
268 268 mdb_iob_puts(mdb.m_out, s);
269 269 strfree(s);
270 270 addr += MIN(nbytes, BUFSIZ - 1);
271 271 } else if (nbytes < 0) {
272 272 warn("failed to read data from target");
273 273 goto out;
274 274 }
275 275 } while (nbytes == BUFSIZ);
276 276
277 277 if (cnt != 0)
278 278 mdb_iob_puts(mdb.m_out, "\\0");
279 279 }
280 280 out:
281 281 mdb_iob_setflags(mdb.m_out, oflags);
282 282 return (addr);
283 283 }
284 284
285 285 static mdb_tgt_addr_t
286 286 fmt_escchr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
287 287 {
288 288 char *(*convert)(const char *, size_t);
289 289 ssize_t nbytes;
290 290 char *buf, *s;
291 291
292 292 if (mdb.m_flags & MDB_FL_ADB)
293 293 convert = &strchr2adb;
294 294 else
295 295 convert = &strchr2esc;
296 296
297 297 buf = mdb_alloc(cnt + 1, UM_SLEEP);
298 298 buf[cnt] = 0;
299 299
300 300 if ((nbytes = mdb_tgt_aread(t, as, buf, cnt, addr)) > 0) {
301 301 s = convert(buf, nbytes);
302 302 mdb_iob_puts(mdb.m_out, s);
303 303 strfree(s);
304 304 addr += nbytes;
305 305 }
306 306
307 307 mdb_free(buf, cnt + 1);
308 308 return (addr);
309 309 }
310 310
311 311 static mdb_tgt_addr_t
312 312 fmt_swapshort(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
313 313 {
314 314 ushort_t x;
315 315
316 316 while (cnt-- != 0) {
317 317 if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) {
318 318 x = (x << 8) | (x >> 8);
319 319 mdb_iob_printf(mdb.m_out, "%-8x", x);
320 320 mdb_nv_set_value(mdb.m_rvalue, x);
321 321 addr += sizeof (x);
322 322 } else {
323 323 warn("failed to read data from target");
324 324 break;
325 325 }
326 326 }
327 327 return (addr);
328 328 }
329 329
330 330 static mdb_tgt_addr_t
331 331 fmt_swapint(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
332 332 {
333 333 uint_t x;
334 334
335 335 while (cnt-- != 0) {
336 336 if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) {
337 337 x = ((x << 24) | ((x << 8) & 0xff0000) |
338 338 ((x >> 8) & 0xff00) | ((x >> 24) & 0xff));
339 339 mdb_iob_printf(mdb.m_out, "%-16x", x);
340 340 mdb_nv_set_value(mdb.m_rvalue, x);
341 341 addr += sizeof (x);
342 342 } else {
343 343 warn("failed to read data from target");
344 344 break;
345 345 }
346 346 }
347 347 return (addr);
348 348 }
349 349
350 350 static mdb_tgt_addr_t
351 351 fmt_time32(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
352 352 {
353 353 int32_t x;
354 354
355 355 while (cnt-- != 0) {
356 356 if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) {
357 357 mdb_iob_printf(mdb.m_out, "%-24Y", (time_t)x);
358 358 mdb_nv_set_value(mdb.m_rvalue, x);
359 359 addr += sizeof (x);
360 360 } else {
361 361 warn("failed to read data from target");
362 362 break;
363 363 }
364 364 }
365 365 return (addr);
366 366 }
367 367
368 368 static mdb_tgt_addr_t
369 369 fmt_time64(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
370 370 {
371 371 int64_t x;
372 372
373 373 while (cnt-- != 0) {
374 374 if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) {
375 375 if ((time_t)x == x)
376 376 mdb_iob_printf(mdb.m_out, "%-24Y", (time_t)x);
377 377 else
378 378 mdb_iob_printf(mdb.m_out, "%-24llR", x);
379 379
380 380 mdb_nv_set_value(mdb.m_rvalue, x);
381 381 addr += sizeof (x);
382 382 } else {
383 383 warn("failed to read data from target");
384 384 break;
385 385 }
386 386 }
387 387 return (addr);
388 388 }
389 389
390 390 static mdb_tgt_addr_t
391 391 fmt_sdbyte(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
392 392 {
393 393 int8_t x;
394 394
395 395 while (cnt-- != 0) {
396 396 if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) {
397 397 mdb_iob_printf(mdb.m_out, "%-8d", (int32_t)x);
398 398 mdb_nv_set_value(mdb.m_rvalue, (uint8_t)x);
399 399 addr += sizeof (x);
400 400 } else {
401 401 warn("failed to read data from target");
402 402 break;
403 403 }
404 404 }
405 405 return (addr);
406 406 }
407 407
408 408 static mdb_tgt_addr_t
409 409 fmt_instr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
410 410 {
411 411 char buf[BUFSIZ];
412 412 uintptr_t naddr;
413 413
414 414 while (cnt-- != 0) {
415 415 naddr = mdb_dis_ins2str(mdb.m_disasm, t, as,
416 416 buf, sizeof (buf), addr);
417 417 if (naddr == addr)
418 418 return (addr); /* If we didn't move, we failed */
419 419 mdb_iob_printf(mdb.m_out, "%s\n", buf);
420 420 addr = naddr;
421 421 }
422 422 return (addr);
423 423 }
424 424
425 425 static mdb_tgt_addr_t
426 426 fmt_dotinstr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
427 427 {
428 428 uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_INDENT;
429 429
430 430 char buf[BUFSIZ];
431 431 uintptr_t naddr;
432 432 uint32_t i;
433 433
434 434 for (mdb_iob_clrflags(mdb.m_out, oflags); cnt-- != 0; addr = naddr) {
435 435 if (mdb_tgt_aread(t, as, &i, sizeof (i), addr) != sizeof (i)) {
436 436 warn("failed to read data from target");
437 437 break; /* Fail if we can't read instruction */
438 438 }
439 439 naddr = mdb_dis_ins2str(mdb.m_disasm, t, as,
440 440 buf, sizeof (buf), addr);
441 441 if (naddr == addr)
442 442 break; /* Fail if we didn't advance */
443 443 mdb_iob_printf(mdb.m_out, "%lx %x: %s\n", (long)addr, i, buf);
444 444 }
445 445
446 446 mdb_iob_setflags(mdb.m_out, oflags);
447 447 return (addr);
448 448 }
449 449
450 450 static mdb_tgt_addr_t
451 451 fmt_binary(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
452 452 {
453 453 uint64_t x;
454 454 const char *fmts[] = { "%-64s", "%-65s" };
455 455 const uint64_t mask = 0x8000000000000000ull;
456 456
457 457 while (cnt-- != 0) {
458 458 if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) {
459 459 mdb_iob_printf(mdb.m_out, fmts[(x & mask) != 0],
460 460 numtostr(x, 2, NTOS_UNSIGNED));
461 461 mdb_nv_set_value(mdb.m_rvalue, x);
462 462 addr += sizeof (x);
463 463 } else {
464 464 warn("failed to read data from target");
465 465 break;
466 466 }
467 467 }
468 468 return (addr);
469 469 }
470 470
471 471 static mdb_tgt_addr_t
472 472 fmt_jazzed(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
473 473 {
474 474 uint64_t x;
475 475 char buf[256];
476 476
477 477 while (cnt-- != 0) {
478 478 boolean_t header = B_TRUE;
479 479
480 480 if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) != sizeof (x)) {
481 481 warn("failed to read data from target");
482 482 break;
483 483 }
484 484
485 485 mdb_nv_set_value(mdb.m_rvalue, x);
486 486 addr += sizeof (x);
487 487
488 488 mdb_iob_printf(mdb.m_out, "%s\n",
489 489 numtostr(x, 2, NTOS_UNSIGNED));
490 490
491 491 while (x != 0) {
492 492 int b = 63, forearm;
493 493 int i = 0, highbit;
494 494
495 495 /*
496 496 * Find the high bit...
497 497 */
498 498 while (!(x & (1ULL << b)))
499 499 b--;
500 500
501 501 highbit = b;
502 502
503 503 /*
504 504 * ...and iterate over the remaining bits, putting
505 505 * the upper arm in our buffer for any set bit (and
506 506 * a space otherwise).
507 507 */
508 508 while (x & ((1ULL << b) - 1)) {
509 509 buf[i++] = x & (1ULL << b) ? '|' : ' ';
510 510 b--;
511 511 }
512 512
513 513 /*
514 514 * If this is the header line, print the upper arm
515 515 * for the lowest set bit and continue...
516 516 */
517 517 if (header) {
518 518 header = B_FALSE;
519 519 buf[i] = '\0';
520 520 mdb_iob_printf(mdb.m_out, "%s|\n", buf);
521 521 continue;
522 522 }
523 523
524 524 /*
525 525 * ...otherwise, put the elbow and forearm into our
526 526 * buffer, and print it.
527 527 */
528 528 buf[i++] = '+';
529 529
530 530 for (forearm = b; forearm > -2; forearm--)
531 531 buf[i++] = '-';
532 532
533 533 buf[i] = '\0';
534 534 mdb_iob_printf(mdb.m_out, "%s bit %d %smask 0x%0*llx\n",
535 535 buf, b, b < 10 && highbit >= 10 ? " " : "",
536 536 (highbit / 4) + 1, 1ULL << b);
537 537
538 538 /*
539 539 * Finally, clear the lowest set bit and continue.
540 540 */
541 541 x &= ~(1ULL << b);
542 542 }
543 543 }
544 544
545 545 return (addr);
546 546 }
547 547
548 548 static mdb_tgt_addr_t
549 549 fmt_hex64(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt)
550 550 {
551 551 const char *fmts[] = { "%-16llx", "%-17llx" };
552 552 const uint64_t mask = 0xf000000000000000ull;
553 553 uint64_t x;
554 554
555 555 while (cnt-- != 0) {
556 556 if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) {
557 557 mdb_iob_printf(mdb.m_out, fmts[(x & mask) != 0], x);
558 558 mdb_nv_set_value(mdb.m_rvalue, x);
559 559 addr += sizeof (x);
560 560 } else {
561 561 warn("failed to read data from target");
562 562 break;
563 563 }
564 564 }
565 565 return (addr);
566 566 }
567 567
568 568 static const mdb_fmt_desc_t fmttab[] = {
569 569 { FMT_NONE, NULL, NULL, 0 }, /* 0 = NUL */
570 570 { FMT_NONE, NULL, NULL, 0 }, /* 1 = SOH */
571 571 { FMT_NONE, NULL, NULL, 0 }, /* 2 = STX */
572 572 { FMT_NONE, NULL, NULL, 0 }, /* 3 = ETX */
573 573 { FMT_NONE, NULL, NULL, 0 }, /* 4 = EOT */
574 574 { FMT_NONE, NULL, NULL, 0 }, /* 5 = ENQ */
575 575 { FMT_NONE, NULL, NULL, 0 }, /* 6 = ACK */
576 576 { FMT_NONE, NULL, NULL, 0 }, /* 7 = BEL */
577 577 { FMT_NONE, NULL, NULL, 0 }, /* 8 = BS */
578 578 { FMT_NONE, NULL, NULL, 0 }, /* 9 = \t */
579 579 { FMT_NONE, NULL, NULL, 0 }, /* 10 = \n */
580 580 { FMT_NONE, NULL, NULL, 0 }, /* 11 = VT */
581 581 { FMT_NONE, NULL, NULL, 0 }, /* 12 = FF */
582 582 { FMT_NONE, NULL, NULL, 0 }, /* 13 = \r */
583 583 { FMT_NONE, NULL, NULL, 0 }, /* 14 = SO */
584 584 { FMT_NONE, NULL, NULL, 0 }, /* 15 = SI */
585 585 { FMT_NONE, NULL, NULL, 0 }, /* 16 = DLE */
586 586 { FMT_NONE, NULL, NULL, 0 }, /* 17 = DC1 */
587 587 { FMT_NONE, NULL, NULL, 0 }, /* 18 = DC2 */
588 588 { FMT_NONE, NULL, NULL, 0 }, /* 19 = DC3 */
589 589 { FMT_NONE, NULL, NULL, 0 }, /* 20 = DC4 */
590 590 { FMT_NONE, NULL, NULL, 0 }, /* 21 = NAK */
591 591 { FMT_NONE, NULL, NULL, 0 }, /* 22 = EYC */
592 592 { FMT_NONE, NULL, NULL, 0 }, /* 23 = ETB */
593 593 { FMT_NONE, NULL, NULL, 0 }, /* 24 = CAN */
594 594 { FMT_NONE, NULL, NULL, 0 }, /* 25 = EM */
595 595 { FMT_NONE, NULL, NULL, 0 }, /* 26 = SUB */
596 596 { FMT_NONE, NULL, NULL, 0 }, /* 27 = ESC */
597 597 { FMT_NONE, NULL, NULL, 0 }, /* 28 = FS */
598 598 { FMT_NONE, NULL, NULL, 0 }, /* 29 = GS */
599 599 { FMT_NONE, NULL, NULL, 0 }, /* 30 = RS */
600 600 { FMT_NONE, NULL, NULL, 0 }, /* 31 = US */
601 601 { FMT_NONE, NULL, NULL, 0 }, /* 32 = SPACE */
602 602 { FMT_NONE, NULL, NULL, 0 }, /* 33 = ! */
603 603 { FMT_NONE, NULL, NULL, 0 }, /* 34 = " */
604 604 { FMT_NONE, NULL, NULL, 0 }, /* 35 = # */
605 605 { FMT_NONE, NULL, NULL, 0 }, /* 36 = $ */
606 606 { FMT_NONE, NULL, NULL, 0 }, /* 37 = % */
607 607 { FMT_NONE, NULL, NULL, 0 }, /* 38 = & */
608 608 { FMT_NONE, NULL, NULL, 0 }, /* 39 = ' */
609 609 { FMT_NONE, NULL, NULL, 0 }, /* 40 = ( */
610 610 { FMT_NONE, NULL, NULL, 0 }, /* 41 = ) */
611 611 { FMT_NONE, NULL, NULL, 0 }, /* 42 = * */
612 612 { FMT_FUNC, FUNCP(fmt_plus), help_plus, 0 }, /* 43 = + */
613 613 { FMT_NONE, NULL, NULL, 0 }, /* 44 = , */
614 614 { FMT_FUNC, FUNCP(fmt_minus), help_minus, 0 }, /* 45 = - */
615 615 { FMT_NONE, NULL, NULL, 0 }, /* 46 = . */
616 616 { FMT_NONE, NULL, NULL, 0 }, /* 47 = / */
617 617 { FMT_NONE, NULL, NULL, 0 }, /* 48 = 0 */
618 618 { FMT_NONE, NULL, NULL, 0 }, /* 49 = 1 */
619 619 { FMT_NONE, NULL, NULL, 0 }, /* 50 = 2 */
620 620 { FMT_NONE, NULL, NULL, 0 }, /* 51 = 3 */
621 621 { FMT_NONE, NULL, NULL, 0 }, /* 52 = 4 */
622 622 { FMT_NONE, NULL, NULL, 0 }, /* 53 = 5 */
623 623 { FMT_NONE, NULL, NULL, 0 }, /* 54 = 6 */
624 624 { FMT_NONE, NULL, NULL, 0 }, /* 55 = 7 */
625 625 { FMT_NONE, NULL, NULL, 0 }, /* 56 = 8 */
626 626 { FMT_NONE, NULL, NULL, 0 }, /* 57 = 9 */
627 627 { FMT_NONE, NULL, NULL, 0 }, /* 58 = : */
628 628 { FMT_NONE, NULL, NULL, 0 }, /* 59 = ; */
629 629 { FMT_NONE, NULL, NULL, 0 }, /* 60 = < */
630 630 { FMT_NONE, NULL, NULL, 0 }, /* 61 = = */
631 631 { FMT_NONE, NULL, NULL, 0 }, /* 62 = > */
632 632 { FMT_NONE, NULL, NULL, 0 }, /* 63 = ? */
633 633 { FMT_NONE, NULL, NULL, 0 }, /* 64 = @ */
634 634 { FMT_NONE, NULL, NULL, 0 }, /* 65 = A */
635 635 { FMT_PRINTF, "%-8x", NULL, 1 }, /* 66 = B */
636 636 { FMT_FUNC, FUNCP(fmt_escchr), help_escchr, 1 }, /* 67 = C */
637 637 { FMT_PRINTF, "%-16d", NULL, 4 }, /* 68 = D */
638 638 { FMT_PRINTF, "%-21llu", NULL, 8 }, /* 69 = E */
639 639 #ifdef _KMDB
640 640 { FMT_NONE, NULL, NULL, 0 }, /* 70 = F */
641 641 #else
642 642 { FMT_PRINTF, "%g", NULL, sizeof (double), B_TRUE }, /* 70 = F */
643 643 #endif
644 644 { FMT_PRINTF, "%-23llo", NULL, 8 }, /* 71 = G */
645 645 { FMT_FUNC, FUNCP(fmt_swapint), help_swapint, 4 }, /* 72 = H */
646 646 { FMT_FUNC, FUNCP(fmt_dotinstr), help_dotinstr, 0 }, /* 73 = I */
647 647 { FMT_FUNC, FUNCP(fmt_hex64), help_hex64, 8 }, /* 74 = J */
648 648 #ifdef _LP64
649 649 { FMT_FUNC, FUNCP(fmt_hex64), help_uintptr, 8 }, /* 75 = K (J) */
650 650 #else
651 651 { FMT_PRINTF, "%-16x", help_uintptr, 4 }, /* 75 = K (X) */
652 652 #endif
653 653 { FMT_MATCH, NULL, help_match32, 4 }, /* 76 = L */
654 654 { FMT_MATCH, NULL, help_match64, 8 }, /* 77 = M */
655 655 { FMT_FUNC, FUNCP(fmt_nl), help_nl, SZ_NONE }, /* 78 = N */
656 656 { FMT_PRINTF, "%-#16o", NULL, 4 }, /* 79 = O */
657 657 { FMT_PRINTF, "%-19a", NULL, sizeof (uintptr_t) }, /* 80 = P */
658 658 { FMT_PRINTF, "%-#16q", NULL, 4 }, /* 81 = Q */
659 659 { FMT_FUNC, FUNCP(fmt_binary), help_binary, 8 }, /* 82 = R */
660 660 { FMT_FUNC, FUNCP(fmt_escstr), help_escstr, 0 }, /* 83 = S */
661 661 { FMT_FUNC, FUNCP(fmt_tab), help_tab, SZ_NONE }, /* 84 = T */
662 662 { FMT_PRINTF, "%-16u", NULL, 4 }, /* 85 = U */
663 663 { FMT_PRINTF, "%-8u", NULL, 1 }, /* 86 = V */
664 664 { FMT_PRINTF|FMT_WRITE, "%-16r", NULL, 4 }, /* 87 = W */
665 665 { FMT_PRINTF, "%-16x", NULL, 4 }, /* 88 = X */
666 666 { FMT_FUNC, FUNCP(fmt_time32), help_time32, 4 }, /* 89 = Y */
667 667 { FMT_FUNC|FMT_WRITE, FUNCP(fmt_hex64), help_hex64, 8 }, /* 90 = Z */
668 668 { FMT_NONE, NULL, NULL, 0 }, /* 91 = [ */
669 669 { FMT_NONE, NULL, NULL, 0 }, /* 92 = \ */
670 670 { FMT_NONE, NULL, NULL, 0 }, /* 93 = ] */
671 671 { FMT_FUNC, FUNCP(fmt_carat), help_carat, 0 }, /* 94 = ^ */
672 672 { FMT_NONE, NULL, NULL, 0 }, /* 95 = _ */
673 673 { FMT_NONE, NULL, NULL, 0 }, /* 96 = ` */
674 674 { FMT_FUNC, FUNCP(fmt_dot), help_dot, SZ_NONE }, /* 97 = a */
675 675 { FMT_PRINTF, "%-#8o", NULL, 1 }, /* 98 = b */
676 676 { FMT_PRINTF, "%c", NULL, 1 }, /* 99 = c */
677 677 { FMT_PRINTF, "%-8hd", NULL, 2 }, /* 100 = d */
678 678 { FMT_PRINTF, "%-21lld", NULL, 8 }, /* 101 = e */
679 679 #ifdef _KMDB
680 680 { FMT_NONE, NULL, NULL, 0 }, /* 102 = f */
681 681 #else
682 682 { FMT_FUNC, FUNCP(fmt_float), help_f, sizeof (float),
683 683 B_TRUE }, /* 102 = f */
684 684 #endif
685 685 { FMT_PRINTF, "%-24llq", NULL, 8 }, /* 103 = g */
686 686 { FMT_FUNC, FUNCP(fmt_swapshort), help_swapshort, 2 }, /* 104 = h */
687 687 { FMT_FUNC, FUNCP(fmt_instr), help_instr, 0 }, /* 105 = i */
688 688 { FMT_FUNC|FMT_NOAUTOWRAP,
689 689 FUNCP(fmt_jazzed), help_jazzed, 8 }, /* 106 = j */
690 690 { FMT_NONE, NULL, NULL, 0 }, /* 107 = k */
691 691 { FMT_MATCH, NULL, help_match16, 2 }, /* 108 = l */
692 692 { FMT_NONE, NULL, NULL, 0 }, /* 109 = m */
693 693 { FMT_FUNC, FUNCP(fmt_nl), help_nl, SZ_NONE }, /* 110 = n */
694 694 { FMT_PRINTF, "%-#8ho", NULL, 2 }, /* 111 = o */
695 695 { FMT_PRINTF, "%-19a", NULL, sizeof (uintptr_t) }, /* 112 = p */
696 696 { FMT_PRINTF, "%-#8hq", NULL, 2 }, /* 113 = q */
697 697 { FMT_FUNC, FUNCP(fmt_ws), help_ws, SZ_NONE }, /* 114 = r */
698 698 { FMT_FUNC, FUNCP(fmt_rawstr), help_rawstr, 0 }, /* 115 = s */
699 699 { FMT_FUNC, FUNCP(fmt_tab), help_tab, SZ_NONE }, /* 116 = t */
700 700 { FMT_PRINTF, "%-8hu", NULL, 2 }, /* 117 = u */
701 701 { FMT_FUNC|FMT_WRITE, FUNCP(fmt_sdbyte), help_sdbyte, 1 }, /* 118 = v */
702 702 { FMT_PRINTF|FMT_WRITE, "%-8hr", NULL, 2 }, /* 119 = w */
703 703 { FMT_PRINTF, "%-8hx", NULL, 2 }, /* 120 = x */
704 704 { FMT_FUNC, FUNCP(fmt_time64), help_time64, 8 }, /* 121 = y */
705 705 { FMT_WRITE, NULL, help_ctf, 0 }, /* 122 = z */
706 706 };
707 707
708 708 mdb_tgt_addr_t
709 709 mdb_fmt_print(mdb_tgt_t *t, mdb_tgt_as_t as,
710 710 mdb_tgt_addr_t addr, size_t cnt, char fmt)
711 711 {
712 712 const mdb_fmt_desc_t *fp = &fmttab[fmt];
713 713 mdb_fmt_func_f *funcp;
714 714 uintmax_t rvalue;
715 715 void *buf;
716 716 uint_t oflags = mdb.m_flags;
717 717
718 718 union {
719 719 uint64_t i8;
720 720 uint32_t i4;
721 721 uint16_t i2;
722 722 uint8_t i1;
723 723 double d;
724 724 } u;
725 725
↓ open down ↓ |
691 lines elided |
↑ open up ↑ |
726 726 if (fmt < 0 || fmt > (sizeof (fmttab) / sizeof (fmttab[0]))) {
727 727 warn("invalid format character -- '%c'\n", fmt);
728 728 return (addr);
729 729 }
730 730
731 731 if (!(fp->f_type & FMT_NOAUTOWRAP)) {
732 732 /*
733 733 * Unless a format has explicitly opted out, we force autowrap
734 734 * for the duration of mdb_fmt_print().
735 735 */
736 - mdb.m_flags |= MDB_FL_AUTOWRAP;
736 + mdb_iob_set_autowrap(mdb.m_out);
737 737 }
738 738
739 739 switch (FMT_TYPE(fp->f_type)) {
740 740 case FMT_FUNC:
741 741 funcp = (mdb_fmt_func_f *)fp->f_ptr;
742 742 addr = funcp(t, as, addr, cnt);
743 743 break;
744 744
745 745 case FMT_PRINTF:
746 746 switch (fp->f_size) {
747 747 case 1:
748 748 buf = &u.i1;
749 749 break;
750 750 case 2:
751 751 buf = &u.i2;
752 752 break;
753 753 case 4:
754 754 buf = &u.i4;
755 755 break;
756 756 case 8:
757 757 buf = &u.i8;
758 758 break;
759 759 default:
760 760 fail("format %c is defined using illegal size\n", fmt);
761 761 }
762 762
763 763 if (fp->f_float == B_TRUE) {
764 764 if (fp->f_size != 8) {
765 765 fail("format %c is using illegal fp size\n",
766 766 fmt);
767 767 }
768 768
769 769 buf = &u.d;
770 770 }
771 771
772 772 while (cnt-- != 0) {
773 773 if (mdb_tgt_aread(t, as, buf, fp->f_size, addr) !=
774 774 fp->f_size) {
775 775 warn("failed to read data from target");
776 776 return (addr);
777 777 }
778 778
779 779 switch (fp->f_size) {
780 780 case 1:
781 781 mdb_iob_printf(mdb.m_out, fp->f_ptr, u.i1);
782 782 rvalue = u.i1;
783 783 break;
784 784 case 2:
785 785 mdb_iob_printf(mdb.m_out, fp->f_ptr, u.i2);
786 786 rvalue = u.i2;
787 787 break;
788 788 case 4:
789 789 mdb_iob_printf(mdb.m_out, fp->f_ptr, u.i4);
790 790 rvalue = u.i4;
791 791 break;
792 792 case 8:
793 793 if (fp->f_float) {
794 794 mdb_iob_printf(mdb.m_out, fp->f_ptr,
795 795 u.d);
796 796 } else {
797 797 mdb_iob_printf(mdb.m_out, fp->f_ptr,
798 798 u.i8);
799 799 }
800 800 rvalue = u.i8;
801 801 break;
802 802 }
803 803
804 804 mdb_nv_set_value(mdb.m_rvalue, rvalue);
805 805 addr += fp->f_size;
806 806 }
807 807 break;
808 808
809 809 default:
810 810 warn("invalid format character -- '%c'\n", fmt);
811 811 }
812 812
813 813 mdb.m_flags = oflags;
814 814
815 815 return (addr);
816 816 }
817 817
818 818 /*ARGSUSED*/
819 819 int
820 820 cmd_formats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
821 821 {
822 822 const mdb_fmt_desc_t *fp = &fmttab[0];
823 823 int i;
824 824 const char *write;
825 825
826 826 if ((flags & DCMD_ADDRSPEC) || argc != 0)
827 827 return (DCMD_USAGE);
828 828
829 829 for (i = 0; i < (sizeof (fmttab) / sizeof (fmttab[0])); i++, fp++) {
830 830 if (fp->f_type == FMT_NONE)
831 831 continue;
832 832
833 833 write = (fp->f_type & FMT_WRITE) ? "write " : "";
834 834
835 835 if (fp->f_type & FMT_FUNC)
836 836 mdb_printf("%c - %s%s", i, write, fp->f_help);
837 837 else if (fp->f_type & FMT_MATCH)
838 838 mdb_printf("%c - match %s", i, fp->f_help);
839 839 else if (fp->f_help != NULL)
840 840 mdb_printf("%c - %s%s", i, write, fp->f_help);
841 841 else
842 842 mdb_printf("%c - %s%s", i, write,
843 843 mdb_iob_format2str(fp->f_ptr));
844 844
845 845 switch (fp->f_size) {
846 846 case SZ_NONE:
847 847 mdb_printf("\n");
848 848 break;
849 849 case 0:
850 850 mdb_printf(" (variable size)\n");
851 851 break;
852 852 case 1:
853 853 mdb_printf(" (1 byte)\n");
854 854 break;
855 855 default:
856 856 mdb_printf(" (%lu bytes)\n", fp->f_size);
857 857 }
858 858 }
859 859
860 860 return (DCMD_OK);
861 861 }
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX