1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <sys/types.h> 32 #include <unistd.h> 33 #include <sys/corectl.h> 34 #include <msg.h> 35 #include <_elfdump.h> 36 #include <struct_layout.h> 37 #include <conv.h> 38 39 40 /* 41 * This module contains the code that displays data from the note 42 * sections found in Solaris core files. The format of these 43 * note sections are described in the core(4) manpage. 44 */ 45 46 47 48 49 /* 50 * Much of the code in this file uses the "%*s" format to set 51 * the left margin indentation. This macro combines the indent 52 * integer argument and the NULL string that follows it. 53 */ 54 #define INDENT state->ns_indent, MSG_ORIG(MSG_STR_EMPTY) 55 56 /* 57 * Indent unit, used for each nesting 58 */ 59 #define INDENT_STEP 4 60 61 /* 62 * The PRINT_ macros are convenience wrappers on print_num(), 63 * print_subtype(), and print_strbuf(). They reduce code 64 * clutter by hiding the boilerplate arguments. 65 * 66 * Assumptions: 67 * - A variable named "layout" exists in the compilation 68 * environment, referencing the layout information for the 69 * current type. 70 * - The variable "state" references the current note state. 71 */ 72 #define PRINT_DEC(_title, _field) \ 73 print_num(state, _title, &layout->_field, SL_FMT_NUM_DEC) 74 #define PRINT_DEC_2UP(_title1, _field1, _title2, _field2) \ 75 print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_DEC, \ 76 _title2, &layout->_field2, SL_FMT_NUM_DEC) 77 #define PRINT_HEX(_title, _field) \ 78 print_num(state, _title, &layout->_field, SL_FMT_NUM_HEX) 79 #define PRINT_HEX_2UP(_title1, _field1, _title2, _field2) \ 80 print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_HEX, \ 81 _title2, &layout->_field2, SL_FMT_NUM_HEX) 82 #define PRINT_ZHEX(_title, _field) \ 83 print_num(state, _title, &layout->_field, SL_FMT_NUM_ZHEX) 84 #define PRINT_ZHEX_2UP(_title1, _field1, _title2, _field2) \ 85 print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_ZHEX, \ 86 _title2, &layout->_field2, SL_FMT_NUM_ZHEX) 87 #define PRINT_SUBTYPE(_title, _field, _func) \ 88 print_subtype(state, _title, &layout->_field, _func) 89 #define PRINT_STRBUF(_title, _field) \ 90 print_strbuf(state, _title, &layout->_field) 91 92 93 94 /* 95 * Structure used to maintain state data for a core note, or a subregion 96 * (sub-struct) of a core note. These values would otherwise need to be 97 * passed to nearly every routine. 98 */ 99 typedef struct { 100 Half ns_mach; /* ELF machine type of core file */ 101 const sl_arch_layout_t *ns_arch; /* structure layout def for mach */ 102 int ns_swap; /* True if byte swapping is needed */ 103 int ns_indent; /* Left margin indentation */ 104 int ns_vcol; /* Column where value starts */ 105 int ns_t2col; /* Column where 2up title starts */ 106 int ns_v2col; /* Column where 2up value starts */ 107 const char *ns_data; /* Pointer to struct data area */ 108 Word ns_len; /* Length of struct data area */ 109 } note_state_t; 110 111 /* 112 * Standard signature for a dump function used to process a note 113 * or a sub-structure within a note. 114 */ 115 typedef void (* dump_func_t)(note_state_t *state, const char *title); 116 117 118 119 120 121 122 /* 123 * Some core notes contain string buffers of fixed size 124 * that are expected to contain NULL terminated strings. 125 * If the NULL is there, we can print these strings directly. 126 * However, the potential exists for a corrupt file to have 127 * a non-terminated buffer. This routine examines the given 128 * string, and if the string is terminated, the string itself 129 * is returned. Otherwise, it is copied to a static buffer, 130 * and a pointer to the buffer is returned. 131 */ 132 static const char * 133 safe_str(const char *str, size_t n) 134 { 135 static char buf[512]; 136 char *s; 137 size_t i; 138 139 if (n == 0) 140 return (MSG_ORIG(MSG_STR_EMPTY)); 141 142 for (i = 0; i < n; i++) 143 if (str[i] == '\0') 144 return (str); 145 146 i = (n >= sizeof (buf)) ? (sizeof (buf) - 4) : (n - 1); 147 (void) memcpy(buf, str, i); 148 s = buf + i; 149 if (n >= sizeof (buf)) { 150 *s++ = '.'; 151 *s++ = '.'; 152 *s++ = '.'; 153 } 154 *s = '\0'; 155 return (buf); 156 } 157 158 /* 159 * Convenience wrappers on top of the corresponding sl_XXX() functions. 160 */ 161 static Word 162 extract_as_word(note_state_t *state, const sl_field_t *fdesc) 163 { 164 return (sl_extract_as_word(state->ns_data, state->ns_swap, fdesc)); 165 } 166 static Word 167 extract_as_lword(note_state_t *state, const sl_field_t *fdesc) 168 { 169 return (sl_extract_as_lword(state->ns_data, state->ns_swap, fdesc)); 170 } 171 static int 172 extract_as_sword(note_state_t *state, const sl_field_t *fdesc) 173 { 174 return (sl_extract_as_sword(state->ns_data, state->ns_swap, fdesc)); 175 } 176 static const char * 177 fmt_num(note_state_t *state, const sl_field_t *fdesc, 178 sl_fmt_num_t fmt_type, sl_fmtbuf_t buf) 179 { 180 return (sl_fmt_num(state->ns_data, state->ns_swap, fdesc, 181 fmt_type, buf)); 182 } 183 184 185 /* 186 * Return true of the data for the specified field is available. 187 */ 188 inline static int 189 data_present(note_state_t *state, const sl_field_t *fdesc) 190 { 191 return ((fdesc->slf_offset + fdesc->slf_eltlen) <= state->ns_len); 192 } 193 194 /* 195 * indent_enter/exit are used to start/end output for a subitem. 196 * On entry, a title is output, and the indentation level is raised 197 * by one unit. On exit, the indentation level is restrored to its 198 * previous value. 199 */ 200 static void 201 indent_enter(note_state_t *state, const char *title, 202 const sl_field_t *first_fdesc) 203 { 204 /* 205 * If the first field offset and extent fall past the end of the 206 * available data, then return without printing a title. That note 207 * is from an older core file that doesn't have all the fields 208 * that we know about. 209 */ 210 if (data_present(state, first_fdesc)) 211 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_TITLE), INDENT, title); 212 213 state->ns_indent += INDENT_STEP; 214 } 215 static void 216 indent_exit(note_state_t *state) 217 { 218 state->ns_indent -= INDENT_STEP; 219 } 220 221 222 /* 223 * print_num outputs a field on one line, in the format: 224 * 225 * title: value 226 */ 227 static void 228 print_num(note_state_t *state, const char *title, 229 const sl_field_t *fdesc, sl_fmt_num_t fmt_type) 230 { 231 sl_fmtbuf_t buf; 232 233 /* 234 * If the field offset and extent fall past the end of the 235 * available data, then return without doing anything. That note 236 * is from an older core file that doesn't have all the fields 237 * that we know about. 238 */ 239 if (!data_present(state, fdesc)) 240 return; 241 242 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT, 243 state->ns_vcol - state->ns_indent, title, 244 fmt_num(state, fdesc, fmt_type, buf)); 245 } 246 247 /* 248 * print_num_2up outputs two fields on one line, in the format: 249 * 250 * title1: value1 title2: value2 251 */ 252 static void 253 print_num_2up(note_state_t *state, const char *title1, 254 const sl_field_t *fdesc1, sl_fmt_num_t fmt_type1, const char *title2, 255 const sl_field_t *fdesc2, sl_fmt_num_t fmt_type2) 256 { 257 sl_fmtbuf_t buf1, buf2; 258 259 /* 260 * If the field offset and extent fall past the end of the 261 * available data, then return without doing anything. That note 262 * is from an older core file that doesn't have all the fields 263 * that we know about. 264 */ 265 if (!(data_present(state, fdesc1) && 266 data_present(state, fdesc2))) 267 return; 268 269 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 270 state->ns_vcol - state->ns_indent, title1, 271 state->ns_t2col - state->ns_vcol, 272 fmt_num(state, fdesc1, fmt_type1, buf1), 273 state->ns_v2col - state->ns_t2col, title2, 274 fmt_num(state, fdesc2, fmt_type2, buf2)); 275 } 276 277 /* 278 * print_strbuf outputs a fixed sized character buffer field 279 * on one line, in the format: 280 * 281 * title: value 282 */ 283 static void 284 print_strbuf(note_state_t *state, const char *title, 285 const sl_field_t *fdesc) 286 { 287 Word n; 288 289 /* 290 * If we are past the end of the data area, then return 291 * without doing anything. That note is from an older core 292 * file that doesn't have all the fields that we know about. 293 * 294 * Note that we are willing to accept a partial buffer, 295 * so we don't use data_present() for this test. 296 */ 297 if (fdesc->slf_offset >= state->ns_len) 298 return; 299 300 /* 301 * We expect the full buffer to be present, but if there 302 * is less than that, we will still proceed. The use of safe_str() 303 * protects us from the effect of printing garbage data. 304 */ 305 n = state->ns_len - fdesc->slf_offset; 306 if (n > fdesc->slf_nelts) 307 n = fdesc->slf_nelts; 308 309 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT, 310 state->ns_vcol - state->ns_indent, 311 title, safe_str(fdesc->slf_offset + state->ns_data, n)); 312 } 313 314 /* 315 * print_str outputs an arbitrary string value item 316 * on one line, in the format: 317 * 318 * title: str 319 */ 320 static void 321 print_str(note_state_t *state, const char *title, const char *str) 322 { 323 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT, 324 state->ns_vcol - state->ns_indent, title, str); 325 } 326 327 /* 328 * Used when one dump function needs to call another dump function 329 * in order to display a subitem. This routine constructs a state 330 * block for the sub-region, and then calls the dump function with it. 331 * This limits the amount of data visible to the sub-function to that 332 * for the sub-item. 333 */ 334 static void 335 print_subtype(note_state_t *state, const char *title, 336 const sl_field_t *fdesc, dump_func_t dump_func) 337 { 338 note_state_t sub_state; 339 340 /* 341 * If there is no data for the sub-item, return immediately. 342 * Partial data is left to the dump function to handle, 343 * as that can be a sign of an older core file with less data, 344 * which can still be interpreted. 345 */ 346 if (fdesc->slf_offset >= state->ns_len) 347 return; 348 349 /* 350 * Construct a state block that reflects the sub-item 351 */ 352 sub_state = *state; 353 sub_state.ns_data += fdesc->slf_offset; 354 sub_state.ns_len -= fdesc->slf_offset; 355 if (sub_state.ns_len > fdesc->slf_eltlen) 356 sub_state.ns_len = fdesc->slf_eltlen; 357 358 (* dump_func)(&sub_state, title); 359 } 360 361 362 /* 363 * Output a sequence of array elements, giving each 364 * element an index, in the format: 365 * 366 * [ndx] value 367 * 368 * entry: 369 * state - Current state 370 * base_desc - Field descriptor for 1st element of array 371 * nelts - # of array elements to display 372 * check_nelts - If True (1), nelts is clipped to fdesc->slf_nelts. 373 * If False (1), nelts is not clipped. 374 * title - Name of array 375 */ 376 static void 377 print_array(note_state_t *state, const sl_field_t *base_desc, 378 sl_fmt_num_t fmt_type, int nelts, int check_nelts, const char *title) 379 { 380 char index1[MAXNDXSIZE], index2[MAXNDXSIZE]; 381 int i; 382 sl_field_t fdesc1, fdesc2; 383 384 if (check_nelts && (check_nelts > base_desc->slf_nelts)) 385 nelts = base_desc->slf_nelts; 386 if (nelts == 0) 387 return; 388 389 indent_enter(state, title, base_desc); 390 391 fdesc1 = fdesc2 = *base_desc; 392 for (i = 0; i < nelts; ) { 393 if (i == (nelts - 1)) { 394 /* One final value is left */ 395 if (!data_present(state, &fdesc1)) 396 break; 397 (void) snprintf(index1, sizeof (index1), 398 MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i)); 399 print_num(state, index1, &fdesc1, fmt_type); 400 fdesc1.slf_offset += fdesc1.slf_eltlen; 401 i++; 402 continue; 403 } 404 405 /* There are at least 2 items left. Show 2 up. */ 406 fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; 407 if (!(data_present(state, &fdesc1) && 408 data_present(state, &fdesc2))) 409 break; 410 (void) snprintf(index1, sizeof (index1), 411 MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i)); 412 (void) snprintf(index2, sizeof (index2), 413 MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i + 1)); 414 print_num_2up(state, index1, &fdesc1, fmt_type, 415 index2, &fdesc2, fmt_type); 416 fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; 417 i += 2; 418 } 419 420 indent_exit(state); 421 } 422 423 424 /* 425 * Output information from auxv_t structure. 426 */ 427 static void 428 dump_auxv(note_state_t *state, const char *title) 429 { 430 const sl_auxv_layout_t *layout = state->ns_arch->auxv; 431 union { 432 Conv_cap_val_hw1_buf_t hw1; 433 Conv_cnote_auxv_af_buf_t auxv_af; 434 Conv_ehdr_flags_buf_t ehdr_flags; 435 Conv_inv_buf_t inv; 436 } conv_buf; 437 sl_fmtbuf_t buf; 438 int ndx, ndx_start; 439 Word sizeof_auxv; 440 441 sizeof_auxv = layout->sizeof_struct.slf_eltlen; 442 443 indent_enter(state, title, &layout->sizeof_struct); 444 445 /* 446 * Immediate indent_exit() restores the indent level to 447 * that of the title. We include indentation as part of 448 * the index string, which is right justified, and don't 449 * want the usual indentation spacing. 450 */ 451 indent_exit(state); 452 453 ndx = 0; 454 while (state->ns_len > sizeof_auxv) { 455 char index[(MAXNDXSIZE * 2) + 1]; 456 sl_fmt_num_t num_fmt = SL_FMT_NUM_ZHEX; 457 const char *vstr = NULL; 458 Word w; 459 int type; 460 sl_field_t a_type_next; 461 462 type = extract_as_word(state, &layout->a_type); 463 ndx_start = ndx; 464 switch (type) { 465 case AT_NULL: 466 a_type_next = layout->a_type; 467 a_type_next.slf_offset += sizeof_auxv; 468 while ((state->ns_len - sizeof_auxv) >= sizeof_auxv) { 469 type = extract_as_word(state, &a_type_next); 470 if (type != AT_NULL) 471 break; 472 ndx++; 473 state->ns_data += sizeof_auxv; 474 state->ns_len -= sizeof_auxv; 475 } 476 num_fmt = SL_FMT_NUM_HEX; 477 break; 478 479 480 481 case AT_IGNORE: 482 case AT_SUN_IFLUSH: 483 num_fmt = SL_FMT_NUM_HEX; 484 break; 485 486 case AT_EXECFD: 487 case AT_PHENT: 488 case AT_PHNUM: 489 case AT_PAGESZ: 490 case AT_SUN_UID: 491 case AT_SUN_RUID: 492 case AT_SUN_GID: 493 case AT_SUN_RGID: 494 case AT_SUN_LPAGESZ: 495 num_fmt = SL_FMT_NUM_DEC; 496 break; 497 498 case AT_FLAGS: /* processor flags */ 499 w = extract_as_word(state, &layout->a_val); 500 vstr = conv_ehdr_flags(state->ns_mach, w, 501 0, &conv_buf.ehdr_flags); 502 break; 503 504 case AT_SUN_HWCAP: 505 w = extract_as_word(state, &layout->a_val); 506 vstr = conv_cap_val_hw1(w, state->ns_mach, 507 0, &conv_buf.hw1); 508 /* 509 * conv_cap_val_hw1() produces output like: 510 * 511 * 0xfff [ flg1 flg2 0xff] 512 * 513 * where the first hex value is the complete value, 514 * and the second is the leftover bits. We only 515 * want the part in brackets, and failing that, 516 * would rather fall back to formatting the full 517 * value ourselves. 518 */ 519 while ((*vstr != '\0') && (*vstr != '[')) 520 vstr++; 521 if (*vstr != '[') 522 vstr = NULL; 523 num_fmt = SL_FMT_NUM_HEX; 524 break; 525 526 527 case AT_SUN_AUXFLAGS: 528 w = extract_as_word(state, &layout->a_val); 529 vstr = conv_cnote_auxv_af(w, 0, &conv_buf.auxv_af); 530 num_fmt = SL_FMT_NUM_HEX; 531 break; 532 } 533 534 if (ndx == ndx_start) 535 (void) snprintf(index, sizeof (index), 536 MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(ndx)); 537 else 538 (void) snprintf(index, sizeof (index), 539 MSG_ORIG(MSG_FMT_INDEXRNG), 540 EC_WORD(ndx_start), EC_WORD(ndx)); 541 542 if (vstr == NULL) 543 vstr = fmt_num(state, &layout->a_val, num_fmt, buf); 544 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_AUXVLINE), INDENT, index, 545 state->ns_vcol - state->ns_indent, 546 conv_cnote_auxv_type(type, CONV_FMT_DECIMAL, 547 &conv_buf.inv), vstr); 548 549 state->ns_data += sizeof_auxv; 550 state->ns_len -= sizeof_auxv; 551 ndx++; 552 } 553 } 554 555 556 /* 557 * Output information from fltset_t structure. 558 */ 559 static void 560 dump_fltset(note_state_t *state, const char *title) 561 { 562 #define NELTS 4 563 564 const sl_fltset_layout_t *layout = state->ns_arch->fltset; 565 Conv_cnote_fltset_buf_t buf; 566 sl_field_t fdesc; 567 uint32_t mask[NELTS]; 568 int i, nelts; 569 570 if (!data_present(state, &layout->sizeof_struct)) 571 return; 572 573 fdesc = layout->word; 574 nelts = fdesc.slf_nelts; 575 if (nelts > NELTS) /* Type has grown? Show what we understand */ 576 nelts = NELTS; 577 for (i = 0; i < nelts; i++) { 578 mask[i] = extract_as_word(state, &fdesc); 579 fdesc.slf_offset += fdesc.slf_eltlen; 580 } 581 582 print_str(state, title, conv_cnote_fltset(mask, nelts, 0, &buf)); 583 584 #undef NELTS 585 } 586 587 588 /* 589 * Output information from sigset_t structure. 590 */ 591 static void 592 dump_sigset(note_state_t *state, const char *title) 593 { 594 #define NELTS 4 595 596 const sl_sigset_layout_t *layout = state->ns_arch->sigset; 597 Conv_cnote_sigset_buf_t buf; 598 sl_field_t fdesc; 599 uint32_t mask[NELTS]; 600 int i, nelts; 601 602 if (!data_present(state, &layout->sizeof_struct)) 603 return; 604 605 fdesc = layout->sigbits; 606 nelts = fdesc.slf_nelts; 607 if (nelts > NELTS) /* Type has grown? Show what we understand */ 608 nelts = NELTS; 609 for (i = 0; i < nelts; i++) { 610 mask[i] = extract_as_word(state, &fdesc); 611 fdesc.slf_offset += fdesc.slf_eltlen; 612 } 613 614 print_str(state, title, conv_cnote_sigset(mask, nelts, 0, &buf)); 615 616 #undef NELTS 617 } 618 619 620 /* 621 * Output information from sigaction structure. 622 */ 623 static void 624 dump_sigaction(note_state_t *state, const char *title) 625 { 626 const sl_sigaction_layout_t *layout = state->ns_arch->sigaction; 627 Conv_cnote_sa_flags_buf_t conv_buf; 628 Word w; 629 630 indent_enter(state, title, &layout->sa_flags); 631 632 if (data_present(state, &layout->sa_flags)) { 633 w = extract_as_word(state, &layout->sa_flags); 634 print_str(state, MSG_ORIG(MSG_CNOTE_T_SA_FLAGS), 635 conv_cnote_sa_flags(w, 0, &conv_buf)); 636 } 637 638 PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_SA_HANDLER), sa_hand, 639 MSG_ORIG(MSG_CNOTE_T_SA_SIGACTION), sa_sigact); 640 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_SA_MASK), sa_mask, dump_sigset); 641 642 indent_exit(state); 643 } 644 645 646 /* 647 * Output information from siginfo structure. 648 */ 649 static void 650 dump_siginfo(note_state_t *state, const char *title) 651 { 652 const sl_siginfo_layout_t *layout = state->ns_arch->siginfo; 653 Conv_inv_buf_t inv_buf; 654 Word w; 655 int v_si_code, v_si_signo; 656 657 if (data_present(state, &layout->sizeof_struct)) 658 return; 659 660 indent_enter(state, title, &layout->f_si_signo); 661 662 v_si_signo = extract_as_sword(state, &layout->f_si_signo); 663 print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_SIGNO), 664 conv_cnote_signal(v_si_signo, CONV_FMT_DECIMAL, &inv_buf)); 665 666 w = extract_as_word(state, &layout->f_si_errno); 667 print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_ERRNO), 668 conv_cnote_errno(w, CONV_FMT_DECIMAL, &inv_buf)); 669 670 v_si_code = extract_as_sword(state, &layout->f_si_code); 671 print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_CODE), 672 conv_cnote_si_code(state->ns_mach, v_si_signo, v_si_code, 673 CONV_FMT_DECIMAL, &inv_buf)); 674 675 if ((v_si_signo == 0) || (v_si_code == SI_NOINFO)) { 676 indent_exit(state); 677 return; 678 } 679 680 /* User generated signals have (si_code <= 0) */ 681 if (v_si_code <= 0) { 682 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_PID), f_si_pid); 683 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_UID), f_si_uid); 684 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_CTID), f_si_ctid); 685 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_ZONEID), f_si_zoneid); 686 switch (v_si_code) { 687 case SI_QUEUE: 688 case SI_TIMER: 689 case SI_ASYNCIO: 690 case SI_MESGQ: 691 default: 692 indent_enter(state, MSG_ORIG(MSG_CNOTE_T_SI_VALUE), 693 &layout->f_si_value_int); 694 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SIVAL_INT), 695 f_si_value_int); 696 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SIVAL_PTR), 697 f_si_value_ptr); 698 indent_exit(state); 699 break; 700 } 701 indent_exit(state); 702 return; 703 } 704 705 /* 706 * Remaining cases are kernel generated signals. Output any 707 * signal or code specific information. 708 */ 709 if (v_si_code == SI_RCTL) 710 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_SI_ENTITY), f_si_entity); 711 switch (v_si_signo) { 712 case SIGILL: 713 case SIGFPE: 714 case SIGSEGV: 715 case SIGBUS: 716 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SI_ADDR), f_si_addr); 717 break; 718 case SIGCHLD: 719 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_PID), f_si_pid); 720 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_STATUS), f_si_status); 721 break; 722 case SIGPOLL: 723 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_BAND), f_si_band); 724 break; 725 } 726 727 indent_exit(state); 728 } 729 730 731 /* 732 * Output information from stack_t structure. 733 */ 734 static void 735 dump_stack(note_state_t *state, const char *title) 736 { 737 const sl_stack_layout_t *layout = state->ns_arch->stack; 738 Conv_cnote_ss_flags_buf_t conv_buf; 739 Word w; 740 741 indent_enter(state, title, &layout->ss_size); 742 743 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_SS_SP), &layout->ss_sp, 744 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_SS_SIZE), &layout->ss_size, 745 SL_FMT_NUM_HEX); 746 747 if (data_present(state, &layout->ss_flags)) { 748 w = extract_as_word(state, &layout->ss_flags); 749 print_str(state, MSG_ORIG(MSG_CNOTE_T_SS_FLAGS), 750 conv_cnote_ss_flags(w, 0, &conv_buf)); 751 } 752 753 indent_exit(state); 754 } 755 756 757 /* 758 * Output information from sysset_t structure. 759 */ 760 static void 761 dump_sysset(note_state_t *state, const char *title) 762 { 763 #define NELTS 16 764 765 const sl_sysset_layout_t *layout = state->ns_arch->sysset; 766 Conv_cnote_sysset_buf_t buf; 767 sl_field_t fdesc; 768 uint32_t mask[NELTS]; 769 int i, nelts; 770 771 if (!data_present(state, &layout->sizeof_struct)) 772 return; 773 774 fdesc = layout->word; 775 nelts = fdesc.slf_nelts; 776 if (nelts > NELTS) /* Type has grown? Show what we understand */ 777 nelts = NELTS; 778 for (i = 0; i < nelts; i++) { 779 mask[i] = extract_as_word(state, &fdesc); 780 fdesc.slf_offset += fdesc.slf_eltlen; 781 } 782 783 print_str(state, title, conv_cnote_sysset(mask, nelts, 0, &buf)); 784 785 #undef NELTS 786 } 787 788 789 /* 790 * Output information from timestruc_t structure. 791 */ 792 static void 793 dump_timestruc(note_state_t *state, const char *title) 794 { 795 const sl_timestruc_layout_t *layout = state->ns_arch->timestruc; 796 797 indent_enter(state, title, &layout->tv_sec); 798 799 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_TV_SEC), tv_sec, 800 MSG_ORIG(MSG_CNOTE_T_TV_NSEC), tv_nsec); 801 802 indent_exit(state); 803 } 804 805 806 /* 807 * Output information from utsname structure. 808 */ 809 static void 810 dump_utsname(note_state_t *state, const char *title) 811 { 812 const sl_utsname_layout_t *layout = state->ns_arch->utsname; 813 814 indent_enter(state, title, &layout->sysname); 815 816 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_SYSNAME), sysname); 817 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_NODENAME), nodename); 818 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_RELEASE), release); 819 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_VERSION), version); 820 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_MACHINE), machine); 821 822 indent_exit(state); 823 } 824 825 826 /* 827 * Dump register contents 828 */ 829 static void 830 dump_prgregset(note_state_t *state, const char *title) 831 { 832 sl_field_t fdesc1, fdesc2; 833 sl_fmtbuf_t buf1, buf2; 834 Conv_inv_buf_t inv_buf1, inv_buf2; 835 Word w; 836 837 indent_enter(state, title, &fdesc1); 838 839 fdesc1 = fdesc2 = state->ns_arch->prgregset->elt0; 840 for (w = 0; w < fdesc1.slf_nelts; ) { 841 if (w == (fdesc1.slf_nelts - 1)) { 842 /* One last register is left */ 843 if (!data_present(state, &fdesc1)) 844 break; 845 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), 846 INDENT, state->ns_vcol - state->ns_indent, 847 conv_cnote_pr_regname(state->ns_mach, w, 848 CONV_FMT_DECIMAL, &inv_buf1), 849 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1)); 850 fdesc1.slf_offset += fdesc1.slf_eltlen; 851 w++; 852 continue; 853 } 854 855 /* There are at least 2 more registers left. Show 2 up */ 856 fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; 857 if (!(data_present(state, &fdesc1) && 858 data_present(state, &fdesc2))) 859 break; 860 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 861 state->ns_vcol - state->ns_indent, 862 conv_cnote_pr_regname(state->ns_mach, w, 863 CONV_FMT_DECIMAL, &inv_buf1), 864 state->ns_t2col - state->ns_vcol, 865 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1), 866 state->ns_v2col - state->ns_t2col, 867 conv_cnote_pr_regname(state->ns_mach, w + 1, 868 CONV_FMT_DECIMAL, &inv_buf2), 869 fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2)); 870 fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; 871 w += 2; 872 } 873 874 indent_exit(state); 875 } 876 877 /* 878 * Output information from lwpstatus_t structure. 879 */ 880 static void 881 dump_lwpstatus(note_state_t *state, const char *title) 882 { 883 const sl_lwpstatus_layout_t *layout = state->ns_arch->lwpstatus; 884 Word w, w2; 885 int32_t i; 886 union { 887 Conv_inv_buf_t inv; 888 Conv_cnote_pr_flags_buf_t flags; 889 } conv_buf; 890 891 indent_enter(state, title, &layout->pr_flags); 892 893 if (data_present(state, &layout->pr_flags)) { 894 w = extract_as_word(state, &layout->pr_flags); 895 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), 896 conv_cnote_pr_flags(w, 0, &conv_buf.flags)); 897 } 898 899 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LWPID), pr_lwpid); 900 901 if (data_present(state, &layout->pr_why)) { 902 w = extract_as_word(state, &layout->pr_why); 903 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHY), 904 conv_cnote_pr_why(w, 0, &conv_buf.inv)); 905 } 906 907 if (data_present(state, &layout->pr_what)) { 908 w2 = extract_as_word(state, &layout->pr_what); 909 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHAT), 910 conv_cnote_pr_what(w, w2, 0, &conv_buf.inv)); 911 } 912 913 if (data_present(state, &layout->pr_cursig)) { 914 w = extract_as_word(state, &layout->pr_cursig); 915 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_CURSIG), 916 conv_cnote_signal(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 917 } 918 919 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_INFO), pr_info, dump_siginfo); 920 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPPEND), pr_lwppend, 921 dump_sigset); 922 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPHOLD), pr_lwphold, 923 dump_sigset); 924 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ACTION), pr_action, 925 dump_sigaction); 926 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ALTSTACK), pr_altstack, 927 dump_stack); 928 929 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_OLDCONTEXT), pr_oldcontext); 930 931 if (data_present(state, &layout->pr_syscall)) { 932 w = extract_as_word(state, &layout->pr_syscall); 933 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 934 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 935 } 936 937 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSYSARG), pr_nsysarg); 938 939 if (data_present(state, &layout->pr_errno)) { 940 w = extract_as_word(state, &layout->pr_errno); 941 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_ERRNO), 942 conv_cnote_errno(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 943 } 944 945 if (data_present(state, &layout->pr_nsysarg)) { 946 w2 = extract_as_word(state, &layout->pr_nsysarg); 947 print_array(state, &layout->pr_sysarg, SL_FMT_NUM_ZHEX, w2, 1, 948 MSG_ORIG(MSG_CNOTE_T_PR_SYSARG)); 949 } 950 951 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RVAL1), pr_rval1, 952 MSG_ORIG(MSG_CNOTE_T_PR_RVAL2), pr_rval2); 953 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 954 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TSTAMP), pr_tstamp, 955 dump_timestruc); 956 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); 957 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); 958 959 if (data_present(state, &layout->pr_errpriv)) { 960 i = extract_as_sword(state, &layout->pr_errpriv); 961 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_ERRPRIV), 962 conv_cnote_priv(i, CONV_FMT_DECIMAL, &conv_buf.inv)); 963 } 964 965 PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_USTACK), pr_ustack, 966 MSG_ORIG(MSG_CNOTE_T_PR_INSTR), pr_instr); 967 968 /* 969 * In order to line up all the values in a single column, 970 * we would have to set vcol to a very high value, which results 971 * in ugly looking output that runs off column 80. So, we use 972 * two levels of vcol, one for the contents so far, and a 973 * higher one for the pr_reg sub-struct. 974 */ 975 state->ns_vcol += 3; 976 state->ns_t2col += 3; 977 state->ns_v2col += 2; 978 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_REG), pr_reg, dump_prgregset); 979 state->ns_vcol -= 3; 980 state->ns_t2col -= 3; 981 state->ns_v2col -= 2; 982 983 /* 984 * The floating point register state is complex, and highly 985 * platform dependent. For now, we simply display it as 986 * a hex dump. This can be replaced if better information 987 * is required. 988 */ 989 if (data_present(state, &layout->pr_fpreg)) { 990 indent_enter(state, MSG_ORIG(MSG_CNOTE_T_PR_FPREG), 991 &layout->pr_fpreg); 992 dump_hex_bytes(layout->pr_fpreg.slf_offset + state->ns_data, 993 layout->pr_fpreg.slf_eltlen, state->ns_indent, 4, 3); 994 indent_exit(state); 995 } 996 997 indent_exit(state); 998 } 999 1000 1001 /* 1002 * Output information from pstatus_t structure. 1003 */ 1004 static void 1005 dump_pstatus(note_state_t *state, const char *title) 1006 { 1007 const sl_pstatus_layout_t *layout = state->ns_arch->pstatus; 1008 Word w; 1009 union { 1010 Conv_inv_buf_t inv; 1011 Conv_cnote_pr_flags_buf_t flags; 1012 } conv_buf; 1013 1014 indent_enter(state, title, &layout->pr_flags); 1015 1016 if (data_present(state, &layout->pr_flags)) { 1017 w = extract_as_word(state, &layout->pr_flags); 1018 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), 1019 conv_cnote_pr_flags(w, 0, &conv_buf.flags)); 1020 } 1021 1022 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); 1023 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1024 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1025 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid, 1026 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1027 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid, 1028 MSG_ORIG(MSG_CNOTE_T_PR_AGENTID), pr_agentid); 1029 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGPEND), pr_sigpend, 1030 dump_sigset); 1031 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_BRKBASE), 1032 &layout->pr_brkbase, SL_FMT_NUM_ZHEX, 1033 MSG_ORIG(MSG_CNOTE_T_PR_BRKSIZE), 1034 &layout->pr_brksize, SL_FMT_NUM_HEX); 1035 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_STKBASE), 1036 &layout->pr_stkbase, SL_FMT_NUM_ZHEX, 1037 MSG_ORIG(MSG_CNOTE_T_PR_STKSIZE), 1038 &layout->pr_stksize, SL_FMT_NUM_HEX); 1039 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); 1040 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); 1041 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CUTIME), pr_cutime, 1042 dump_timestruc); 1043 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CSTIME), pr_cstime, 1044 dump_timestruc); 1045 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGTRACE), pr_sigtrace, 1046 dump_sigset); 1047 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_FLTTRACE), pr_flttrace, 1048 dump_fltset); 1049 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SYSENTRY), pr_sysentry, 1050 dump_sysset); 1051 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SYSEXIT), pr_sysexit, 1052 dump_sysset); 1053 1054 if (data_present(state, &layout->pr_dmodel)) { 1055 w = extract_as_word(state, &layout->pr_dmodel); 1056 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), 1057 conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); 1058 } 1059 1060 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid, 1061 MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid); 1062 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb, 1063 MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid); 1064 1065 /* 1066 * In order to line up all the values in a single column, 1067 * we would have to set vcol to a very high value, which results 1068 * in ugly looking output that runs off column 80. So, we use 1069 * two levels of vcol, one for the contents so far, and a 1070 * higher one for the pr_lwp sub-struct. 1071 */ 1072 state->ns_vcol += 5; 1073 state->ns_t2col += 5; 1074 state->ns_v2col += 5; 1075 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpstatus); 1076 state->ns_vcol -= 5; 1077 state->ns_t2col -= 5; 1078 state->ns_v2col -= 5; 1079 1080 indent_exit(state); 1081 } 1082 1083 1084 /* 1085 * Output information from prstatus_t (<sys/old_procfs.h>) structure. 1086 */ 1087 static void 1088 dump_prstatus(note_state_t *state, const char *title) 1089 { 1090 const sl_prstatus_layout_t *layout = state->ns_arch->prstatus; 1091 Word w, w2; 1092 int i; 1093 union { 1094 Conv_inv_buf_t inv; 1095 Conv_cnote_old_pr_flags_buf_t flags; 1096 } conv_buf; 1097 1098 indent_enter(state, title, &layout->pr_flags); 1099 1100 if (data_present(state, &layout->pr_flags)) { 1101 w = extract_as_word(state, &layout->pr_flags); 1102 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), 1103 conv_cnote_old_pr_flags(w, 0, &conv_buf.flags)); 1104 } 1105 1106 if (data_present(state, &layout->pr_why)) { 1107 w = extract_as_word(state, &layout->pr_why); 1108 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHY), 1109 conv_cnote_pr_why(w, 0, &conv_buf.inv)); 1110 } 1111 1112 if (data_present(state, &layout->pr_what)) { 1113 w2 = extract_as_word(state, &layout->pr_what); 1114 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHAT), 1115 conv_cnote_pr_what(w, w2, 0, &conv_buf.inv)); 1116 } 1117 1118 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_INFO), pr_info, dump_siginfo); 1119 1120 if (data_present(state, &layout->pr_cursig)) { 1121 w = extract_as_word(state, &layout->pr_cursig); 1122 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_CURSIG), 1123 conv_cnote_signal(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1124 } 1125 1126 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); 1127 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGPEND), pr_sigpend, 1128 dump_sigset); 1129 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGHOLD), pr_sighold, 1130 dump_sigset); 1131 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ALTSTACK), pr_altstack, 1132 dump_stack); 1133 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ACTION), pr_action, 1134 dump_sigaction); 1135 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1136 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1137 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp, 1138 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1139 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); 1140 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); 1141 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CUTIME), pr_cutime, 1142 dump_timestruc); 1143 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CSTIME), pr_cstime, 1144 dump_timestruc); 1145 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1146 1147 if (data_present(state, &layout->pr_syscall)) { 1148 w = extract_as_word(state, &layout->pr_syscall); 1149 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1150 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1151 } 1152 1153 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSYSARG), pr_nsysarg); 1154 1155 if (data_present(state, &layout->pr_nsysarg)) { 1156 w2 = extract_as_word(state, &layout->pr_nsysarg); 1157 print_array(state, &layout->pr_sysarg, SL_FMT_NUM_ZHEX, w2, 1, 1158 MSG_ORIG(MSG_CNOTE_T_PR_SYSARG)); 1159 } 1160 1161 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_WHO), pr_who); 1162 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPPEND), pr_sigpend, 1163 dump_sigset); 1164 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_OLDCONTEXT), pr_oldcontext); 1165 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_BRKBASE), 1166 &layout->pr_brkbase, SL_FMT_NUM_ZHEX, 1167 MSG_ORIG(MSG_CNOTE_T_PR_BRKSIZE), 1168 &layout->pr_brksize, SL_FMT_NUM_HEX); 1169 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_STKBASE), 1170 &layout->pr_stkbase, SL_FMT_NUM_ZHEX, 1171 MSG_ORIG(MSG_CNOTE_T_PR_STKSIZE), 1172 &layout->pr_stksize, SL_FMT_NUM_HEX); 1173 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_PROCESSOR), pr_processor); 1174 1175 if (data_present(state, &layout->pr_bind)) { 1176 i = extract_as_sword(state, &layout->pr_bind); 1177 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BIND), 1178 conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv)); 1179 } 1180 1181 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_INSTR), pr_instr); 1182 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_REG), pr_reg, dump_prgregset); 1183 1184 indent_exit(state); 1185 } 1186 1187 1188 /* 1189 * Print percent from 16-bit binary fraction [0 .. 1] 1190 * Round up .01 to .1 to indicate some small percentage (the 0x7000 below). 1191 * 1192 * Note: This routine was copied from ps(1) and then modified. 1193 */ 1194 static const char * 1195 prtpct_value(note_state_t *state, const sl_field_t *fdesc, 1196 sl_fmtbuf_t buf) 1197 { 1198 uint_t value; /* need 32 bits to compute with */ 1199 1200 value = extract_as_word(state, fdesc); 1201 value = ((value * 1000) + 0x7000) >> 15; /* [0 .. 1000] */ 1202 if (value >= 1000) 1203 value = 999; 1204 1205 (void) snprintf(buf, sizeof (sl_fmtbuf_t), 1206 MSG_ORIG(MSG_CNOTE_FMT_PRTPCT), value / 10, value % 10); 1207 1208 return (buf); 1209 } 1210 1211 1212 1213 /* 1214 * Version of prtpct() used for a 2-up display of two adjacent percentages. 1215 */ 1216 static void 1217 prtpct_2up(note_state_t *state, const sl_field_t *fdesc1, 1218 const char *title1, const sl_field_t *fdesc2, const char *title2) 1219 { 1220 sl_fmtbuf_t buf1, buf2; 1221 1222 if (!(data_present(state, fdesc1) && 1223 data_present(state, fdesc2))) 1224 return; 1225 1226 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1227 state->ns_vcol - state->ns_indent, title1, 1228 state->ns_t2col - state->ns_vcol, 1229 prtpct_value(state, fdesc1, buf1), 1230 state->ns_v2col - state->ns_t2col, title2, 1231 prtpct_value(state, fdesc2, buf2)); 1232 } 1233 1234 1235 /* 1236 * The psinfo_t and prpsinfo_t structs have pr_state and pr_sname 1237 * fields that we wish to print in a 2up format. The pr_state is 1238 * an integer, while pr_sname is a single character. 1239 */ 1240 static void 1241 print_state_sname_2up(note_state_t *state, 1242 const sl_field_t *state_fdesc, 1243 const sl_field_t *sname_fdesc) 1244 { 1245 sl_fmtbuf_t buf1, buf2; 1246 int sname; 1247 1248 /* 1249 * If the field slf_offset and extent fall past the end of the 1250 * available data, then return without doing anything. That note 1251 * is from an older core file that doesn't have all the fields 1252 * that we know about. 1253 */ 1254 if (!(data_present(state, state_fdesc) && 1255 data_present(state, sname_fdesc))) 1256 return; 1257 1258 sname = extract_as_sword(state, sname_fdesc); 1259 buf2[0] = sname; 1260 buf2[1] = '\0'; 1261 1262 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1263 state->ns_vcol - state->ns_indent, MSG_ORIG(MSG_CNOTE_T_PR_STATE), 1264 state->ns_t2col - state->ns_vcol, 1265 fmt_num(state, state_fdesc, SL_FMT_NUM_DEC, buf1), 1266 state->ns_v2col - state->ns_t2col, MSG_ORIG(MSG_CNOTE_T_PR_SNAME), 1267 buf2); 1268 } 1269 1270 /* 1271 * Output information from lwpsinfo_t structure. 1272 */ 1273 static void 1274 dump_lwpsinfo(note_state_t *state, const char *title) 1275 { 1276 const sl_lwpsinfo_layout_t *layout = state->ns_arch->lwpsinfo; 1277 Word w; 1278 int32_t i; 1279 union { 1280 Conv_cnote_proc_flag_buf_t proc_flag; 1281 Conv_inv_buf_t inv; 1282 } conv_buf; 1283 1284 indent_enter(state, title, &layout->pr_flag); 1285 1286 if (data_present(state, &layout->pr_flag)) { 1287 w = extract_as_word(state, &layout->pr_flag); 1288 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1289 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1290 } 1291 1292 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_LWPID), &layout->pr_lwpid, 1293 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, 1294 SL_FMT_NUM_ZHEX); 1295 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan); 1296 1297 if (data_present(state, &layout->pr_stype)) { 1298 w = extract_as_word(state, &layout->pr_stype); 1299 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_STYPE), 1300 conv_cnote_pr_stype(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1301 } 1302 1303 print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname); 1304 1305 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice); 1306 1307 if (data_present(state, &layout->pr_syscall)) { 1308 w = extract_as_word(state, &layout->pr_syscall); 1309 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1310 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1311 } 1312 1313 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri, 1314 MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu); 1315 1316 if (data_present(state, &layout->pr_pri) && 1317 data_present(state, &layout->pr_pctcpu)) { 1318 sl_fmtbuf_t buf1, buf2; 1319 1320 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1321 state->ns_vcol - state->ns_indent, 1322 MSG_ORIG(MSG_CNOTE_T_PR_PRI), 1323 state->ns_t2col - state->ns_vcol, 1324 fmt_num(state, &layout->pr_pri, SL_FMT_NUM_DEC, buf1), 1325 state->ns_v2col - state->ns_t2col, 1326 MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1327 prtpct_value(state, &layout->pr_pctcpu, buf2)); 1328 } 1329 1330 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1331 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1332 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1333 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_NAME), pr_name); 1334 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ONPRO), pr_onpro, 1335 MSG_ORIG(MSG_CNOTE_T_PR_BINDPRO), pr_bindpro); 1336 1337 if (data_present(state, &layout->pr_bindpset)) { 1338 i = extract_as_sword(state, &layout->pr_bindpset); 1339 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BINDPSET), 1340 conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv)); 1341 } 1342 1343 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LGRP), pr_lgrp); 1344 1345 indent_exit(state); 1346 } 1347 1348 1349 /* 1350 * Output information from psinfo_t structure. 1351 */ 1352 static void 1353 dump_psinfo(note_state_t *state, const char *title) 1354 { 1355 const sl_psinfo_layout_t *layout = state->ns_arch->psinfo; 1356 Word w; 1357 union { 1358 Conv_cnote_proc_flag_buf_t proc_flag; 1359 Conv_inv_buf_t inv; 1360 } conv_buf; 1361 1362 indent_enter(state, title, &layout->pr_flag); 1363 1364 if (data_present(state, &layout->pr_flag)) { 1365 w = extract_as_word(state, &layout->pr_flag); 1366 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1367 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1368 } 1369 1370 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); 1371 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1372 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1373 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid, 1374 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1375 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, 1376 MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid); 1377 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid, 1378 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 1379 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, 1380 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size, 1381 SL_FMT_NUM_HEX); 1382 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), 1383 &layout->pr_rssize, SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_TTYDEV), 1384 &layout->pr_ttydev, SL_FMT_NUM_DEC); 1385 prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1386 &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM)); 1387 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1388 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1389 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc); 1390 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname); 1391 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs); 1392 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat, 1393 SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc, 1394 SL_FMT_NUM_DEC); 1395 PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ARGV), pr_argv, 1396 MSG_ORIG(MSG_CNOTE_T_PR_ENVP), pr_envp); 1397 1398 if (data_present(state, &layout->pr_dmodel)) { 1399 w = extract_as_word(state, &layout->pr_dmodel); 1400 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), 1401 conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); 1402 } 1403 1404 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid, 1405 MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid); 1406 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb, 1407 MSG_ORIG(MSG_CNOTE_T_PR_POOLID), pr_poolid); 1408 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid, 1409 MSG_ORIG(MSG_CNOTE_T_PR_CONTRACT), pr_contract); 1410 1411 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpsinfo); 1412 1413 indent_exit(state); 1414 } 1415 1416 1417 /* 1418 * Output information from prpsinfo_t structure. 1419 */ 1420 static void 1421 dump_prpsinfo(note_state_t *state, const char *title) 1422 { 1423 const sl_prpsinfo_layout_t *layout = state->ns_arch->prpsinfo; 1424 Word w; 1425 union { 1426 Conv_cnote_proc_flag_buf_t proc_flag; 1427 Conv_inv_buf_t inv; 1428 } conv_buf; 1429 1430 indent_enter(state, title, &layout->pr_state); 1431 1432 print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname); 1433 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZOMB), pr_zomb, 1434 MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice); 1435 1436 if (data_present(state, &layout->pr_flag)) { 1437 w = extract_as_word(state, &layout->pr_flag); 1438 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1439 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1440 } 1441 1442 1443 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, 1444 MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid); 1445 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1446 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1447 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp, 1448 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1449 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, 1450 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size, 1451 SL_FMT_NUM_HEX); 1452 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), pr_rssize, 1453 MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan); 1454 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1455 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1456 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PRI), pr_pri, 1457 MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri); 1458 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu); 1459 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OTTYDEV), pr_ottydev, 1460 MSG_ORIG(MSG_CNOTE_T_PR_LTTYDEV), pr_lttydev); 1461 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1462 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname); 1463 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs); 1464 1465 if (data_present(state, &layout->pr_syscall)) { 1466 w = extract_as_word(state, &layout->pr_syscall); 1467 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1468 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1469 } 1470 1471 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc); 1472 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_BYSIZE), pr_bysize, 1473 MSG_ORIG(MSG_CNOTE_T_PR_BYRSSIZE), pr_byrssize); 1474 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc, 1475 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ARGV), &layout->pr_argv, 1476 SL_FMT_NUM_ZHEX); 1477 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ENVP), &layout->pr_envp, 1478 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat, 1479 SL_FMT_NUM_HEX); 1480 prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1481 &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM)); 1482 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid, 1483 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 1484 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid); 1485 1486 if (data_present(state, &layout->pr_dmodel)) { 1487 w = extract_as_word(state, &layout->pr_dmodel); 1488 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), 1489 conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); 1490 } 1491 1492 indent_exit(state); 1493 } 1494 1495 1496 /* 1497 * Output information from prcred_t structure. 1498 */ 1499 static void 1500 dump_prcred(note_state_t *state, const char *title) 1501 { 1502 const sl_prcred_layout_t *layout = state->ns_arch->prcred; 1503 Word ngroups; 1504 1505 indent_enter(state, title, &layout->pr_euid); 1506 1507 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid, 1508 MSG_ORIG(MSG_CNOTE_T_PR_RUID), pr_ruid); 1509 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_SUID), pr_suid, 1510 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 1511 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RGID), pr_rgid, 1512 MSG_ORIG(MSG_CNOTE_T_PR_SGID), pr_sgid); 1513 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NGROUPS), pr_ngroups); 1514 1515 if (data_present(state, &layout->pr_ngroups)) { 1516 ngroups = extract_as_word(state, &layout->pr_ngroups); 1517 print_array(state, &layout->pr_groups, SL_FMT_NUM_DEC, ngroups, 1518 0, MSG_ORIG(MSG_CNOTE_T_PR_GROUPS)); 1519 } 1520 1521 indent_exit(state); 1522 } 1523 1524 1525 /* 1526 * Output information from prpriv_t structure. 1527 */ 1528 static void 1529 dump_prpriv(note_state_t *state, const char *title) 1530 { 1531 const sl_prpriv_layout_t *layout = state->ns_arch->prpriv; 1532 Word nsets; 1533 1534 indent_enter(state, title, &layout->pr_nsets); 1535 1536 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSETS), pr_nsets); 1537 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_SETSIZE), pr_setsize); 1538 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_INFOSIZE), pr_infosize); 1539 1540 if (data_present(state, &layout->pr_nsets)) { 1541 nsets = extract_as_word(state, &layout->pr_nsets); 1542 print_array(state, &layout->pr_sets, SL_FMT_NUM_ZHEX, nsets, 1543 0, MSG_ORIG(MSG_CNOTE_T_PR_SETS)); 1544 } 1545 1546 indent_exit(state); 1547 } 1548 1549 1550 /* 1551 * Output information from priv_impl_info_t structure. 1552 */ 1553 static void 1554 dump_priv_impl_info(note_state_t *state, const char *title) 1555 { 1556 const sl_priv_impl_info_layout_t *layout; 1557 1558 layout = state->ns_arch->priv_impl_info; 1559 indent_enter(state, title, &layout->priv_headersize); 1560 1561 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PRIV_HEADERSIZE), priv_headersize, 1562 MSG_ORIG(MSG_CNOTE_T_PRIV_FLAGS), priv_flags); 1563 1564 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_NSETS), 1565 &layout->priv_nsets, SL_FMT_NUM_DEC, 1566 MSG_ORIG(MSG_CNOTE_T_PRIV_SETSIZE), &layout->priv_setsize, 1567 SL_FMT_NUM_HEX); 1568 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_MAX), &layout->priv_max, 1569 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PRIV_INFOSIZE), 1570 &layout->priv_infosize, SL_FMT_NUM_HEX); 1571 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PRIV_GLOBALINFOSIZE), 1572 priv_globalinfosize); 1573 1574 indent_exit(state); 1575 } 1576 1577 1578 /* 1579 * Dump information from an asrset_t array. This data 1580 * structure is specific to sparcv9, and does not appear 1581 * on any other platform. 1582 * 1583 * asrset_t is a simple array, defined in <sys/regset.h> as 1584 * typedef int64_t asrset_t[16]; %asr16 - > %asr31 1585 * 1586 * As such, we do not make use of the struct_layout facilities 1587 * for this routine. 1588 */ 1589 static void 1590 dump_asrset(note_state_t *state, const char *title) 1591 { 1592 static const sl_field_t ftemplate = { 0, sizeof (int64_t), 16, 0 }; 1593 sl_field_t fdesc1, fdesc2; 1594 sl_fmtbuf_t buf1, buf2; 1595 char index1[MAXNDXSIZE * 2], index2[MAXNDXSIZE * 2]; 1596 Word w, nelts; 1597 1598 fdesc1 = fdesc2 = ftemplate; 1599 1600 /* We expect 16 values, but will print whatever is actually there */ 1601 nelts = state->ns_len / ftemplate.slf_eltlen; 1602 if (nelts == 0) 1603 return; 1604 1605 indent_enter(state, title, &fdesc1); 1606 1607 for (w = 0; w < nelts; ) { 1608 (void) snprintf(index1, sizeof (index1), 1609 MSG_ORIG(MSG_FMT_ASRINDEX), w + 16); 1610 1611 if (w == (nelts - 1)) { 1612 /* One last register is left */ 1613 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), 1614 INDENT, state->ns_vcol - state->ns_indent, index1, 1615 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1)); 1616 fdesc1.slf_offset += fdesc1.slf_eltlen; 1617 w++; 1618 continue; 1619 } 1620 1621 /* There are at least 2 more registers left. Show 2 up */ 1622 (void) snprintf(index2, sizeof (index2), 1623 MSG_ORIG(MSG_FMT_ASRINDEX), w + 17); 1624 1625 fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; 1626 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1627 state->ns_vcol - state->ns_indent, index1, 1628 state->ns_t2col - state->ns_vcol, 1629 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1), 1630 state->ns_v2col - state->ns_t2col, index2, 1631 fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2)); 1632 fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; 1633 w += 2; 1634 } 1635 1636 indent_exit(state); 1637 } 1638 1639 corenote_ret_t 1640 corenote(Half mach, int do_swap, Word type, 1641 const char *desc, Word descsz) 1642 { 1643 note_state_t state; 1644 1645 /* 1646 * Get the per-architecture layout definition 1647 */ 1648 state.ns_mach = mach; 1649 state.ns_arch = sl_mach(state.ns_mach); 1650 if (sl_mach(state.ns_mach) == NULL) 1651 return (CORENOTE_R_BADARCH); 1652 1653 state.ns_swap = do_swap; 1654 state.ns_indent = 4; 1655 state.ns_t2col = state.ns_v2col = 0; 1656 state.ns_data = desc; 1657 state.ns_len = descsz; 1658 1659 switch (type) { 1660 case NT_PRSTATUS: /* prstatus_t <sys/old_procfs.h> */ 1661 state.ns_vcol = 26; 1662 state.ns_t2col = 46; 1663 state.ns_v2col = 60; 1664 dump_prstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSTATUS_T)); 1665 return (CORENOTE_R_OK); 1666 1667 case NT_PRFPREG: /* prfpregset_t <sys/procfs_isa.h> */ 1668 return (CORENOTE_R_OK_DUMP); 1669 1670 case NT_PRPSINFO: /* prpsinfo_t <sys/old_procfs.h> */ 1671 state.ns_vcol = 20; 1672 state.ns_t2col = 41; 1673 state.ns_v2col = 54; 1674 dump_prpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPSINFO_T)); 1675 return (CORENOTE_R_OK); 1676 1677 case NT_PRXREG: /* prxregset_t <sys/procfs_isa.h> */ 1678 return (CORENOTE_R_OK_DUMP); 1679 1680 case NT_PLATFORM: /* string from sysinfo(SI_PLATFORM) */ 1681 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); 1682 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz)); 1683 return (CORENOTE_R_OK); 1684 1685 case NT_AUXV: /* auxv_t array <sys/auxv.h> */ 1686 state.ns_vcol = 18; 1687 dump_auxv(&state, MSG_ORIG(MSG_CNOTE_DESC_AUXV_T)); 1688 return (CORENOTE_R_OK); 1689 1690 case NT_GWINDOWS: /* gwindows_t SPARC only */ 1691 return (CORENOTE_R_OK_DUMP); 1692 1693 case NT_ASRS: /* asrset_t <sys/regset> sparcv9 only */ 1694 state.ns_vcol = 18; 1695 state.ns_t2col = 38; 1696 state.ns_v2col = 46; 1697 dump_asrset(&state, MSG_ORIG(MSG_CNOTE_DESC_ASRSET_T)); 1698 return (CORENOTE_R_OK); 1699 1700 case NT_LDT: /* ssd array <sys/sysi86.h> IA32 only */ 1701 return (CORENOTE_R_OK_DUMP); 1702 1703 case NT_PSTATUS: /* pstatus_t <sys/procfs.h> */ 1704 state.ns_vcol = 22; 1705 state.ns_t2col = 42; 1706 state.ns_v2col = 54; 1707 dump_pstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PSTATUS_T)); 1708 return (CORENOTE_R_OK); 1709 1710 case NT_PSINFO: /* psinfo_t <sys/procfs.h> */ 1711 state.ns_vcol = 25; 1712 state.ns_t2col = 45; 1713 state.ns_v2col = 58; 1714 dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T)); 1715 return (CORENOTE_R_OK); 1716 1717 case NT_PRCRED: /* prcred_t <sys/procfs.h> */ 1718 state.ns_vcol = 20; 1719 state.ns_t2col = 34; 1720 state.ns_v2col = 44; 1721 dump_prcred(&state, MSG_ORIG(MSG_CNOTE_DESC_PRCRED_T)); 1722 return (CORENOTE_R_OK); 1723 1724 case NT_UTSNAME: /* struct utsname <sys/utsname.h> */ 1725 state.ns_vcol = 18; 1726 dump_utsname(&state, MSG_ORIG(MSG_CNOTE_DESC_STRUCT_UTSNAME)); 1727 return (CORENOTE_R_OK); 1728 1729 case NT_LWPSTATUS: /* lwpstatus_t <sys/procfs.h> */ 1730 state.ns_vcol = 24; 1731 state.ns_t2col = 44; 1732 state.ns_v2col = 54; 1733 dump_lwpstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSTATUS_T)); 1734 return (CORENOTE_R_OK); 1735 1736 case NT_LWPSINFO: /* lwpsinfo_t <sys/procfs.h> */ 1737 state.ns_vcol = 22; 1738 state.ns_t2col = 42; 1739 state.ns_v2col = 54; 1740 dump_lwpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSINFO_T)); 1741 return (CORENOTE_R_OK); 1742 1743 case NT_PRPRIV: /* prpriv_t <sys/procfs.h> */ 1744 state.ns_vcol = 21; 1745 state.ns_t2col = 34; 1746 state.ns_v2col = 38; 1747 dump_prpriv(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPRIV_T)); 1748 return (CORENOTE_R_OK); 1749 1750 case NT_PRPRIVINFO: /* priv_impl_info_t <sys/priv.h> */ 1751 state.ns_vcol = 29; 1752 state.ns_t2col = 41; 1753 state.ns_v2col = 56; 1754 dump_priv_impl_info(&state, 1755 MSG_ORIG(MSG_CNOTE_DESC_PRIV_IMPL_INFO_T)); 1756 return (CORENOTE_R_OK); 1757 1758 case NT_CONTENT: /* core_content_t <sys/corectl.h> */ 1759 if (sizeof (core_content_t) > descsz) 1760 return (CORENOTE_R_BADDATA); 1761 { 1762 static sl_field_t fdesc = { 0, 8, 0, 0 }; 1763 Conv_cnote_cc_content_buf_t conv_buf; 1764 core_content_t content; 1765 1766 state.ns_vcol = 8; 1767 indent_enter(&state, 1768 MSG_ORIG(MSG_CNOTE_DESC_CORE_CONTENT_T), 1769 &fdesc); 1770 content = extract_as_lword(&state, &fdesc); 1771 print_str(&state, MSG_ORIG(MSG_STR_EMPTY), 1772 conv_cnote_cc_content(content, 0, &conv_buf)); 1773 indent_exit(&state); 1774 } 1775 return (CORENOTE_R_OK); 1776 1777 case NT_ZONENAME: /* string from getzonenamebyid(3C) */ 1778 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); 1779 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz)); 1780 return (CORENOTE_R_OK); 1781 } 1782 1783 return (CORENOTE_R_BADTYPE); 1784 } 1785