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 static void 1260 dump_lwpname(note_state_t *state, const char *title) 1261 { 1262 const sl_prlwpname_layout_t *layout = state->ns_arch->prlwpname; 1263 1264 indent_enter(state, title, &layout->pr_lwpid); 1265 1266 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LWPID), pr_lwpid); 1267 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_LWPNAME), pr_lwpname); 1268 1269 indent_exit(state); 1270 } 1271 1272 1273 /* 1274 * Print percent from 16-bit binary fraction [0 .. 1] 1275 * Round up .01 to .1 to indicate some small percentage (the 0x7000 below). 1276 * 1277 * Note: This routine was copied from ps(1) and then modified. 1278 */ 1279 static const char * 1280 prtpct_value(note_state_t *state, const sl_field_t *fdesc, 1281 sl_fmtbuf_t buf) 1282 { 1283 uint_t value; /* need 32 bits to compute with */ 1284 1285 value = extract_as_word(state, fdesc); 1286 value = ((value * 1000) + 0x7000) >> 15; /* [0 .. 1000] */ 1287 if (value >= 1000) 1288 value = 999; 1289 1290 (void) snprintf(buf, sizeof (sl_fmtbuf_t), 1291 MSG_ORIG(MSG_CNOTE_FMT_PRTPCT), value / 10, value % 10); 1292 1293 return (buf); 1294 } 1295 1296 1297 1298 /* 1299 * Version of prtpct() used for a 2-up display of two adjacent percentages. 1300 */ 1301 static void 1302 prtpct_2up(note_state_t *state, const sl_field_t *fdesc1, 1303 const char *title1, const sl_field_t *fdesc2, const char *title2) 1304 { 1305 sl_fmtbuf_t buf1, buf2; 1306 1307 if (!(data_present(state, fdesc1) && 1308 data_present(state, fdesc2))) 1309 return; 1310 1311 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1312 state->ns_vcol - state->ns_indent, title1, 1313 state->ns_t2col - state->ns_vcol, 1314 prtpct_value(state, fdesc1, buf1), 1315 state->ns_v2col - state->ns_t2col, title2, 1316 prtpct_value(state, fdesc2, buf2)); 1317 } 1318 1319 1320 /* 1321 * The psinfo_t and prpsinfo_t structs have pr_state and pr_sname 1322 * fields that we wish to print in a 2up format. The pr_state is 1323 * an integer, while pr_sname is a single character. 1324 */ 1325 static void 1326 print_state_sname_2up(note_state_t *state, 1327 const sl_field_t *state_fdesc, 1328 const sl_field_t *sname_fdesc) 1329 { 1330 sl_fmtbuf_t buf1, buf2; 1331 int sname; 1332 1333 /* 1334 * If the field slf_offset and extent fall past the end of the 1335 * available data, then return without doing anything. That note 1336 * is from an older core file that doesn't have all the fields 1337 * that we know about. 1338 */ 1339 if (!(data_present(state, state_fdesc) && 1340 data_present(state, sname_fdesc))) 1341 return; 1342 1343 sname = extract_as_sword(state, sname_fdesc); 1344 buf2[0] = sname; 1345 buf2[1] = '\0'; 1346 1347 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1348 state->ns_vcol - state->ns_indent, MSG_ORIG(MSG_CNOTE_T_PR_STATE), 1349 state->ns_t2col - state->ns_vcol, 1350 fmt_num(state, state_fdesc, SL_FMT_NUM_DEC, buf1), 1351 state->ns_v2col - state->ns_t2col, MSG_ORIG(MSG_CNOTE_T_PR_SNAME), 1352 buf2); 1353 } 1354 1355 /* 1356 * Output information from lwpsinfo_t structure. 1357 */ 1358 static void 1359 dump_lwpsinfo(note_state_t *state, const char *title) 1360 { 1361 const sl_lwpsinfo_layout_t *layout = state->ns_arch->lwpsinfo; 1362 Word w; 1363 int32_t i; 1364 union { 1365 Conv_cnote_proc_flag_buf_t proc_flag; 1366 Conv_inv_buf_t inv; 1367 } conv_buf; 1368 1369 indent_enter(state, title, &layout->pr_flag); 1370 1371 if (data_present(state, &layout->pr_flag)) { 1372 w = extract_as_word(state, &layout->pr_flag); 1373 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1374 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1375 } 1376 1377 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_LWPID), &layout->pr_lwpid, 1378 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, 1379 SL_FMT_NUM_ZHEX); 1380 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan); 1381 1382 if (data_present(state, &layout->pr_stype)) { 1383 w = extract_as_word(state, &layout->pr_stype); 1384 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_STYPE), 1385 conv_cnote_pr_stype(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1386 } 1387 1388 print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname); 1389 1390 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice); 1391 1392 if (data_present(state, &layout->pr_syscall)) { 1393 w = extract_as_word(state, &layout->pr_syscall); 1394 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1395 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1396 } 1397 1398 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri, 1399 MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu); 1400 1401 if (data_present(state, &layout->pr_pri) && 1402 data_present(state, &layout->pr_pctcpu)) { 1403 sl_fmtbuf_t buf1, buf2; 1404 1405 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1406 state->ns_vcol - state->ns_indent, 1407 MSG_ORIG(MSG_CNOTE_T_PR_PRI), 1408 state->ns_t2col - state->ns_vcol, 1409 fmt_num(state, &layout->pr_pri, SL_FMT_NUM_DEC, buf1), 1410 state->ns_v2col - state->ns_t2col, 1411 MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1412 prtpct_value(state, &layout->pr_pctcpu, buf2)); 1413 } 1414 1415 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1416 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1417 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1418 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_NAME), pr_name); 1419 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ONPRO), pr_onpro, 1420 MSG_ORIG(MSG_CNOTE_T_PR_BINDPRO), pr_bindpro); 1421 1422 if (data_present(state, &layout->pr_bindpset)) { 1423 i = extract_as_sword(state, &layout->pr_bindpset); 1424 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BINDPSET), 1425 conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv)); 1426 } 1427 1428 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LGRP), pr_lgrp); 1429 1430 indent_exit(state); 1431 } 1432 1433 1434 /* 1435 * Output information from psinfo_t structure. 1436 */ 1437 static void 1438 dump_psinfo(note_state_t *state, const char *title) 1439 { 1440 const sl_psinfo_layout_t *layout = state->ns_arch->psinfo; 1441 Word w; 1442 union { 1443 Conv_cnote_proc_flag_buf_t proc_flag; 1444 Conv_inv_buf_t inv; 1445 } conv_buf; 1446 1447 indent_enter(state, title, &layout->pr_flag); 1448 1449 if (data_present(state, &layout->pr_flag)) { 1450 w = extract_as_word(state, &layout->pr_flag); 1451 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1452 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1453 } 1454 1455 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); 1456 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1457 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1458 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid, 1459 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1460 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, 1461 MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid); 1462 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid, 1463 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 1464 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, 1465 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size, 1466 SL_FMT_NUM_HEX); 1467 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), 1468 &layout->pr_rssize, SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_TTYDEV), 1469 &layout->pr_ttydev, SL_FMT_NUM_DEC); 1470 prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1471 &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM)); 1472 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1473 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1474 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc); 1475 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname); 1476 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs); 1477 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat, 1478 SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc, 1479 SL_FMT_NUM_DEC); 1480 PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ARGV), pr_argv, 1481 MSG_ORIG(MSG_CNOTE_T_PR_ENVP), pr_envp); 1482 1483 if (data_present(state, &layout->pr_dmodel)) { 1484 w = extract_as_word(state, &layout->pr_dmodel); 1485 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), 1486 conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); 1487 } 1488 1489 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid, 1490 MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid); 1491 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb, 1492 MSG_ORIG(MSG_CNOTE_T_PR_POOLID), pr_poolid); 1493 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid, 1494 MSG_ORIG(MSG_CNOTE_T_PR_CONTRACT), pr_contract); 1495 1496 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpsinfo); 1497 1498 indent_exit(state); 1499 } 1500 1501 /* 1502 * Output information from prpsinfo_t structure. 1503 */ 1504 static void 1505 dump_prpsinfo(note_state_t *state, const char *title) 1506 { 1507 const sl_prpsinfo_layout_t *layout = state->ns_arch->prpsinfo; 1508 Word w; 1509 union { 1510 Conv_cnote_proc_flag_buf_t proc_flag; 1511 Conv_inv_buf_t inv; 1512 } conv_buf; 1513 1514 indent_enter(state, title, &layout->pr_state); 1515 1516 print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname); 1517 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZOMB), pr_zomb, 1518 MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice); 1519 1520 if (data_present(state, &layout->pr_flag)) { 1521 w = extract_as_word(state, &layout->pr_flag); 1522 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), 1523 conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); 1524 } 1525 1526 1527 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, 1528 MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid); 1529 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, 1530 MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); 1531 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp, 1532 MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); 1533 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, 1534 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size, 1535 SL_FMT_NUM_HEX); 1536 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), pr_rssize, 1537 MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan); 1538 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); 1539 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); 1540 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PRI), pr_pri, 1541 MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri); 1542 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu); 1543 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OTTYDEV), pr_ottydev, 1544 MSG_ORIG(MSG_CNOTE_T_PR_LTTYDEV), pr_lttydev); 1545 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); 1546 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname); 1547 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs); 1548 1549 if (data_present(state, &layout->pr_syscall)) { 1550 w = extract_as_word(state, &layout->pr_syscall); 1551 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), 1552 conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); 1553 } 1554 1555 PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc); 1556 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_BYSIZE), pr_bysize, 1557 MSG_ORIG(MSG_CNOTE_T_PR_BYRSSIZE), pr_byrssize); 1558 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc, 1559 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ARGV), &layout->pr_argv, 1560 SL_FMT_NUM_ZHEX); 1561 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ENVP), &layout->pr_envp, 1562 SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat, 1563 SL_FMT_NUM_HEX); 1564 prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), 1565 &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM)); 1566 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid, 1567 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 1568 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid); 1569 1570 if (data_present(state, &layout->pr_dmodel)) { 1571 w = extract_as_word(state, &layout->pr_dmodel); 1572 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), 1573 conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); 1574 } 1575 1576 indent_exit(state); 1577 } 1578 1579 1580 /* 1581 * Output information from prcred_t structure. 1582 */ 1583 static void 1584 dump_prcred(note_state_t *state, const char *title) 1585 { 1586 const sl_prcred_layout_t *layout = state->ns_arch->prcred; 1587 Word ngroups; 1588 1589 indent_enter(state, title, &layout->pr_euid); 1590 1591 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid, 1592 MSG_ORIG(MSG_CNOTE_T_PR_RUID), pr_ruid); 1593 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_SUID), pr_suid, 1594 MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); 1595 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RGID), pr_rgid, 1596 MSG_ORIG(MSG_CNOTE_T_PR_SGID), pr_sgid); 1597 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NGROUPS), pr_ngroups); 1598 1599 if (data_present(state, &layout->pr_ngroups)) { 1600 ngroups = extract_as_word(state, &layout->pr_ngroups); 1601 print_array(state, &layout->pr_groups, SL_FMT_NUM_DEC, ngroups, 1602 0, MSG_ORIG(MSG_CNOTE_T_PR_GROUPS)); 1603 } 1604 1605 indent_exit(state); 1606 } 1607 1608 1609 /* 1610 * Output information from prpriv_t structure. 1611 */ 1612 static void 1613 dump_prpriv(note_state_t *state, const char *title) 1614 { 1615 const sl_prpriv_layout_t *layout = state->ns_arch->prpriv; 1616 Word nsets; 1617 1618 indent_enter(state, title, &layout->pr_nsets); 1619 1620 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSETS), pr_nsets); 1621 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_SETSIZE), pr_setsize); 1622 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_INFOSIZE), pr_infosize); 1623 1624 if (data_present(state, &layout->pr_nsets)) { 1625 nsets = extract_as_word(state, &layout->pr_nsets); 1626 print_array(state, &layout->pr_sets, SL_FMT_NUM_ZHEX, nsets, 1627 0, MSG_ORIG(MSG_CNOTE_T_PR_SETS)); 1628 } 1629 1630 indent_exit(state); 1631 } 1632 1633 static void 1634 dump_prfdinfo(note_state_t *state, const char *title) 1635 { 1636 const sl_prfdinfo_layout_t *layout = state->ns_arch->prfdinfo; 1637 char buf[1024]; 1638 uint32_t fileflags, mode; 1639 1640 indent_enter(state, title, &layout->pr_fd); 1641 1642 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_FD), pr_fd); 1643 mode = extract_as_word(state, &layout->pr_mode); 1644 1645 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_MODE), 1646 conv_cnote_filemode(mode, 0, buf, sizeof (buf))); 1647 1648 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, 1649 MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid); 1650 1651 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_MAJOR), pr_major, 1652 MSG_ORIG(MSG_CNOTE_T_PR_MINOR), pr_minor); 1653 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RMAJOR), pr_rmajor, 1654 MSG_ORIG(MSG_CNOTE_T_PR_RMINOR), pr_rminor); 1655 1656 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_INO), pr_ino); 1657 1658 PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_SIZE), pr_size, 1659 MSG_ORIG(MSG_CNOTE_T_PR_OFFSET), pr_offset); 1660 1661 fileflags = extract_as_word(state, &layout->pr_fileflags); 1662 1663 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FILEFLAGS), 1664 conv_cnote_fileflags(fileflags, 0, buf, sizeof (buf))); 1665 1666 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_FDFLAGS), pr_fdflags); 1667 1668 PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PATH), pr_path); 1669 1670 indent_exit(state); 1671 } 1672 1673 /* 1674 * Output information from priv_impl_info_t structure. 1675 */ 1676 static void 1677 dump_priv_impl_info(note_state_t *state, const char *title) 1678 { 1679 const sl_priv_impl_info_layout_t *layout; 1680 1681 layout = state->ns_arch->priv_impl_info; 1682 indent_enter(state, title, &layout->priv_headersize); 1683 1684 PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PRIV_HEADERSIZE), priv_headersize, 1685 MSG_ORIG(MSG_CNOTE_T_PRIV_FLAGS), priv_flags); 1686 1687 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_NSETS), 1688 &layout->priv_nsets, SL_FMT_NUM_DEC, 1689 MSG_ORIG(MSG_CNOTE_T_PRIV_SETSIZE), &layout->priv_setsize, 1690 SL_FMT_NUM_HEX); 1691 print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_MAX), &layout->priv_max, 1692 SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PRIV_INFOSIZE), 1693 &layout->priv_infosize, SL_FMT_NUM_HEX); 1694 PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PRIV_GLOBALINFOSIZE), 1695 priv_globalinfosize); 1696 1697 indent_exit(state); 1698 } 1699 1700 1701 /* 1702 * Dump information from an asrset_t array. This data 1703 * structure is specific to sparcv9, and does not appear 1704 * on any other platform. 1705 * 1706 * asrset_t is a simple array, defined in <sys/regset.h> as 1707 * typedef int64_t asrset_t[16]; %asr16 - > %asr31 1708 * 1709 * As such, we do not make use of the struct_layout facilities 1710 * for this routine. 1711 */ 1712 static void 1713 dump_asrset(note_state_t *state, const char *title) 1714 { 1715 static const sl_field_t ftemplate = { 0, sizeof (int64_t), 16, 0 }; 1716 sl_field_t fdesc1, fdesc2; 1717 sl_fmtbuf_t buf1, buf2; 1718 char index1[MAXNDXSIZE * 2], index2[MAXNDXSIZE * 2]; 1719 Word w, nelts; 1720 1721 fdesc1 = fdesc2 = ftemplate; 1722 1723 /* We expect 16 values, but will print whatever is actually there */ 1724 nelts = state->ns_len / ftemplate.slf_eltlen; 1725 if (nelts == 0) 1726 return; 1727 1728 indent_enter(state, title, &fdesc1); 1729 1730 for (w = 0; w < nelts; ) { 1731 (void) snprintf(index1, sizeof (index1), 1732 MSG_ORIG(MSG_FMT_ASRINDEX), w + 16); 1733 1734 if (w == (nelts - 1)) { 1735 /* One last register is left */ 1736 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), 1737 INDENT, state->ns_vcol - state->ns_indent, index1, 1738 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1)); 1739 fdesc1.slf_offset += fdesc1.slf_eltlen; 1740 w++; 1741 continue; 1742 } 1743 1744 /* There are at least 2 more registers left. Show 2 up */ 1745 (void) snprintf(index2, sizeof (index2), 1746 MSG_ORIG(MSG_FMT_ASRINDEX), w + 17); 1747 1748 fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; 1749 dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, 1750 state->ns_vcol - state->ns_indent, index1, 1751 state->ns_t2col - state->ns_vcol, 1752 fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1), 1753 state->ns_v2col - state->ns_t2col, index2, 1754 fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2)); 1755 fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; 1756 w += 2; 1757 } 1758 1759 indent_exit(state); 1760 } 1761 1762 corenote_ret_t 1763 corenote(Half mach, int do_swap, Word type, 1764 const char *desc, Word descsz) 1765 { 1766 note_state_t state; 1767 1768 /* 1769 * Get the per-architecture layout definition 1770 */ 1771 state.ns_mach = mach; 1772 state.ns_arch = sl_mach(state.ns_mach); 1773 if (sl_mach(state.ns_mach) == NULL) 1774 return (CORENOTE_R_BADARCH); 1775 1776 state.ns_swap = do_swap; 1777 state.ns_indent = 4; 1778 state.ns_t2col = state.ns_v2col = 0; 1779 state.ns_data = desc; 1780 state.ns_len = descsz; 1781 1782 switch (type) { 1783 case NT_PRSTATUS: /* prstatus_t <sys/old_procfs.h> */ 1784 state.ns_vcol = 26; 1785 state.ns_t2col = 46; 1786 state.ns_v2col = 60; 1787 dump_prstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSTATUS_T)); 1788 return (CORENOTE_R_OK); 1789 1790 case NT_PRFPREG: /* prfpregset_t <sys/procfs_isa.h> */ 1791 return (CORENOTE_R_OK_DUMP); 1792 1793 case NT_PRPSINFO: /* prpsinfo_t <sys/old_procfs.h> */ 1794 state.ns_vcol = 20; 1795 state.ns_t2col = 41; 1796 state.ns_v2col = 54; 1797 dump_prpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPSINFO_T)); 1798 return (CORENOTE_R_OK); 1799 1800 case NT_PRXREG: /* prxregset_t <sys/procfs_isa.h> */ 1801 return (CORENOTE_R_OK_DUMP); 1802 1803 case NT_PLATFORM: /* string from sysinfo(SI_PLATFORM) */ 1804 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); 1805 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz)); 1806 return (CORENOTE_R_OK); 1807 1808 case NT_AUXV: /* auxv_t array <sys/auxv.h> */ 1809 state.ns_vcol = 18; 1810 dump_auxv(&state, MSG_ORIG(MSG_CNOTE_DESC_AUXV_T)); 1811 return (CORENOTE_R_OK); 1812 1813 case NT_GWINDOWS: /* gwindows_t SPARC only */ 1814 return (CORENOTE_R_OK_DUMP); 1815 1816 case NT_ASRS: /* asrset_t <sys/regset> sparcv9 only */ 1817 state.ns_vcol = 18; 1818 state.ns_t2col = 38; 1819 state.ns_v2col = 46; 1820 dump_asrset(&state, MSG_ORIG(MSG_CNOTE_DESC_ASRSET_T)); 1821 return (CORENOTE_R_OK); 1822 1823 case NT_LDT: /* ssd array <sys/sysi86.h> IA32 only */ 1824 return (CORENOTE_R_OK_DUMP); 1825 1826 case NT_PSTATUS: /* pstatus_t <sys/procfs.h> */ 1827 state.ns_vcol = 22; 1828 state.ns_t2col = 42; 1829 state.ns_v2col = 54; 1830 dump_pstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PSTATUS_T)); 1831 return (CORENOTE_R_OK); 1832 1833 case NT_PSINFO: /* psinfo_t <sys/procfs.h> */ 1834 state.ns_vcol = 25; 1835 state.ns_t2col = 45; 1836 state.ns_v2col = 58; 1837 dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T)); 1838 return (CORENOTE_R_OK); 1839 1840 case NT_PRCRED: /* prcred_t <sys/procfs.h> */ 1841 state.ns_vcol = 20; 1842 state.ns_t2col = 34; 1843 state.ns_v2col = 44; 1844 dump_prcred(&state, MSG_ORIG(MSG_CNOTE_DESC_PRCRED_T)); 1845 return (CORENOTE_R_OK); 1846 1847 case NT_UTSNAME: /* struct utsname <sys/utsname.h> */ 1848 state.ns_vcol = 18; 1849 dump_utsname(&state, MSG_ORIG(MSG_CNOTE_DESC_STRUCT_UTSNAME)); 1850 return (CORENOTE_R_OK); 1851 1852 case NT_LWPSTATUS: /* lwpstatus_t <sys/procfs.h> */ 1853 state.ns_vcol = 24; 1854 state.ns_t2col = 44; 1855 state.ns_v2col = 54; 1856 dump_lwpstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSTATUS_T)); 1857 return (CORENOTE_R_OK); 1858 1859 case NT_LWPSINFO: /* lwpsinfo_t <sys/procfs.h> */ 1860 state.ns_vcol = 22; 1861 state.ns_t2col = 42; 1862 state.ns_v2col = 54; 1863 dump_lwpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSINFO_T)); 1864 return (CORENOTE_R_OK); 1865 1866 case NT_PRPRIV: /* prpriv_t <sys/procfs.h> */ 1867 state.ns_vcol = 21; 1868 state.ns_t2col = 34; 1869 state.ns_v2col = 38; 1870 dump_prpriv(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPRIV_T)); 1871 return (CORENOTE_R_OK); 1872 1873 case NT_PRPRIVINFO: /* priv_impl_info_t <sys/priv.h> */ 1874 state.ns_vcol = 29; 1875 state.ns_t2col = 41; 1876 state.ns_v2col = 56; 1877 dump_priv_impl_info(&state, 1878 MSG_ORIG(MSG_CNOTE_DESC_PRIV_IMPL_INFO_T)); 1879 return (CORENOTE_R_OK); 1880 1881 case NT_CONTENT: /* core_content_t <sys/corectl.h> */ 1882 if (sizeof (core_content_t) > descsz) 1883 return (CORENOTE_R_BADDATA); 1884 { 1885 static sl_field_t fdesc = { 0, 8, 0, 0 }; 1886 Conv_cnote_cc_content_buf_t conv_buf; 1887 core_content_t content; 1888 1889 state.ns_vcol = 8; 1890 indent_enter(&state, 1891 MSG_ORIG(MSG_CNOTE_DESC_CORE_CONTENT_T), 1892 &fdesc); 1893 content = extract_as_lword(&state, &fdesc); 1894 print_str(&state, MSG_ORIG(MSG_STR_EMPTY), 1895 conv_cnote_cc_content(content, 0, &conv_buf)); 1896 indent_exit(&state); 1897 } 1898 return (CORENOTE_R_OK); 1899 1900 case NT_ZONENAME: /* string from getzonenamebyid(3C) */ 1901 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); 1902 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz)); 1903 return (CORENOTE_R_OK); 1904 1905 1906 case NT_FDINFO: 1907 state.ns_vcol = 22; 1908 state.ns_t2col = 41; 1909 state.ns_v2col = 54; 1910 dump_prfdinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRFDINFO_T)); 1911 return (CORENOTE_R_OK); 1912 1913 case NT_SPYMASTER: 1914 state.ns_vcol = 25; 1915 state.ns_t2col = 45; 1916 state.ns_v2col = 58; 1917 dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T)); 1918 return (CORENOTE_R_OK); 1919 1920 case NT_SECFLAGS: 1921 state.ns_vcol = 23; 1922 state.ns_t2col = 41; 1923 state.ns_v2col = 54; 1924 dump_secflags(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSECFLAGS_T)); 1925 return (CORENOTE_R_OK); 1926 1927 case NT_LWPNAME: 1928 state.ns_vcol = 20; 1929 dump_lwpname(&state, MSG_ORIG(MSG_CNOTE_DESC_PRLWPNAME_T)); 1930 return (CORENOTE_R_OK); 1931 } 1932 1933 return (CORENOTE_R_BADTYPE); 1934 }