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