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