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) 2018, Joyent, Inc. 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 case AT_SUN_FPSIZE: 502 case AT_SUN_FPTYPE: 503 num_fmt = SL_FMT_NUM_DEC; 504 break; 505 506 case AT_FLAGS: /* processor flags */ 507 w = extract_as_word(state, &layout->a_val); 508 vstr = conv_ehdr_flags(state->ns_mach, w, 509 0, &conv_buf.ehdr_flags); 510 break; 511 512 case AT_SUN_HWCAP: 513 w = extract_as_word(state, &layout->a_val); 514 vstr = conv_cap_val_hw1(w, state->ns_mach, 515 0, &conv_buf.hw1); 516 /* 517 * conv_cap_val_hw1() produces output like: 518 * 519 * 0xfff [ flg1 flg2 0xff] 520 * 521 * where the first hex value is the complete value, 522 * and the second is the leftover bits. We only 523 * want the part in brackets, and failing that, 524 * would rather fall back to formatting the full 525 * value ourselves. 526 */ 527 while ((*vstr != '\0') && (*vstr != '[')) 528 vstr++; 529 if (*vstr != '[') 530 vstr = NULL; 531 num_fmt = SL_FMT_NUM_HEX; 532 break; 533 case AT_SUN_HWCAP2: 534 w = extract_as_word(state, &layout->a_val); 535 vstr = conv_cap_val_hw2(w, state->ns_mach, 536 0, &conv_buf.hw2); 537 /* 538 * conv_cap_val_hw2() produces output like: 539 * 540 * 0xfff [ flg1 flg2 0xff] 541 * 542 * where the first hex value is the complete value, 543 * and the second is the leftover bits. We only 544 * want the part in brackets, and failing that, 545 * would rather fall back to formatting the full 546 * value ourselves. 547 */ 548 while ((*vstr != '\0') && (*vstr != '[')) 549 vstr++; 550 if (*vstr != '[') 551 vstr = NULL; 552 num_fmt = SL_FMT_NUM_HEX; 553 break; 554 555 556 557 case AT_SUN_AUXFLAGS: 558 w = extract_as_word(state, &layout->a_val); 559 vstr = conv_cnote_auxv_af(w, 0, &conv_buf.auxv_af); 560 num_fmt = SL_FMT_NUM_HEX; 561 break; 562 } 563 564 if (ndx == ndx_start) 565 (void) snprintf(index, sizeof (index), 566 MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(ndx)); 567 else 568 (void) snprintf(index, sizeof (index), 569 MSG_ORIG(MSG_FMT_INDEXRNG), 570 EC_WORD(ndx_start), EC_WORD(ndx)); 571 572 if (vstr == NULL) 573 vstr = fmt_num(state, &layout->a_val, num_fmt, buf); 574 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_AUXVLINE), INDENT, index, 575 state->ns_vcol - state->ns_indent, 576 conv_cnote_auxv_type(type, CONV_FMT_DECIMAL, 577 &conv_buf.inv), vstr); 578 579 state->ns_data += sizeof_auxv; 580 state->ns_len -= sizeof_auxv; 581 ndx++; 582 } 583 } 584 585 586 /* 587 * Output information from fltset_t structure. 588 */ 589 static void 590 dump_fltset(note_state_t *state, const char *title) 591 { 592 #define NELTS 4 593 594 const sl_fltset_layout_t *layout = state->ns_arch->fltset; 595 Conv_cnote_fltset_buf_t buf; 596 sl_field_t fdesc; 597 uint32_t mask[NELTS]; 598 int i, nelts; 599 600 if (!data_present(state, &layout->sizeof_struct)) 601 return; 602 603 fdesc = layout->word; 604 nelts = fdesc.slf_nelts; 605 if (nelts > NELTS) /* Type has grown? Show what we understand */ 606 nelts = NELTS; 607 for (i = 0; i < nelts; i++) { 608 mask[i] = extract_as_word(state, &fdesc); 609 fdesc.slf_offset += fdesc.slf_eltlen; 610 } 611 612 print_str(state, title, conv_cnote_fltset(mask, nelts, 0, &buf)); 613 614 #undef NELTS 615 } 616 617 618 /* 619 * Output information from sigset_t structure. 620 */ 621 static void 622 dump_sigset(note_state_t *state, const char *title) 623 { 624 #define NELTS 4 625 626 const sl_sigset_layout_t *layout = state->ns_arch->sigset; 627 Conv_cnote_sigset_buf_t buf; 628 sl_field_t fdesc; 629 uint32_t mask[NELTS]; 630 int i, nelts; 631 632 if (!data_present(state, &layout->sizeof_struct)) 633 return; 634 635 fdesc = layout->sigbits; 636 nelts = fdesc.slf_nelts; 637 if (nelts > NELTS) /* Type has grown? Show what we understand */ 638 nelts = NELTS; 639 for (i = 0; i < nelts; i++) { 640 mask[i] = extract_as_word(state, &fdesc); 641 fdesc.slf_offset += fdesc.slf_eltlen; 642 } 643 644 print_str(state, title, conv_cnote_sigset(mask, nelts, 0, &buf)); 645 646 #undef NELTS 647 } 648 649 650 /* 651 * Output information from sigaction structure. 652 */ 653 static void 654 dump_sigaction(note_state_t *state, const char *title) 655 { 656 const sl_sigaction_layout_t *layout = state->ns_arch->sigaction; 657 Conv_cnote_sa_flags_buf_t conv_buf; 658 Word w; 659 660 indent_enter(state, title, &layout->sa_flags); 661 662 if (data_present(state, &layout->sa_flags)) { 663 w = extract_as_word(state, &layout->sa_flags); 664 print_str(state, MSG_ORIG(MSG_CNOTE_T_SA_FLAGS), 665 conv_cnote_sa_flags(w, 0, &conv_buf)); 666 } 667 668 PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_SA_HANDLER), sa_hand, 669 MSG_ORIG(MSG_CNOTE_T_SA_SIGACTION), sa_sigact); 670 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_SA_MASK), sa_mask, dump_sigset); 671 672 indent_exit(state); 673 } 674 675 676 /* 677 * Output information from siginfo structure. 678 */ 679 static void 680 dump_siginfo(note_state_t *state, const char *title) 681 { 682 const sl_siginfo_layout_t *layout = state->ns_arch->siginfo; 683 Conv_inv_buf_t inv_buf; 684 Word w; 685 int v_si_code, v_si_signo; 686 687 if (!data_present(state, &layout->sizeof_struct)) 688 return; 689 690 indent_enter(state, title, &layout->f_si_signo); 691 692 v_si_signo = extract_as_sword(state, &layout->f_si_signo); 693 print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_SIGNO), 694 conv_cnote_signal(v_si_signo, CONV_FMT_DECIMAL, &inv_buf)); 695 696 w = extract_as_word(state, &layout->f_si_errno); 697 print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_ERRNO), 698 conv_cnote_errno(w, CONV_FMT_DECIMAL, &inv_buf)); 699 700 v_si_code = extract_as_sword(state, &layout->f_si_code); 701 print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_CODE), 702 conv_cnote_si_code(state->ns_mach, v_si_signo, v_si_code, 703 CONV_FMT_DECIMAL, &inv_buf)); 704 705 if ((v_si_signo == 0) || (v_si_code == SI_NOINFO)) { 706 indent_exit(state); 707 return; 708 } 709 710 /* User generated signals have (si_code <= 0) */ 711 if (v_si_code <= 0) { 712 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_PID), f_si_pid); 713 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_UID), f_si_uid); 714 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_CTID), f_si_ctid); 715 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_ZONEID), f_si_zoneid); 716 switch (v_si_code) { 717 case SI_QUEUE: 718 case SI_TIMER: 719 case SI_ASYNCIO: 720 case SI_MESGQ: 721 indent_enter(state, MSG_ORIG(MSG_CNOTE_T_SI_VALUE), 722 &layout->f_si_value_int); 723 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SIVAL_INT), 724 f_si_value_int); 725 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SIVAL_PTR), 726 f_si_value_ptr); 727 indent_exit(state); 728 break; 729 } 730 indent_exit(state); 731 return; 732 } 733 734 /* 735 * Remaining cases are kernel generated signals. Output any 736 * signal or code specific information. 737 */ 738 if (v_si_code == SI_RCTL) 739 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_SI_ENTITY), f_si_entity); 740 switch (v_si_signo) { 741 case SIGILL: 742 case SIGFPE: 743 case SIGSEGV: 744 case SIGBUS: 745 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SI_ADDR), f_si_addr); 746 break; 747 case SIGCHLD: 748 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_PID), f_si_pid); 749 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_STATUS), f_si_status); 750 break; 751 case SIGPOLL: 752 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_BAND), f_si_band); 753 break; 754 } 755 756 indent_exit(state); 757 } 758 759 760 /* 761 * Output information from stack_t structure. 762 */ 763 static void 764 dump_stack(note_state_t *state, const char *title) 765 { 766 const sl_stack_layout_t *layout = state->ns_arch->stack; 767 Conv_cnote_ss_flags_buf_t conv_buf; 768 Word w; 769 770 indent_enter(state, title, &layout->ss_size); 771 772 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_SS_SP), &layout->ss_sp, 773 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_SS_SIZE), &layout->ss_size, 774 SL_FMT_NUM_HEX); 775 776 if (data_present(state, &layout->ss_flags)) { 777 w = extract_as_word(state, &layout->ss_flags); 778 print_str(state, MSG_ORIG(MSG_CNOTE_T_SS_FLAGS), 779 conv_cnote_ss_flags(w, 0, &conv_buf)); 780 } 781 782 indent_exit(state); 783 } 784 785 786 /* 787 * Output information from sysset_t structure. 788 */ 789 static void 790 dump_sysset(note_state_t *state, const char *title) 791 { 792 #define NELTS 16 793 794 const sl_sysset_layout_t *layout = state->ns_arch->sysset; 795 Conv_cnote_sysset_buf_t buf; 796 sl_field_t fdesc; 797 uint32_t mask[NELTS]; 798 int i, nelts; 799 800 if (!data_present(state, &layout->sizeof_struct)) 801 return; 802 803 fdesc = layout->word; 804 nelts = fdesc.slf_nelts; 805 if (nelts > NELTS) /* Type has grown? Show what we understand */ 806 nelts = NELTS; 807 for (i = 0; i < nelts; i++) { 808 mask[i] = extract_as_word(state, &fdesc); 809 fdesc.slf_offset += fdesc.slf_eltlen; 810 } 811 812 print_str(state, title, conv_cnote_sysset(mask, nelts, 0, &buf)); 813 814 #undef NELTS 815 } 816 817 818 /* 819 * Output information from timestruc_t structure. 820 */ 821 static void 822 dump_timestruc(note_state_t *state, const char *title) 823 { 824 const sl_timestruc_layout_t *layout = state->ns_arch->timestruc; 825 826 indent_enter(state, title, &layout->tv_sec); 827 828 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_TV_SEC), tv_sec, 829 MSG_ORIG(MSG_CNOTE_T_TV_NSEC), tv_nsec); 830 831 indent_exit(state); 832 } 833 834 /* 835 * Output information from prsecflags_t structure. 836 */ 837 static void 838 dump_secflags(note_state_t *state, const char *title) 839 { 840 const sl_prsecflags_layout_t *layout = state->ns_arch->prsecflags; 841 Conv_secflags_buf_t inv; 842 Lword lw; 843 Word w; 844 845 indent_enter(state, title, &layout->pr_version); 846 847 w = extract_as_word(state, &layout->pr_version); 848 849 if (w != PRSECFLAGS_VERSION_1) { 850 PRINT_DEC(MSG_INTL(MSG_NOTE_BAD_SECFLAGS_VER), pr_version); 851 dump_hex_bytes(state->ns_data, state->ns_len, state->ns_indent, 852 4, 3); 853 } else { 854 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_VERSION), pr_version); 855 lw = extract_as_lword(state, &layout->pr_effective); 856 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_EFFECTIVE), 857 conv_prsecflags(lw, 0, &inv)); 858 859 lw = extract_as_lword(state, &layout->pr_inherit); 860 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_INHERIT), 861 conv_prsecflags(lw, 0, &inv)); 862 863 lw = extract_as_lword(state, &layout->pr_lower); 864 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_LOWER), 865 conv_prsecflags(lw, 0, &inv)); 866 867 lw = extract_as_lword(state, &layout->pr_upper); 868 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_UPPER), 869 conv_prsecflags(lw, 0, &inv)); 870 } 871 872 indent_exit(state); 873 } 874 875 /* 876 * Output information from utsname structure. 877 */ 878 static void 879 dump_utsname(note_state_t *state, const char *title) 880 { 881 const sl_utsname_layout_t *layout = state->ns_arch->utsname; 882 883 indent_enter(state, title, &layout->sysname); 884 885 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_SYSNAME), sysname); 886 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_NODENAME), nodename); 887 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_RELEASE), release); 888 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_VERSION), version); 889 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_MACHINE), machine); 890 891 indent_exit(state); 892 } 893 894 895 /* 896 * Dump register contents 897 */ 898 static void 899 dump_prgregset(note_state_t *state, const char *title) 900 { 901 sl_field_t fdesc1, fdesc2; 902 sl_fmtbuf_t buf1, buf2; 903 Conv_inv_buf_t inv_buf1, inv_buf2; 904 Word w; 905 906 fdesc1 = fdesc2 = state->ns_arch->prgregset->elt0; 907 indent_enter(state, title, &fdesc1); 908 909 for (w = 0; w < fdesc1.slf_nelts; ) { 910 if (w == (fdesc1.slf_nelts - 1)) { 911 /* One last register is left */ 912 if (!data_present(state, &fdesc1)) 913 break; 914 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), 915 INDENT, state->ns_vcol - state->ns_indent, 916 conv_cnote_pr_regname(state->ns_mach, w, 917 CONV_FMT_DECIMAL, &inv_buf1), 918 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1)); 919 fdesc1.slf_offset += fdesc1.slf_eltlen; 920 w++; 921 continue; 922 } 923 924 /* There are at least 2 more registers left. Show 2 up */ 925 fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; 926 if (!(data_present(state, &fdesc1) && 927 data_present(state, &fdesc2))) 928 break; 929 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 930 state->ns_vcol - state->ns_indent, 931 conv_cnote_pr_regname(state->ns_mach, w, 932 CONV_FMT_DECIMAL, &inv_buf1), 933 state->ns_t2col - state->ns_vcol, 934 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1), 935 state->ns_v2col - state->ns_t2col, 936 conv_cnote_pr_regname(state->ns_mach, w + 1, 937 CONV_FMT_DECIMAL, &inv_buf2), 938 fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2)); 939 fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; 940 w += 2; 941 } 942 943 indent_exit(state); 944 } 945 946 /* 947 * Output information from lwpstatus_t structure. 948 */ 949 static void 950 dump_lwpstatus(note_state_t *state, const char *title) 951 { 952 const sl_lwpstatus_layout_t *layout = state->ns_arch->lwpstatus; 953 Word w, w2; 954 int32_t i; 955 union { 956 Conv_inv_buf_t inv; 957 Conv_cnote_pr_flags_buf_t flags; 958 } conv_buf; 959 960 indent_enter(state, title, &layout->pr_flags); 961 962 if (data_present(state, &layout->pr_flags)) { 963 w = extract_as_word(state, &layout->pr_flags); 964 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), 965 conv_cnote_pr_flags(w, 0, &conv_buf.flags)); 966 } 967 968 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LWPID), pr_lwpid); 969 970 if (data_present(state, &layout->pr_why)) { 971 w = extract_as_word(state, &layout->pr_why); 972 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHY), 973 conv_cnote_pr_why(w, 0, &conv_buf.inv)); 974 975 if (data_present(state, &layout->pr_what)) { 976 w2 = extract_as_word(state, &layout->pr_what); 977 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHAT), 978 conv_cnote_pr_what(w, w2, 0, &conv_buf.inv)); 979 } 980 } 981 982 if (data_present(state, &layout->pr_cursig)) { 983 w = extract_as_word(state, &layout->pr_cursig); 984 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_CURSIG), 985 conv_cnote_signal(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 986 } 987 988 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_INFO), pr_info, dump_siginfo); 989 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPPEND), pr_lwppend, 990 dump_sigset); 991 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPHOLD), pr_lwphold, 992 dump_sigset); 993 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ACTION), pr_action, 994 dump_sigaction); 995 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ALTSTACK), pr_altstack, 996 dump_stack); 997 998 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_OLDCONTEXT), pr_oldcontext); 999 1000 if (data_present(state, &layout->pr_syscall)) { 1001 w = extract_as_word(state, &layout->pr_syscall); 1002 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1003 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1004 } 1005 1006 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSYSARG), pr_nsysarg); 1007 1008 if (data_present(state, &layout->pr_errno)) { 1009 w = extract_as_word(state, &layout->pr_errno); 1010 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_ERRNO), 1011 conv_cnote_errno(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1012 } 1013 1014 if (data_present(state, &layout->pr_nsysarg)) { 1015 w2 = extract_as_word(state, &layout->pr_nsysarg); 1016 print_array(state, &layout->pr_sysarg, SL_FMT_NUM_ZHEX, w2, 1, 1017 MSG_ORIG(MSG_CNOTE_T_PR_SYSARG)); 1018 } 1019 1020 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RVAL1), pr_rval1, 1021 MSG_ORIG(MSG_CNOTE_T_PR_RVAL2), pr_rval2); 1022 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1023 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TSTAMP), pr_tstamp, 1024 dump_timestruc); 1025 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); 1026 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); 1027 1028 if (data_present(state, &layout->pr_errpriv)) { 1029 i = extract_as_sword(state, &layout->pr_errpriv); 1030 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_ERRPRIV), 1031 conv_cnote_priv(i, CONV_FMT_DECIMAL, &conv_buf.inv)); 1032 } 1033 1034 PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_USTACK), pr_ustack, 1035 MSG_ORIG(MSG_CNOTE_T_PR_INSTR), pr_instr); 1036 1037 /* 1038 * In order to line up all the values in a single column, 1039 * we would have to set vcol to a very high value, which results 1040 * in ugly looking output that runs off column 80. So, we use 1041 * two levels of vcol, one for the contents so far, and a 1042 * higher one for the pr_reg sub-struct. 1043 */ 1044 state->ns_vcol += 3; 1045 state->ns_t2col += 3; 1046 state->ns_v2col += 2; 1047 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_REG), pr_reg, dump_prgregset); 1048 state->ns_vcol -= 3; 1049 state->ns_t2col -= 3; 1050 state->ns_v2col -= 2; 1051 1052 /* 1053 * The floating point register state is complex, and highly 1054 * platform dependent. For now, we simply display it as 1055 * a hex dump. This can be replaced if better information 1056 * is required. 1057 */ 1058 if (data_present(state, &layout->pr_fpreg)) { 1059 indent_enter(state, MSG_ORIG(MSG_CNOTE_T_PR_FPREG), 1060 &layout->pr_fpreg); 1061 dump_hex_bytes(layout->pr_fpreg.slf_offset + state->ns_data, 1062 layout->pr_fpreg.slf_eltlen, state->ns_indent, 4, 3); 1063 indent_exit(state); 1064 } 1065 1066 indent_exit(state); 1067 } 1068 1069 1070 /* 1071 * Output information from pstatus_t structure. 1072 */ 1073 static void 1074 dump_pstatus(note_state_t *state, const char *title) 1075 { 1076 const sl_pstatus_layout_t *layout = state->ns_arch->pstatus; 1077 Word w; 1078 union { 1079 Conv_inv_buf_t inv; 1080 Conv_cnote_pr_flags_buf_t flags; 1081 } conv_buf; 1082 1083 indent_enter(state, title, &layout->pr_flags); 1084 1085 if (data_present(state, &layout->pr_flags)) { 1086 w = extract_as_word(state, &layout->pr_flags); 1087 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), 1088 conv_cnote_pr_flags(w, 0, &conv_buf.flags)); 1089 } 1090 1091 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); 1092 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1093 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1094 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid, 1095 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1096 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid, 1097 MSG_ORIG(MSG_CNOTE_T_PR_AGENTID), pr_agentid); 1098 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGPEND), pr_sigpend, 1099 dump_sigset); 1100 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_BRKBASE), 1101 &layout->pr_brkbase, SL_FMT_NUM_ZHEX, 1102 MSG_ORIG(MSG_CNOTE_T_PR_BRKSIZE), 1103 &layout->pr_brksize, SL_FMT_NUM_HEX); 1104 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_STKBASE), 1105 &layout->pr_stkbase, SL_FMT_NUM_ZHEX, 1106 MSG_ORIG(MSG_CNOTE_T_PR_STKSIZE), 1107 &layout->pr_stksize, SL_FMT_NUM_HEX); 1108 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); 1109 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); 1110 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CUTIME), pr_cutime, 1111 dump_timestruc); 1112 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CSTIME), pr_cstime, 1113 dump_timestruc); 1114 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGTRACE), pr_sigtrace, 1115 dump_sigset); 1116 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_FLTTRACE), pr_flttrace, 1117 dump_fltset); 1118 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SYSENTRY), pr_sysentry, 1119 dump_sysset); 1120 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SYSEXIT), pr_sysexit, 1121 dump_sysset); 1122 1123 if (data_present(state, &layout->pr_dmodel)) { 1124 w = extract_as_word(state, &layout->pr_dmodel); 1125 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), 1126 conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); 1127 } 1128 1129 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid, 1130 MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid); 1131 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb, 1132 MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid); 1133 1134 /* 1135 * In order to line up all the values in a single column, 1136 * we would have to set vcol to a very high value, which results 1137 * in ugly looking output that runs off column 80. So, we use 1138 * two levels of vcol, one for the contents so far, and a 1139 * higher one for the pr_lwp sub-struct. 1140 */ 1141 state->ns_vcol += 5; 1142 state->ns_t2col += 5; 1143 state->ns_v2col += 5; 1144 1145 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpstatus); 1146 state->ns_vcol -= 5; 1147 state->ns_t2col -= 5; 1148 state->ns_v2col -= 5; 1149 1150 indent_exit(state); 1151 } 1152 1153 1154 /* 1155 * Output information from prstatus_t (<sys/old_procfs.h>) structure. 1156 */ 1157 static void 1158 dump_prstatus(note_state_t *state, const char *title) 1159 { 1160 const sl_prstatus_layout_t *layout = state->ns_arch->prstatus; 1161 Word w, w2; 1162 int i; 1163 union { 1164 Conv_inv_buf_t inv; 1165 Conv_cnote_old_pr_flags_buf_t flags; 1166 } conv_buf; 1167 1168 indent_enter(state, title, &layout->pr_flags); 1169 1170 if (data_present(state, &layout->pr_flags)) { 1171 w = extract_as_word(state, &layout->pr_flags); 1172 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), 1173 conv_cnote_old_pr_flags(w, 0, &conv_buf.flags)); 1174 } 1175 1176 if (data_present(state, &layout->pr_why)) { 1177 w = extract_as_word(state, &layout->pr_why); 1178 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHY), 1179 conv_cnote_pr_why(w, 0, &conv_buf.inv)); 1180 1181 1182 if (data_present(state, &layout->pr_what)) { 1183 w2 = extract_as_word(state, &layout->pr_what); 1184 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHAT), 1185 conv_cnote_pr_what(w, w2, 0, &conv_buf.inv)); 1186 } 1187 } 1188 1189 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_INFO), pr_info, dump_siginfo); 1190 1191 if (data_present(state, &layout->pr_cursig)) { 1192 w = extract_as_word(state, &layout->pr_cursig); 1193 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_CURSIG), 1194 conv_cnote_signal(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1195 } 1196 1197 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); 1198 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGPEND), pr_sigpend, 1199 dump_sigset); 1200 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGHOLD), pr_sighold, 1201 dump_sigset); 1202 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ALTSTACK), pr_altstack, 1203 dump_stack); 1204 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ACTION), pr_action, 1205 dump_sigaction); 1206 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1207 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1208 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp, 1209 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1210 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); 1211 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); 1212 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CUTIME), pr_cutime, 1213 dump_timestruc); 1214 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CSTIME), pr_cstime, 1215 dump_timestruc); 1216 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1217 1218 if (data_present(state, &layout->pr_syscall)) { 1219 w = extract_as_word(state, &layout->pr_syscall); 1220 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1221 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1222 } 1223 1224 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSYSARG), pr_nsysarg); 1225 1226 if (data_present(state, &layout->pr_nsysarg)) { 1227 w2 = extract_as_word(state, &layout->pr_nsysarg); 1228 print_array(state, &layout->pr_sysarg, SL_FMT_NUM_ZHEX, w2, 1, 1229 MSG_ORIG(MSG_CNOTE_T_PR_SYSARG)); 1230 } 1231 1232 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_WHO), pr_who); 1233 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPPEND), pr_sigpend, 1234 dump_sigset); 1235 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_OLDCONTEXT), pr_oldcontext); 1236 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_BRKBASE), 1237 &layout->pr_brkbase, SL_FMT_NUM_ZHEX, 1238 MSG_ORIG(MSG_CNOTE_T_PR_BRKSIZE), 1239 &layout->pr_brksize, SL_FMT_NUM_HEX); 1240 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_STKBASE), 1241 &layout->pr_stkbase, SL_FMT_NUM_ZHEX, 1242 MSG_ORIG(MSG_CNOTE_T_PR_STKSIZE), 1243 &layout->pr_stksize, SL_FMT_NUM_HEX); 1244 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_PROCESSOR), pr_processor); 1245 1246 if (data_present(state, &layout->pr_bind)) { 1247 i = extract_as_sword(state, &layout->pr_bind); 1248 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BIND), 1249 conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv)); 1250 } 1251 1252 PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_INSTR), pr_instr); 1253 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_REG), pr_reg, dump_prgregset); 1254 1255 indent_exit(state); 1256 } 1257 1258 1259 /* 1260 * Print percent from 16-bit binary fraction [0 .. 1] 1261 * Round up .01 to .1 to indicate some small percentage (the 0x7000 below). 1262 * 1263 * Note: This routine was copied from ps(1) and then modified. 1264 */ 1265 static const char * 1266 prtpct_value(note_state_t *state, const sl_field_t *fdesc, 1267 sl_fmtbuf_t buf) 1268 { 1269 uint_t value; /* need 32 bits to compute with */ 1270 1271 value = extract_as_word(state, fdesc); 1272 value = ((value * 1000) + 0x7000) >> 15; /* [0 .. 1000] */ 1273 if (value >= 1000) 1274 value = 999; 1275 1276 (void) snprintf(buf, sizeof (sl_fmtbuf_t), 1277 MSG_ORIG(MSG_CNOTE_FMT_PRTPCT), value / 10, value % 10); 1278 1279 return (buf); 1280 } 1281 1282 1283 1284 /* 1285 * Version of prtpct() used for a 2-up display of two adjacent percentages. 1286 */ 1287 static void 1288 prtpct_2up(note_state_t *state, const sl_field_t *fdesc1, 1289 const char *title1, const sl_field_t *fdesc2, const char *title2) 1290 { 1291 sl_fmtbuf_t buf1, buf2; 1292 1293 if (!(data_present(state, fdesc1) && 1294 data_present(state, fdesc2))) 1295 return; 1296 1297 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1298 state->ns_vcol - state->ns_indent, title1, 1299 state->ns_t2col - state->ns_vcol, 1300 prtpct_value(state, fdesc1, buf1), 1301 state->ns_v2col - state->ns_t2col, title2, 1302 prtpct_value(state, fdesc2, buf2)); 1303 } 1304 1305 1306 /* 1307 * The psinfo_t and prpsinfo_t structs have pr_state and pr_sname 1308 * fields that we wish to print in a 2up format. The pr_state is 1309 * an integer, while pr_sname is a single character. 1310 */ 1311 static void 1312 print_state_sname_2up(note_state_t *state, 1313 const sl_field_t *state_fdesc, 1314 const sl_field_t *sname_fdesc) 1315 { 1316 sl_fmtbuf_t buf1, buf2; 1317 int sname; 1318 1319 /* 1320 * If the field slf_offset and extent fall past the end of the 1321 * available data, then return without doing anything. That note 1322 * is from an older core file that doesn't have all the fields 1323 * that we know about. 1324 */ 1325 if (!(data_present(state, state_fdesc) && 1326 data_present(state, sname_fdesc))) 1327 return; 1328 1329 sname = extract_as_sword(state, sname_fdesc); 1330 buf2[0] = sname; 1331 buf2[1] = '\0'; 1332 1333 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1334 state->ns_vcol - state->ns_indent, MSG_ORIG(MSG_CNOTE_T_PR_STATE), 1335 state->ns_t2col - state->ns_vcol, 1336 fmt_num(state, state_fdesc, SL_FMT_NUM_DEC, buf1), 1337 state->ns_v2col - state->ns_t2col, MSG_ORIG(MSG_CNOTE_T_PR_SNAME), 1338 buf2); 1339 } 1340 1341 /* 1342 * Output information from lwpsinfo_t structure. 1343 */ 1344 static void 1345 dump_lwpsinfo(note_state_t *state, const char *title) 1346 { 1347 const sl_lwpsinfo_layout_t *layout = state->ns_arch->lwpsinfo; 1348 Word w; 1349 int32_t i; 1350 union { 1351 Conv_cnote_proc_flag_buf_t proc_flag; 1352 Conv_inv_buf_t inv; 1353 } conv_buf; 1354 1355 indent_enter(state, title, &layout->pr_flag); 1356 1357 if (data_present(state, &layout->pr_flag)) { 1358 w = extract_as_word(state, &layout->pr_flag); 1359 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1360 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1361 } 1362 1363 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_LWPID), &layout->pr_lwpid, 1364 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, 1365 SL_FMT_NUM_ZHEX); 1366 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan); 1367 1368 if (data_present(state, &layout->pr_stype)) { 1369 w = extract_as_word(state, &layout->pr_stype); 1370 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_STYPE), 1371 conv_cnote_pr_stype(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1372 } 1373 1374 print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname); 1375 1376 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice); 1377 1378 if (data_present(state, &layout->pr_syscall)) { 1379 w = extract_as_word(state, &layout->pr_syscall); 1380 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1381 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1382 } 1383 1384 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri, 1385 MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu); 1386 1387 if (data_present(state, &layout->pr_pri) && 1388 data_present(state, &layout->pr_pctcpu)) { 1389 sl_fmtbuf_t buf1, buf2; 1390 1391 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1392 state->ns_vcol - state->ns_indent, 1393 MSG_ORIG(MSG_CNOTE_T_PR_PRI), 1394 state->ns_t2col - state->ns_vcol, 1395 fmt_num(state, &layout->pr_pri, SL_FMT_NUM_DEC, buf1), 1396 state->ns_v2col - state->ns_t2col, 1397 MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1398 prtpct_value(state, &layout->pr_pctcpu, buf2)); 1399 } 1400 1401 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1402 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1403 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1404 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_NAME), pr_name); 1405 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ONPRO), pr_onpro, 1406 MSG_ORIG(MSG_CNOTE_T_PR_BINDPRO), pr_bindpro); 1407 1408 if (data_present(state, &layout->pr_bindpset)) { 1409 i = extract_as_sword(state, &layout->pr_bindpset); 1410 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BINDPSET), 1411 conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv)); 1412 } 1413 1414 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LGRP), pr_lgrp); 1415 1416 indent_exit(state); 1417 } 1418 1419 1420 /* 1421 * Output information from psinfo_t structure. 1422 */ 1423 static void 1424 dump_psinfo(note_state_t *state, const char *title) 1425 { 1426 const sl_psinfo_layout_t *layout = state->ns_arch->psinfo; 1427 Word w; 1428 union { 1429 Conv_cnote_proc_flag_buf_t proc_flag; 1430 Conv_inv_buf_t inv; 1431 } conv_buf; 1432 1433 indent_enter(state, title, &layout->pr_flag); 1434 1435 if (data_present(state, &layout->pr_flag)) { 1436 w = extract_as_word(state, &layout->pr_flag); 1437 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1438 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1439 } 1440 1441 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); 1442 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1443 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1444 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid, 1445 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1446 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, 1447 MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid); 1448 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid, 1449 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 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_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), 1454 &layout->pr_rssize, SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_TTYDEV), 1455 &layout->pr_ttydev, SL_FMT_NUM_DEC); 1456 prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1457 &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM)); 1458 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1459 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1460 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc); 1461 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname); 1462 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs); 1463 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat, 1464 SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc, 1465 SL_FMT_NUM_DEC); 1466 PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ARGV), pr_argv, 1467 MSG_ORIG(MSG_CNOTE_T_PR_ENVP), pr_envp); 1468 1469 if (data_present(state, &layout->pr_dmodel)) { 1470 w = extract_as_word(state, &layout->pr_dmodel); 1471 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), 1472 conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); 1473 } 1474 1475 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid, 1476 MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid); 1477 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb, 1478 MSG_ORIG(MSG_CNOTE_T_PR_POOLID), pr_poolid); 1479 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid, 1480 MSG_ORIG(MSG_CNOTE_T_PR_CONTRACT), pr_contract); 1481 1482 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpsinfo); 1483 1484 indent_exit(state); 1485 } 1486 1487 /* 1488 * Output information from prpsinfo_t structure. 1489 */ 1490 static void 1491 dump_prpsinfo(note_state_t *state, const char *title) 1492 { 1493 const sl_prpsinfo_layout_t *layout = state->ns_arch->prpsinfo; 1494 Word w; 1495 union { 1496 Conv_cnote_proc_flag_buf_t proc_flag; 1497 Conv_inv_buf_t inv; 1498 } conv_buf; 1499 1500 indent_enter(state, title, &layout->pr_state); 1501 1502 print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname); 1503 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZOMB), pr_zomb, 1504 MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice); 1505 1506 if (data_present(state, &layout->pr_flag)) { 1507 w = extract_as_word(state, &layout->pr_flag); 1508 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1509 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1510 } 1511 1512 1513 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, 1514 MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid); 1515 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1516 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1517 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp, 1518 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1519 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, 1520 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size, 1521 SL_FMT_NUM_HEX); 1522 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), pr_rssize, 1523 MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan); 1524 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1525 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1526 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PRI), pr_pri, 1527 MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri); 1528 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu); 1529 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OTTYDEV), pr_ottydev, 1530 MSG_ORIG(MSG_CNOTE_T_PR_LTTYDEV), pr_lttydev); 1531 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1532 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname); 1533 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs); 1534 1535 if (data_present(state, &layout->pr_syscall)) { 1536 w = extract_as_word(state, &layout->pr_syscall); 1537 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1538 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1539 } 1540 1541 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc); 1542 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_BYSIZE), pr_bysize, 1543 MSG_ORIG(MSG_CNOTE_T_PR_BYRSSIZE), pr_byrssize); 1544 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc, 1545 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ARGV), &layout->pr_argv, 1546 SL_FMT_NUM_ZHEX); 1547 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ENVP), &layout->pr_envp, 1548 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat, 1549 SL_FMT_NUM_HEX); 1550 prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1551 &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM)); 1552 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid, 1553 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 1554 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid); 1555 1556 if (data_present(state, &layout->pr_dmodel)) { 1557 w = extract_as_word(state, &layout->pr_dmodel); 1558 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), 1559 conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); 1560 } 1561 1562 indent_exit(state); 1563 } 1564 1565 1566 /* 1567 * Output information from prcred_t structure. 1568 */ 1569 static void 1570 dump_prcred(note_state_t *state, const char *title) 1571 { 1572 const sl_prcred_layout_t *layout = state->ns_arch->prcred; 1573 Word ngroups; 1574 1575 indent_enter(state, title, &layout->pr_euid); 1576 1577 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid, 1578 MSG_ORIG(MSG_CNOTE_T_PR_RUID), pr_ruid); 1579 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_SUID), pr_suid, 1580 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 1581 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RGID), pr_rgid, 1582 MSG_ORIG(MSG_CNOTE_T_PR_SGID), pr_sgid); 1583 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NGROUPS), pr_ngroups); 1584 1585 if (data_present(state, &layout->pr_ngroups)) { 1586 ngroups = extract_as_word(state, &layout->pr_ngroups); 1587 print_array(state, &layout->pr_groups, SL_FMT_NUM_DEC, ngroups, 1588 0, MSG_ORIG(MSG_CNOTE_T_PR_GROUPS)); 1589 } 1590 1591 indent_exit(state); 1592 } 1593 1594 1595 /* 1596 * Output information from prpriv_t structure. 1597 */ 1598 static void 1599 dump_prpriv(note_state_t *state, const char *title) 1600 { 1601 const sl_prpriv_layout_t *layout = state->ns_arch->prpriv; 1602 Word nsets; 1603 1604 indent_enter(state, title, &layout->pr_nsets); 1605 1606 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSETS), pr_nsets); 1607 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_SETSIZE), pr_setsize); 1608 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_INFOSIZE), pr_infosize); 1609 1610 if (data_present(state, &layout->pr_nsets)) { 1611 nsets = extract_as_word(state, &layout->pr_nsets); 1612 print_array(state, &layout->pr_sets, SL_FMT_NUM_ZHEX, nsets, 1613 0, MSG_ORIG(MSG_CNOTE_T_PR_SETS)); 1614 } 1615 1616 indent_exit(state); 1617 } 1618 1619 static void 1620 dump_prfdinfo(note_state_t *state, const char *title) 1621 { 1622 const sl_prfdinfo_layout_t *layout = state->ns_arch->prfdinfo; 1623 char buf[1024]; 1624 uint32_t fileflags, mode; 1625 1626 indent_enter(state, title, &layout->pr_fd); 1627 1628 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_FD), pr_fd); 1629 mode = extract_as_word(state, &layout->pr_mode); 1630 1631 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_MODE), 1632 conv_cnote_filemode(mode, 0, buf, sizeof (buf))); 1633 1634 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, 1635 MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid); 1636 1637 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_MAJOR), pr_major, 1638 MSG_ORIG(MSG_CNOTE_T_PR_MINOR), pr_minor); 1639 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RMAJOR), pr_rmajor, 1640 MSG_ORIG(MSG_CNOTE_T_PR_RMINOR), pr_rminor); 1641 1642 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_INO), pr_ino); 1643 1644 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_SIZE), pr_size, 1645 MSG_ORIG(MSG_CNOTE_T_PR_OFFSET), pr_offset); 1646 1647 fileflags = extract_as_word(state, &layout->pr_fileflags); 1648 1649 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FILEFLAGS), 1650 conv_cnote_fileflags(fileflags, 0, buf, sizeof (buf))); 1651 1652 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_FDFLAGS), pr_fdflags); 1653 1654 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PATH), pr_path); 1655 1656 indent_exit(state); 1657 } 1658 1659 /* 1660 * Output information from priv_impl_info_t structure. 1661 */ 1662 static void 1663 dump_priv_impl_info(note_state_t *state, const char *title) 1664 { 1665 const sl_priv_impl_info_layout_t *layout; 1666 1667 layout = state->ns_arch->priv_impl_info; 1668 indent_enter(state, title, &layout->priv_headersize); 1669 1670 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PRIV_HEADERSIZE), priv_headersize, 1671 MSG_ORIG(MSG_CNOTE_T_PRIV_FLAGS), priv_flags); 1672 1673 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_NSETS), 1674 &layout->priv_nsets, SL_FMT_NUM_DEC, 1675 MSG_ORIG(MSG_CNOTE_T_PRIV_SETSIZE), &layout->priv_setsize, 1676 SL_FMT_NUM_HEX); 1677 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_MAX), &layout->priv_max, 1678 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PRIV_INFOSIZE), 1679 &layout->priv_infosize, SL_FMT_NUM_HEX); 1680 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PRIV_GLOBALINFOSIZE), 1681 priv_globalinfosize); 1682 1683 indent_exit(state); 1684 } 1685 1686 1687 /* 1688 * Dump information from an asrset_t array. This data 1689 * structure is specific to sparcv9, and does not appear 1690 * on any other platform. 1691 * 1692 * asrset_t is a simple array, defined in <sys/regset.h> as 1693 * typedef int64_t asrset_t[16]; %asr16 - > %asr31 1694 * 1695 * As such, we do not make use of the struct_layout facilities 1696 * for this routine. 1697 */ 1698 static void 1699 dump_asrset(note_state_t *state, const char *title) 1700 { 1701 static const sl_field_t ftemplate = { 0, sizeof (int64_t), 16, 0 }; 1702 sl_field_t fdesc1, fdesc2; 1703 sl_fmtbuf_t buf1, buf2; 1704 char index1[MAXNDXSIZE * 2], index2[MAXNDXSIZE * 2]; 1705 Word w, nelts; 1706 1707 fdesc1 = fdesc2 = ftemplate; 1708 1709 /* We expect 16 values, but will print whatever is actually there */ 1710 nelts = state->ns_len / ftemplate.slf_eltlen; 1711 if (nelts == 0) 1712 return; 1713 1714 indent_enter(state, title, &fdesc1); 1715 1716 for (w = 0; w < nelts; ) { 1717 (void) snprintf(index1, sizeof (index1), 1718 MSG_ORIG(MSG_FMT_ASRINDEX), w + 16); 1719 1720 if (w == (nelts - 1)) { 1721 /* One last register is left */ 1722 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), 1723 INDENT, state->ns_vcol - state->ns_indent, index1, 1724 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1)); 1725 fdesc1.slf_offset += fdesc1.slf_eltlen; 1726 w++; 1727 continue; 1728 } 1729 1730 /* There are at least 2 more registers left. Show 2 up */ 1731 (void) snprintf(index2, sizeof (index2), 1732 MSG_ORIG(MSG_FMT_ASRINDEX), w + 17); 1733 1734 fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; 1735 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1736 state->ns_vcol - state->ns_indent, index1, 1737 state->ns_t2col - state->ns_vcol, 1738 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1), 1739 state->ns_v2col - state->ns_t2col, index2, 1740 fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2)); 1741 fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; 1742 w += 2; 1743 } 1744 1745 indent_exit(state); 1746 } 1747 1748 corenote_ret_t 1749 corenote(Half mach, int do_swap, Word type, 1750 const char *desc, Word descsz) 1751 { 1752 note_state_t state; 1753 1754 /* 1755 * Get the per-architecture layout definition 1756 */ 1757 state.ns_mach = mach; 1758 state.ns_arch = sl_mach(state.ns_mach); 1759 if (sl_mach(state.ns_mach) == NULL) 1760 return (CORENOTE_R_BADARCH); 1761 1762 state.ns_swap = do_swap; 1763 state.ns_indent = 4; 1764 state.ns_t2col = state.ns_v2col = 0; 1765 state.ns_data = desc; 1766 state.ns_len = descsz; 1767 1768 switch (type) { 1769 case NT_PRSTATUS: /* prstatus_t <sys/old_procfs.h> */ 1770 state.ns_vcol = 26; 1771 state.ns_t2col = 46; 1772 state.ns_v2col = 60; 1773 dump_prstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSTATUS_T)); 1774 return (CORENOTE_R_OK); 1775 1776 case NT_PRFPREG: /* prfpregset_t <sys/procfs_isa.h> */ 1777 return (CORENOTE_R_OK_DUMP); 1778 1779 case NT_PRPSINFO: /* prpsinfo_t <sys/old_procfs.h> */ 1780 state.ns_vcol = 20; 1781 state.ns_t2col = 41; 1782 state.ns_v2col = 54; 1783 dump_prpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPSINFO_T)); 1784 return (CORENOTE_R_OK); 1785 1786 case NT_PRXREG: /* prxregset_t <sys/procfs_isa.h> */ 1787 return (CORENOTE_R_OK_DUMP); 1788 1789 case NT_PLATFORM: /* string from sysinfo(SI_PLATFORM) */ 1790 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); 1791 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz)); 1792 return (CORENOTE_R_OK); 1793 1794 case NT_AUXV: /* auxv_t array <sys/auxv.h> */ 1795 state.ns_vcol = 18; 1796 dump_auxv(&state, MSG_ORIG(MSG_CNOTE_DESC_AUXV_T)); 1797 return (CORENOTE_R_OK); 1798 1799 case NT_GWINDOWS: /* gwindows_t SPARC only */ 1800 return (CORENOTE_R_OK_DUMP); 1801 1802 case NT_ASRS: /* asrset_t <sys/regset> sparcv9 only */ 1803 state.ns_vcol = 18; 1804 state.ns_t2col = 38; 1805 state.ns_v2col = 46; 1806 dump_asrset(&state, MSG_ORIG(MSG_CNOTE_DESC_ASRSET_T)); 1807 return (CORENOTE_R_OK); 1808 1809 case NT_LDT: /* ssd array <sys/sysi86.h> IA32 only */ 1810 return (CORENOTE_R_OK_DUMP); 1811 1812 case NT_PSTATUS: /* pstatus_t <sys/procfs.h> */ 1813 state.ns_vcol = 22; 1814 state.ns_t2col = 42; 1815 state.ns_v2col = 54; 1816 dump_pstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PSTATUS_T)); 1817 return (CORENOTE_R_OK); 1818 1819 case NT_PSINFO: /* psinfo_t <sys/procfs.h> */ 1820 state.ns_vcol = 25; 1821 state.ns_t2col = 45; 1822 state.ns_v2col = 58; 1823 dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T)); 1824 return (CORENOTE_R_OK); 1825 1826 case NT_PRCRED: /* prcred_t <sys/procfs.h> */ 1827 state.ns_vcol = 20; 1828 state.ns_t2col = 34; 1829 state.ns_v2col = 44; 1830 dump_prcred(&state, MSG_ORIG(MSG_CNOTE_DESC_PRCRED_T)); 1831 return (CORENOTE_R_OK); 1832 1833 case NT_UTSNAME: /* struct utsname <sys/utsname.h> */ 1834 state.ns_vcol = 18; 1835 dump_utsname(&state, MSG_ORIG(MSG_CNOTE_DESC_STRUCT_UTSNAME)); 1836 return (CORENOTE_R_OK); 1837 1838 case NT_LWPSTATUS: /* lwpstatus_t <sys/procfs.h> */ 1839 state.ns_vcol = 24; 1840 state.ns_t2col = 44; 1841 state.ns_v2col = 54; 1842 dump_lwpstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSTATUS_T)); 1843 return (CORENOTE_R_OK); 1844 1845 case NT_LWPSINFO: /* lwpsinfo_t <sys/procfs.h> */ 1846 state.ns_vcol = 22; 1847 state.ns_t2col = 42; 1848 state.ns_v2col = 54; 1849 dump_lwpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSINFO_T)); 1850 return (CORENOTE_R_OK); 1851 1852 case NT_PRPRIV: /* prpriv_t <sys/procfs.h> */ 1853 state.ns_vcol = 21; 1854 state.ns_t2col = 34; 1855 state.ns_v2col = 38; 1856 dump_prpriv(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPRIV_T)); 1857 return (CORENOTE_R_OK); 1858 1859 case NT_PRPRIVINFO: /* priv_impl_info_t <sys/priv.h> */ 1860 state.ns_vcol = 29; 1861 state.ns_t2col = 41; 1862 state.ns_v2col = 56; 1863 dump_priv_impl_info(&state, 1864 MSG_ORIG(MSG_CNOTE_DESC_PRIV_IMPL_INFO_T)); 1865 return (CORENOTE_R_OK); 1866 1867 case NT_CONTENT: /* core_content_t <sys/corectl.h> */ 1868 if (sizeof (core_content_t) > descsz) 1869 return (CORENOTE_R_BADDATA); 1870 { 1871 static sl_field_t fdesc = { 0, 8, 0, 0 }; 1872 Conv_cnote_cc_content_buf_t conv_buf; 1873 core_content_t content; 1874 1875 state.ns_vcol = 8; 1876 indent_enter(&state, 1877 MSG_ORIG(MSG_CNOTE_DESC_CORE_CONTENT_T), 1878 &fdesc); 1879 content = extract_as_lword(&state, &fdesc); 1880 print_str(&state, MSG_ORIG(MSG_STR_EMPTY), 1881 conv_cnote_cc_content(content, 0, &conv_buf)); 1882 indent_exit(&state); 1883 } 1884 return (CORENOTE_R_OK); 1885 1886 case NT_ZONENAME: /* string from getzonenamebyid(3C) */ 1887 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); 1888 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz)); 1889 return (CORENOTE_R_OK); 1890 1891 1892 case NT_FDINFO: 1893 state.ns_vcol = 22; 1894 state.ns_t2col = 41; 1895 state.ns_v2col = 54; 1896 dump_prfdinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRFDINFO_T)); 1897 return (CORENOTE_R_OK); 1898 1899 case NT_SPYMASTER: 1900 state.ns_vcol = 25; 1901 state.ns_t2col = 45; 1902 state.ns_v2col = 58; 1903 dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T)); 1904 return (CORENOTE_R_OK); 1905 1906 case NT_SECFLAGS: 1907 state.ns_vcol = 23; 1908 state.ns_t2col = 41; 1909 state.ns_v2col = 54; 1910 dump_secflags(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSECFLAGS_T)); 1911 return (CORENOTE_R_OK); 1912 } 1913 1914 return (CORENOTE_R_BADTYPE); 1915 }