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