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