/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. * Copyright 2022 Oxide Computer Company */ #include #include #include #include #include #include #include #include #include <_elfdump.h> #include #include #include #include /* * This module contains the code that displays data from the note * sections found in illumos core files. The format of these * note sections are described in the core(5) manpage. */ /* * Much of the code in this file uses the "%*s" format to set * the left margin indentation. This macro combines the indent * integer argument and the NULL string that follows it. */ #define INDENT state->ns_indent, MSG_ORIG(MSG_STR_EMPTY) /* * Indent unit, used for each nesting */ #define INDENT_STEP 4 /* * The PRINT_ macros are convenience wrappers on print_num(), * print_subtype(), and print_strbuf(). They reduce code * clutter by hiding the boilerplate arguments. * * Assumptions: * - A variable named "layout" exists in the compilation * environment, referencing the layout information for the * current type. * - The variable "state" references the current note state. */ #define PRINT_DEC(_title, _field) \ print_num(state, _title, &layout->_field, SL_FMT_NUM_DEC) #define PRINT_DEC_2UP(_title1, _field1, _title2, _field2) \ print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_DEC, \ _title2, &layout->_field2, SL_FMT_NUM_DEC) #define PRINT_HEX(_title, _field) \ print_num(state, _title, &layout->_field, SL_FMT_NUM_HEX) #define PRINT_HEX_2UP(_title1, _field1, _title2, _field2) \ print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_HEX, \ _title2, &layout->_field2, SL_FMT_NUM_HEX) #define PRINT_ZHEX(_title, _field) \ print_num(state, _title, &layout->_field, SL_FMT_NUM_ZHEX) #define PRINT_ZHEX_2UP(_title1, _field1, _title2, _field2) \ print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_ZHEX, \ _title2, &layout->_field2, SL_FMT_NUM_ZHEX) #define PRINT_SUBTYPE(_title, _field, _func) \ print_subtype(state, _title, &layout->_field, _func) #define PRINT_STRBUF(_title, _field) \ print_strbuf(state, _title, &layout->_field) /* * Structure used to maintain state data for a core note, or a subregion * (sub-struct) of a core note. These values would otherwise need to be * passed to nearly every routine. */ typedef struct { Half ns_mach; /* ELF machine type of core file */ const sl_arch_layout_t *ns_arch; /* structure layout def for mach */ int ns_swap; /* True if byte swapping is needed */ int ns_indent; /* Left margin indentation */ int ns_vcol; /* Column where value starts */ int ns_t2col; /* Column where 2up title starts */ int ns_v2col; /* Column where 2up value starts */ const char *ns_data; /* Pointer to struct data area */ Word ns_len; /* Length of struct data area */ } note_state_t; /* * Standard signature for a dump function used to process a note * or a sub-structure within a note. */ typedef void (* dump_func_t)(note_state_t *state, const char *title); /* * Some core notes contain string buffers of fixed size * that are expected to contain NULL terminated strings. * If the NULL is there, we can print these strings directly. * However, the potential exists for a corrupt file to have * a non-terminated buffer. This routine examines the given * string, and if the string is terminated, the string itself * is returned. Otherwise, it is copied to a static buffer, * and a pointer to the buffer is returned. */ static const char * safe_str(const char *str, size_t n) { static char buf[2048]; size_t i, used; if (n == 0) return (MSG_ORIG(MSG_STR_EMPTY)); /* * If the string is terminated and doesn't need escaping, we can return * it as is. */ for (i = 0; i < n; i++) { if (str[i] == '\0') return (str); if (!isascii(str[i]) || !isprint(str[i])) { break; } } for (i = 0, used = 0; i < n; i++) { if (str[i] == '\0') { if (used + 1 > sizeof (buf)) break; buf[used++] = str[i]; return (buf); } else if (isascii(str[i]) && isprint(str[i])) { if (used + 1 > sizeof (buf)) break; buf[used++] = str[i]; } else { size_t len = snprintf(NULL, 0, "\\x%02x", str[i]); if (used + len > sizeof (buf)) break; (void) snprintf(buf + used, sizeof (buf) - used, "\\x%02x", str[i]); used += len; } } if (i == n && used < sizeof (buf)) { buf[used] = '\0'; return (buf); } /* * If we got here, we would have overflowed. Figure out where we need to * start and truncate. */ used = MIN(used, sizeof (buf) - 4); buf[used++] = '.'; buf[used++] = '.'; buf[used++] = '.'; buf[used++] = '\0'; return (buf); } /* * Convenience wrappers on top of the corresponding sl_XXX() functions. */ static Word extract_as_word(note_state_t *state, const sl_field_t *fdesc) { return (sl_extract_as_word(state->ns_data, state->ns_swap, fdesc)); } static Lword extract_as_lword(note_state_t *state, const sl_field_t *fdesc) { return (sl_extract_as_lword(state->ns_data, state->ns_swap, fdesc)); } static int extract_as_sword(note_state_t *state, const sl_field_t *fdesc) { return (sl_extract_as_sword(state->ns_data, state->ns_swap, fdesc)); } static const char * fmt_num(note_state_t *state, const sl_field_t *fdesc, sl_fmt_num_t fmt_type, sl_fmtbuf_t buf) { return (sl_fmt_num(state->ns_data, state->ns_swap, fdesc, fmt_type, buf)); } /* * Return true of the data for the specified field is available. */ inline static int data_present(note_state_t *state, const sl_field_t *fdesc) { return ((fdesc->slf_offset + fdesc->slf_eltlen) <= state->ns_len); } /* * indent_enter/exit are used to start/end output for a subitem. * On entry, a title is output, and the indentation level is raised * by one unit. On exit, the indentation level is restored to its * previous value. */ static void indent_enter(note_state_t *state, const char *title, const sl_field_t *first_fdesc) { /* * If the first field offset and extent fall past the end of the * available data, then return without printing a title. That note * is from an older core file that doesn't have all the fields * that we know about. */ if (data_present(state, first_fdesc)) dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_TITLE), INDENT, title); state->ns_indent += INDENT_STEP; } static void indent_exit(note_state_t *state) { state->ns_indent -= INDENT_STEP; } /* * print_num outputs a field on one line, in the format: * * title: value */ static void print_num(note_state_t *state, const char *title, const sl_field_t *fdesc, sl_fmt_num_t fmt_type) { sl_fmtbuf_t buf; /* * If the field offset and extent fall past the end of the * available data, then return without doing anything. That note * is from an older core file that doesn't have all the fields * that we know about. */ if (!data_present(state, fdesc)) return; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT, state->ns_vcol - state->ns_indent, title, fmt_num(state, fdesc, fmt_type, buf)); } /* * print_num_2up outputs two fields on one line, in the format: * * title1: value1 title2: value2 */ static void print_num_2up(note_state_t *state, const char *title1, const sl_field_t *fdesc1, sl_fmt_num_t fmt_type1, const char *title2, const sl_field_t *fdesc2, sl_fmt_num_t fmt_type2) { sl_fmtbuf_t buf1, buf2; /* * If the field offset and extent fall past the end of the * available data, then return without doing anything. That note * is from an older core file that doesn't have all the fields * that we know about. */ if (!(data_present(state, fdesc1) && data_present(state, fdesc2))) return; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, state->ns_vcol - state->ns_indent, title1, state->ns_t2col - state->ns_vcol, fmt_num(state, fdesc1, fmt_type1, buf1), state->ns_v2col - state->ns_t2col, title2, fmt_num(state, fdesc2, fmt_type2, buf2)); } /* * print_strbuf outputs a fixed sized character buffer field * on one line, in the format: * * title: value */ static void print_strbuf(note_state_t *state, const char *title, const sl_field_t *fdesc) { Word n; /* * If we are past the end of the data area, then return * without doing anything. That note is from an older core * file that doesn't have all the fields that we know about. * * Note that we are willing to accept a partial buffer, * so we don't use data_present() for this test. */ if (fdesc->slf_offset >= state->ns_len) return; /* * We expect the full buffer to be present, but if there * is less than that, we will still proceed. The use of safe_str() * protects us from the effect of printing garbage data. */ n = state->ns_len - fdesc->slf_offset; if (n > fdesc->slf_nelts) n = fdesc->slf_nelts; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT, state->ns_vcol - state->ns_indent, title, safe_str(fdesc->slf_offset + state->ns_data, n)); } /* * print_str outputs an arbitrary string value item * on one line, in the format: * * title: str */ static void print_str(note_state_t *state, const char *title, const char *str) { dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT, state->ns_vcol - state->ns_indent, title, str); } /* * Used when one dump function needs to call another dump function * in order to display a subitem. This routine constructs a state * block for the sub-region, and then calls the dump function with it. * This limits the amount of data visible to the sub-function to that * for the sub-item. */ static void print_subtype(note_state_t *state, const char *title, const sl_field_t *fdesc, dump_func_t dump_func) { note_state_t sub_state; /* * If there is no data for the sub-item, return immediately. * Partial data is left to the dump function to handle, * as that can be a sign of an older core file with less data, * which can still be interpreted. */ if (fdesc->slf_offset >= state->ns_len) return; /* * Construct a state block that reflects the sub-item */ sub_state = *state; sub_state.ns_data += fdesc->slf_offset; sub_state.ns_len -= fdesc->slf_offset; if (sub_state.ns_len > fdesc->slf_eltlen) sub_state.ns_len = fdesc->slf_eltlen; (* dump_func)(&sub_state, title); } /* * Output a sequence of array elements, giving each * element an index, in the format: * * [ndx] value * * entry: * state - Current state * base_desc - Field descriptor for 1st element of array * nelts - # of array elements to display * check_nelts - If True (1), nelts is clipped to fdesc->slf_nelts. * If False (1), nelts is not clipped. * title - Name of array */ static void print_array(note_state_t *state, const sl_field_t *base_desc, sl_fmt_num_t fmt_type, int nelts, int check_nelts, const char *title) { char index1[MAXNDXSIZE], index2[MAXNDXSIZE]; int i; sl_field_t fdesc1, fdesc2; if (check_nelts && (check_nelts > base_desc->slf_nelts)) nelts = base_desc->slf_nelts; if (nelts == 0) return; indent_enter(state, title, base_desc); fdesc1 = fdesc2 = *base_desc; for (i = 0; i < nelts; ) { if (i == (nelts - 1)) { /* One final value is left */ if (!data_present(state, &fdesc1)) break; (void) snprintf(index1, sizeof (index1), MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i)); print_num(state, index1, &fdesc1, fmt_type); fdesc1.slf_offset += fdesc1.slf_eltlen; i++; continue; } /* There are at least 2 items left. Show 2 up. */ fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; if (!(data_present(state, &fdesc1) && data_present(state, &fdesc2))) break; (void) snprintf(index1, sizeof (index1), MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i)); (void) snprintf(index2, sizeof (index2), MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i + 1)); print_num_2up(state, index1, &fdesc1, fmt_type, index2, &fdesc2, fmt_type); fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; i += 2; } indent_exit(state); } /* * Output information from auxv_t structure. */ static void dump_auxv(note_state_t *state, const char *title) { const sl_auxv_layout_t *layout = state->ns_arch->auxv; union { Conv_cap_val_hw1_buf_t hw1; Conv_cap_val_hw2_buf_t hw2; Conv_cap_val_hw3_buf_t hw3; Conv_cnote_auxv_af_buf_t auxv_af; Conv_ehdr_flags_buf_t ehdr_flags; Conv_secflags_buf_t secflags; Conv_inv_buf_t inv; } conv_buf; sl_fmtbuf_t buf; int ndx, ndx_start; Word sizeof_auxv; sizeof_auxv = layout->sizeof_struct.slf_eltlen; indent_enter(state, title, &layout->sizeof_struct); /* * Immediate indent_exit() restores the indent level to * that of the title. We include indentation as part of * the index string, which is right justified, and don't * want the usual indentation spacing. */ indent_exit(state); ndx = 0; while (state->ns_len > sizeof_auxv) { char index[(MAXNDXSIZE * 2) + 1]; sl_fmt_num_t num_fmt = SL_FMT_NUM_ZHEX; const char *vstr = NULL; Word w; int type; sl_field_t a_type_next; type = extract_as_word(state, &layout->a_type); ndx_start = ndx; switch (type) { case AT_NULL: a_type_next = layout->a_type; a_type_next.slf_offset += sizeof_auxv; while ((state->ns_len - sizeof_auxv) >= sizeof_auxv) { type = extract_as_word(state, &a_type_next); if (type != AT_NULL) break; ndx++; state->ns_data += sizeof_auxv; state->ns_len -= sizeof_auxv; } num_fmt = SL_FMT_NUM_HEX; break; case AT_IGNORE: case AT_SUN_IFLUSH: num_fmt = SL_FMT_NUM_HEX; break; case AT_EXECFD: case AT_PHENT: case AT_PHNUM: case AT_PAGESZ: case AT_SUN_UID: case AT_SUN_RUID: case AT_SUN_GID: case AT_SUN_RGID: case AT_SUN_LPAGESZ: case AT_SUN_FPSIZE: case AT_SUN_FPTYPE: num_fmt = SL_FMT_NUM_DEC; break; case AT_FLAGS: /* processor flags */ w = extract_as_word(state, &layout->a_val); vstr = conv_ehdr_flags(state->ns_mach, w, 0, &conv_buf.ehdr_flags); break; case AT_SUN_HWCAP: w = extract_as_word(state, &layout->a_val); vstr = conv_cap_val_hw1(w, state->ns_mach, 0, &conv_buf.hw1); /* * conv_cap_val_hw1() produces output like: * * 0xfff [ flg1 flg2 0xff] * * where the first hex value is the complete value, * and the second is the leftover bits. We only * want the part in brackets, and failing that, * would rather fall back to formatting the full * value ourselves. */ while ((*vstr != '\0') && (*vstr != '[')) vstr++; if (*vstr != '[') vstr = NULL; num_fmt = SL_FMT_NUM_HEX; break; case AT_SUN_HWCAP2: w = extract_as_word(state, &layout->a_val); vstr = conv_cap_val_hw2(w, state->ns_mach, 0, &conv_buf.hw2); /* * conv_cap_val_hw2() produces output like: * * 0xfff [ flg1 flg2 0xff] * * where the first hex value is the complete value, * and the second is the leftover bits. We only * want the part in brackets, and failing that, * would rather fall back to formatting the full * value ourselves. */ while ((*vstr != '\0') && (*vstr != '[')) vstr++; if (*vstr != '[') vstr = NULL; num_fmt = SL_FMT_NUM_HEX; break; case AT_SUN_HWCAP3: w = extract_as_word(state, &layout->a_val); vstr = conv_cap_val_hw3(w, state->ns_mach, 0, &conv_buf.hw3); /* * conv_cap_val_hw3() produces output like: * * 0xfff [ flg1 flg2 0xff] * * where the first hex value is the complete value, * and the second is the leftover bits. We only * want the part in brackets, and failing that, * would rather fall back to formatting the full * value ourselves. */ while ((*vstr != '\0') && (*vstr != '[')) vstr++; if (*vstr != '[') vstr = NULL; num_fmt = SL_FMT_NUM_HEX; break; case AT_SUN_AUXFLAGS: w = extract_as_word(state, &layout->a_val); vstr = conv_cnote_auxv_af(w, 0, &conv_buf.auxv_af); num_fmt = SL_FMT_NUM_HEX; break; } if (ndx == ndx_start) (void) snprintf(index, sizeof (index), MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(ndx)); else (void) snprintf(index, sizeof (index), MSG_ORIG(MSG_FMT_INDEXRNG), EC_WORD(ndx_start), EC_WORD(ndx)); if (vstr == NULL) vstr = fmt_num(state, &layout->a_val, num_fmt, buf); dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_AUXVLINE), INDENT, index, state->ns_vcol - state->ns_indent, conv_cnote_auxv_type(type, CONV_FMT_DECIMAL, &conv_buf.inv), vstr); state->ns_data += sizeof_auxv; state->ns_len -= sizeof_auxv; ndx++; } } /* * Output information from fltset_t structure. */ static void dump_fltset(note_state_t *state, const char *title) { #define NELTS 4 const sl_fltset_layout_t *layout = state->ns_arch->fltset; Conv_cnote_fltset_buf_t buf; sl_field_t fdesc; uint32_t mask[NELTS]; int i, nelts; if (!data_present(state, &layout->sizeof_struct)) return; fdesc = layout->word; nelts = fdesc.slf_nelts; if (nelts > NELTS) /* Type has grown? Show what we understand */ nelts = NELTS; for (i = 0; i < nelts; i++) { mask[i] = extract_as_word(state, &fdesc); fdesc.slf_offset += fdesc.slf_eltlen; } print_str(state, title, conv_cnote_fltset(mask, nelts, 0, &buf)); #undef NELTS } /* * Output information from sigset_t structure. */ static void dump_sigset(note_state_t *state, const char *title) { #define NELTS 4 const sl_sigset_layout_t *layout = state->ns_arch->sigset; Conv_cnote_sigset_buf_t buf; sl_field_t fdesc; uint32_t mask[NELTS]; int i, nelts; if (!data_present(state, &layout->sizeof_struct)) return; fdesc = layout->sigbits; nelts = fdesc.slf_nelts; if (nelts > NELTS) /* Type has grown? Show what we understand */ nelts = NELTS; for (i = 0; i < nelts; i++) { mask[i] = extract_as_word(state, &fdesc); fdesc.slf_offset += fdesc.slf_eltlen; } print_str(state, title, conv_cnote_sigset(mask, nelts, 0, &buf)); #undef NELTS } /* * Output information from sigaction structure. */ static void dump_sigaction(note_state_t *state, const char *title) { const sl_sigaction_layout_t *layout = state->ns_arch->sigaction; Conv_cnote_sa_flags_buf_t conv_buf; Word w; indent_enter(state, title, &layout->sa_flags); if (data_present(state, &layout->sa_flags)) { w = extract_as_word(state, &layout->sa_flags); print_str(state, MSG_ORIG(MSG_CNOTE_T_SA_FLAGS), conv_cnote_sa_flags(w, 0, &conv_buf)); } PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_SA_HANDLER), sa_hand, MSG_ORIG(MSG_CNOTE_T_SA_SIGACTION), sa_sigact); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_SA_MASK), sa_mask, dump_sigset); indent_exit(state); } /* * Output information from siginfo structure. */ static void dump_siginfo(note_state_t *state, const char *title) { const sl_siginfo_layout_t *layout = state->ns_arch->siginfo; Conv_inv_buf_t inv_buf; Word w; int v_si_code, v_si_signo; if (!data_present(state, &layout->sizeof_struct)) return; indent_enter(state, title, &layout->f_si_signo); v_si_signo = extract_as_sword(state, &layout->f_si_signo); print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_SIGNO), conv_cnote_signal(v_si_signo, CONV_FMT_DECIMAL, &inv_buf)); w = extract_as_word(state, &layout->f_si_errno); print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_ERRNO), conv_cnote_errno(w, CONV_FMT_DECIMAL, &inv_buf)); v_si_code = extract_as_sword(state, &layout->f_si_code); print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_CODE), conv_cnote_si_code(state->ns_mach, v_si_signo, v_si_code, CONV_FMT_DECIMAL, &inv_buf)); if ((v_si_signo == 0) || (v_si_code == SI_NOINFO)) { indent_exit(state); return; } /* User generated signals have (si_code <= 0) */ if (v_si_code <= 0) { PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_PID), f_si_pid); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_UID), f_si_uid); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_CTID), f_si_ctid); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_ZONEID), f_si_zoneid); switch (v_si_code) { case SI_QUEUE: case SI_TIMER: case SI_ASYNCIO: case SI_MESGQ: indent_enter(state, MSG_ORIG(MSG_CNOTE_T_SI_VALUE), &layout->f_si_value_int); PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SIVAL_INT), f_si_value_int); PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SIVAL_PTR), f_si_value_ptr); indent_exit(state); break; } indent_exit(state); return; } /* * Remaining cases are kernel generated signals. Output any * signal or code specific information. */ if (v_si_code == SI_RCTL) PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_SI_ENTITY), f_si_entity); switch (v_si_signo) { case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SI_ADDR), f_si_addr); break; case SIGCHLD: PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_PID), f_si_pid); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_STATUS), f_si_status); break; case SIGPOLL: PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_BAND), f_si_band); break; } indent_exit(state); } /* * Output information from stack_t structure. */ static void dump_stack(note_state_t *state, const char *title) { const sl_stack_layout_t *layout = state->ns_arch->stack; Conv_cnote_ss_flags_buf_t conv_buf; Word w; indent_enter(state, title, &layout->ss_size); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_SS_SP), &layout->ss_sp, SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_SS_SIZE), &layout->ss_size, SL_FMT_NUM_HEX); if (data_present(state, &layout->ss_flags)) { w = extract_as_word(state, &layout->ss_flags); print_str(state, MSG_ORIG(MSG_CNOTE_T_SS_FLAGS), conv_cnote_ss_flags(w, 0, &conv_buf)); } indent_exit(state); } /* * Output information from sysset_t structure. */ static void dump_sysset(note_state_t *state, const char *title) { #define NELTS 16 const sl_sysset_layout_t *layout = state->ns_arch->sysset; Conv_cnote_sysset_buf_t buf; sl_field_t fdesc; uint32_t mask[NELTS]; int i, nelts; if (!data_present(state, &layout->sizeof_struct)) return; fdesc = layout->word; nelts = fdesc.slf_nelts; if (nelts > NELTS) /* Type has grown? Show what we understand */ nelts = NELTS; for (i = 0; i < nelts; i++) { mask[i] = extract_as_word(state, &fdesc); fdesc.slf_offset += fdesc.slf_eltlen; } print_str(state, title, conv_cnote_sysset(mask, nelts, 0, &buf)); #undef NELTS } /* * Output information from timestruc_t structure. */ static void dump_timestruc(note_state_t *state, const char *title) { const sl_timestruc_layout_t *layout = state->ns_arch->timestruc; indent_enter(state, title, &layout->tv_sec); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_TV_SEC), tv_sec, MSG_ORIG(MSG_CNOTE_T_TV_NSEC), tv_nsec); indent_exit(state); } /* * Output information from prsecflags_t structure. */ static void dump_secflags(note_state_t *state, const char *title) { const sl_prsecflags_layout_t *layout = state->ns_arch->prsecflags; Conv_secflags_buf_t inv; Lword lw; Word w; indent_enter(state, title, &layout->pr_version); w = extract_as_word(state, &layout->pr_version); if (w != PRSECFLAGS_VERSION_1) { PRINT_DEC(MSG_INTL(MSG_NOTE_BAD_SECFLAGS_VER), pr_version); dump_hex_bytes(state->ns_data, state->ns_len, state->ns_indent, 4, 3); } else { PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_VERSION), pr_version); lw = extract_as_lword(state, &layout->pr_effective); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_EFFECTIVE), conv_prsecflags(lw, 0, &inv)); lw = extract_as_lword(state, &layout->pr_inherit); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_INHERIT), conv_prsecflags(lw, 0, &inv)); lw = extract_as_lword(state, &layout->pr_lower); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_LOWER), conv_prsecflags(lw, 0, &inv)); lw = extract_as_lword(state, &layout->pr_upper); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_UPPER), conv_prsecflags(lw, 0, &inv)); } indent_exit(state); } /* * Output information from utsname structure. */ static void dump_utsname(note_state_t *state, const char *title) { const sl_utsname_layout_t *layout = state->ns_arch->utsname; indent_enter(state, title, &layout->sysname); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_SYSNAME), sysname); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_NODENAME), nodename); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_RELEASE), release); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_VERSION), version); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_MACHINE), machine); indent_exit(state); } /* * Dump register contents */ static void dump_prgregset(note_state_t *state, const char *title) { sl_field_t fdesc1, fdesc2; sl_fmtbuf_t buf1, buf2; Conv_inv_buf_t inv_buf1, inv_buf2; Word w; fdesc1 = fdesc2 = state->ns_arch->prgregset->elt0; indent_enter(state, title, &fdesc1); for (w = 0; w < fdesc1.slf_nelts; ) { if (w == (fdesc1.slf_nelts - 1)) { /* One last register is left */ if (!data_present(state, &fdesc1)) break; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT, state->ns_vcol - state->ns_indent, conv_cnote_pr_regname(state->ns_mach, w, CONV_FMT_DECIMAL, &inv_buf1), fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1)); fdesc1.slf_offset += fdesc1.slf_eltlen; w++; continue; } /* There are at least 2 more registers left. Show 2 up */ fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; if (!(data_present(state, &fdesc1) && data_present(state, &fdesc2))) break; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, state->ns_vcol - state->ns_indent, conv_cnote_pr_regname(state->ns_mach, w, CONV_FMT_DECIMAL, &inv_buf1), state->ns_t2col - state->ns_vcol, fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1), state->ns_v2col - state->ns_t2col, conv_cnote_pr_regname(state->ns_mach, w + 1, CONV_FMT_DECIMAL, &inv_buf2), fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2)); fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; w += 2; } indent_exit(state); } /* * Output information from lwpstatus_t structure. */ static void dump_lwpstatus(note_state_t *state, const char *title) { const sl_lwpstatus_layout_t *layout = state->ns_arch->lwpstatus; Word w, w2; int32_t i; union { Conv_inv_buf_t inv; Conv_cnote_pr_flags_buf_t flags; } conv_buf; indent_enter(state, title, &layout->pr_flags); if (data_present(state, &layout->pr_flags)) { w = extract_as_word(state, &layout->pr_flags); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), conv_cnote_pr_flags(w, 0, &conv_buf.flags)); } PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LWPID), pr_lwpid); if (data_present(state, &layout->pr_why)) { w = extract_as_word(state, &layout->pr_why); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHY), conv_cnote_pr_why(w, 0, &conv_buf.inv)); if (data_present(state, &layout->pr_what)) { w2 = extract_as_word(state, &layout->pr_what); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHAT), conv_cnote_pr_what(w, w2, 0, &conv_buf.inv)); } } if (data_present(state, &layout->pr_cursig)) { w = extract_as_word(state, &layout->pr_cursig); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_CURSIG), conv_cnote_signal(w, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_INFO), pr_info, dump_siginfo); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPPEND), pr_lwppend, dump_sigset); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPHOLD), pr_lwphold, dump_sigset); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ACTION), pr_action, dump_sigaction); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ALTSTACK), pr_altstack, dump_stack); PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_OLDCONTEXT), pr_oldcontext); if (data_present(state, &layout->pr_syscall)) { w = extract_as_word(state, &layout->pr_syscall); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSYSARG), pr_nsysarg); if (data_present(state, &layout->pr_errno)) { w = extract_as_word(state, &layout->pr_errno); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_ERRNO), conv_cnote_errno(w, CONV_FMT_DECIMAL, &conv_buf.inv)); } if (data_present(state, &layout->pr_nsysarg)) { w2 = extract_as_word(state, &layout->pr_nsysarg); print_array(state, &layout->pr_sysarg, SL_FMT_NUM_ZHEX, w2, 1, MSG_ORIG(MSG_CNOTE_T_PR_SYSARG)); } PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RVAL1), pr_rval1, MSG_ORIG(MSG_CNOTE_T_PR_RVAL2), pr_rval2); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TSTAMP), pr_tstamp, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); if (data_present(state, &layout->pr_errpriv)) { i = extract_as_sword(state, &layout->pr_errpriv); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_ERRPRIV), conv_cnote_priv(i, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_USTACK), pr_ustack, MSG_ORIG(MSG_CNOTE_T_PR_INSTR), pr_instr); /* * In order to line up all the values in a single column, * we would have to set vcol to a very high value, which results * in ugly looking output that runs off column 80. So, we use * two levels of vcol, one for the contents so far, and a * higher one for the pr_reg sub-struct. */ state->ns_vcol += 3; state->ns_t2col += 3; state->ns_v2col += 2; PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_REG), pr_reg, dump_prgregset); state->ns_vcol -= 3; state->ns_t2col -= 3; state->ns_v2col -= 2; /* * The floating point register state is complex, and highly * platform dependent. For now, we simply display it as * a hex dump. This can be replaced if better information * is required. */ if (data_present(state, &layout->pr_fpreg)) { indent_enter(state, MSG_ORIG(MSG_CNOTE_T_PR_FPREG), &layout->pr_fpreg); dump_hex_bytes(layout->pr_fpreg.slf_offset + state->ns_data, layout->pr_fpreg.slf_eltlen, state->ns_indent, 4, 3); indent_exit(state); } indent_exit(state); } /* * Output information from pstatus_t structure. */ static void dump_pstatus(note_state_t *state, const char *title) { const sl_pstatus_layout_t *layout = state->ns_arch->pstatus; Word w; union { Conv_inv_buf_t inv; Conv_cnote_pr_flags_buf_t flags; } conv_buf; indent_enter(state, title, &layout->pr_flags); if (data_present(state, &layout->pr_flags)) { w = extract_as_word(state, &layout->pr_flags); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), conv_cnote_pr_flags(w, 0, &conv_buf.flags)); } PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid, MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid, MSG_ORIG(MSG_CNOTE_T_PR_AGENTID), pr_agentid); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGPEND), pr_sigpend, dump_sigset); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_BRKBASE), &layout->pr_brkbase, SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_BRKSIZE), &layout->pr_brksize, SL_FMT_NUM_HEX); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_STKBASE), &layout->pr_stkbase, SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_STKSIZE), &layout->pr_stksize, SL_FMT_NUM_HEX); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CUTIME), pr_cutime, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CSTIME), pr_cstime, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGTRACE), pr_sigtrace, dump_sigset); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_FLTTRACE), pr_flttrace, dump_fltset); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SYSENTRY), pr_sysentry, dump_sysset); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SYSEXIT), pr_sysexit, dump_sysset); if (data_present(state, &layout->pr_dmodel)) { w = extract_as_word(state, &layout->pr_dmodel); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); } PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid, MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb, MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid); /* * In order to line up all the values in a single column, * we would have to set vcol to a very high value, which results * in ugly looking output that runs off column 80. So, we use * two levels of vcol, one for the contents so far, and a * higher one for the pr_lwp sub-struct. */ state->ns_vcol += 5; state->ns_t2col += 5; state->ns_v2col += 5; PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpstatus); state->ns_vcol -= 5; state->ns_t2col -= 5; state->ns_v2col -= 5; indent_exit(state); } /* * Output information from prstatus_t () structure. */ static void dump_prstatus(note_state_t *state, const char *title) { const sl_prstatus_layout_t *layout = state->ns_arch->prstatus; Word w, w2; int i; union { Conv_inv_buf_t inv; Conv_cnote_old_pr_flags_buf_t flags; } conv_buf; indent_enter(state, title, &layout->pr_flags); if (data_present(state, &layout->pr_flags)) { w = extract_as_word(state, &layout->pr_flags); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS), conv_cnote_old_pr_flags(w, 0, &conv_buf.flags)); } if (data_present(state, &layout->pr_why)) { w = extract_as_word(state, &layout->pr_why); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHY), conv_cnote_pr_why(w, 0, &conv_buf.inv)); if (data_present(state, &layout->pr_what)) { w2 = extract_as_word(state, &layout->pr_what); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHAT), conv_cnote_pr_what(w, w2, 0, &conv_buf.inv)); } } PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_INFO), pr_info, dump_siginfo); if (data_present(state, &layout->pr_cursig)) { w = extract_as_word(state, &layout->pr_cursig); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_CURSIG), conv_cnote_signal(w, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGPEND), pr_sigpend, dump_sigset); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGHOLD), pr_sighold, dump_sigset); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ALTSTACK), pr_altstack, dump_stack); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ACTION), pr_action, dump_sigaction); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp, MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CUTIME), pr_cutime, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CSTIME), pr_cstime, dump_timestruc); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); if (data_present(state, &layout->pr_syscall)) { w = extract_as_word(state, &layout->pr_syscall); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSYSARG), pr_nsysarg); if (data_present(state, &layout->pr_nsysarg)) { w2 = extract_as_word(state, &layout->pr_nsysarg); print_array(state, &layout->pr_sysarg, SL_FMT_NUM_ZHEX, w2, 1, MSG_ORIG(MSG_CNOTE_T_PR_SYSARG)); } PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_WHO), pr_who); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPPEND), pr_sigpend, dump_sigset); PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_OLDCONTEXT), pr_oldcontext); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_BRKBASE), &layout->pr_brkbase, SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_BRKSIZE), &layout->pr_brksize, SL_FMT_NUM_HEX); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_STKBASE), &layout->pr_stkbase, SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_STKSIZE), &layout->pr_stksize, SL_FMT_NUM_HEX); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_PROCESSOR), pr_processor); if (data_present(state, &layout->pr_bind)) { i = extract_as_sword(state, &layout->pr_bind); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BIND), conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_INSTR), pr_instr); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_REG), pr_reg, dump_prgregset); indent_exit(state); } static void dump_lwpname(note_state_t *state, const char *title) { const sl_prlwpname_layout_t *layout = state->ns_arch->prlwpname; indent_enter(state, title, &layout->pr_lwpid); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LWPID), pr_lwpid); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_LWPNAME), pr_lwpname); indent_exit(state); } /* * Print percent from 16-bit binary fraction [0 .. 1] * Round up .01 to .1 to indicate some small percentage (the 0x7000 below). * * Note: This routine was copied from ps(1) and then modified. */ static const char * prtpct_value(note_state_t *state, const sl_field_t *fdesc, sl_fmtbuf_t buf) { uint_t value; /* need 32 bits to compute with */ value = extract_as_word(state, fdesc); value = ((value * 1000) + 0x7000) >> 15; /* [0 .. 1000] */ if (value >= 1000) value = 999; (void) snprintf(buf, sizeof (sl_fmtbuf_t), MSG_ORIG(MSG_CNOTE_FMT_PRTPCT), value / 10, value % 10); return (buf); } /* * Version of prtpct() used for a 2-up display of two adjacent percentages. */ static void prtpct_2up(note_state_t *state, const sl_field_t *fdesc1, const char *title1, const sl_field_t *fdesc2, const char *title2) { sl_fmtbuf_t buf1, buf2; if (!(data_present(state, fdesc1) && data_present(state, fdesc2))) return; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, state->ns_vcol - state->ns_indent, title1, state->ns_t2col - state->ns_vcol, prtpct_value(state, fdesc1, buf1), state->ns_v2col - state->ns_t2col, title2, prtpct_value(state, fdesc2, buf2)); } /* * The psinfo_t and prpsinfo_t structs have pr_state and pr_sname * fields that we wish to print in a 2up format. The pr_state is * an integer, while pr_sname is a single character. */ static void print_state_sname_2up(note_state_t *state, const sl_field_t *state_fdesc, const sl_field_t *sname_fdesc) { sl_fmtbuf_t buf1, buf2; int sname; /* * If the field slf_offset and extent fall past the end of the * available data, then return without doing anything. That note * is from an older core file that doesn't have all the fields * that we know about. */ if (!(data_present(state, state_fdesc) && data_present(state, sname_fdesc))) return; sname = extract_as_sword(state, sname_fdesc); buf2[0] = sname; buf2[1] = '\0'; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, state->ns_vcol - state->ns_indent, MSG_ORIG(MSG_CNOTE_T_PR_STATE), state->ns_t2col - state->ns_vcol, fmt_num(state, state_fdesc, SL_FMT_NUM_DEC, buf1), state->ns_v2col - state->ns_t2col, MSG_ORIG(MSG_CNOTE_T_PR_SNAME), buf2); } /* * Output information from lwpsinfo_t structure. */ static void dump_lwpsinfo(note_state_t *state, const char *title) { const sl_lwpsinfo_layout_t *layout = state->ns_arch->lwpsinfo; Word w; int32_t i; union { Conv_cnote_proc_flag_buf_t proc_flag; Conv_inv_buf_t inv; } conv_buf; indent_enter(state, title, &layout->pr_flag); if (data_present(state, &layout->pr_flag)) { w = extract_as_word(state, &layout->pr_flag); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); } print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_LWPID), &layout->pr_lwpid, SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, SL_FMT_NUM_ZHEX); PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan); if (data_present(state, &layout->pr_stype)) { w = extract_as_word(state, &layout->pr_stype); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_STYPE), conv_cnote_pr_stype(w, CONV_FMT_DECIMAL, &conv_buf.inv)); } print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice); if (data_present(state, &layout->pr_syscall)) { w = extract_as_word(state, &layout->pr_syscall); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri, MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu); if (data_present(state, &layout->pr_pri) && data_present(state, &layout->pr_pctcpu)) { sl_fmtbuf_t buf1, buf2; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, state->ns_vcol - state->ns_indent, MSG_ORIG(MSG_CNOTE_T_PR_PRI), state->ns_t2col - state->ns_vcol, fmt_num(state, &layout->pr_pri, SL_FMT_NUM_DEC, buf1), state->ns_v2col - state->ns_t2col, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), prtpct_value(state, &layout->pr_pctcpu, buf2)); } PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_NAME), pr_name); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ONPRO), pr_onpro, MSG_ORIG(MSG_CNOTE_T_PR_BINDPRO), pr_bindpro); if (data_present(state, &layout->pr_bindpset)) { i = extract_as_sword(state, &layout->pr_bindpset); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BINDPSET), conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LGRP), pr_lgrp); indent_exit(state); } /* * Output information from psinfo_t structure. */ static void dump_psinfo(note_state_t *state, const char *title) { const sl_psinfo_layout_t *layout = state->ns_arch->psinfo; Word w; union { Conv_cnote_proc_flag_buf_t proc_flag; Conv_inv_buf_t inv; } conv_buf; indent_enter(state, title, &layout->pr_flag); if (data_present(state, &layout->pr_flag)) { w = extract_as_word(state, &layout->pr_flag); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); } PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid, MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid, MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size, SL_FMT_NUM_HEX); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), &layout->pr_rssize, SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_TTYDEV), &layout->pr_ttydev, SL_FMT_NUM_DEC); prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM)); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat, SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc, SL_FMT_NUM_DEC); PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ARGV), pr_argv, MSG_ORIG(MSG_CNOTE_T_PR_ENVP), pr_envp); if (data_present(state, &layout->pr_dmodel)) { w = extract_as_word(state, &layout->pr_dmodel); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); } PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid, MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb, MSG_ORIG(MSG_CNOTE_T_PR_POOLID), pr_poolid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid, MSG_ORIG(MSG_CNOTE_T_PR_CONTRACT), pr_contract); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpsinfo); indent_exit(state); } /* * Output information from prpsinfo_t structure. */ static void dump_prpsinfo(note_state_t *state, const char *title) { const sl_prpsinfo_layout_t *layout = state->ns_arch->prpsinfo; Word w; union { Conv_cnote_proc_flag_buf_t proc_flag; Conv_inv_buf_t inv; } conv_buf; indent_enter(state, title, &layout->pr_state); print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZOMB), pr_zomb, MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice); if (data_present(state, &layout->pr_flag)) { w = extract_as_word(state, &layout->pr_flag); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG), conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag)); } PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid, MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp, MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr, SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size, SL_FMT_NUM_HEX); PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), pr_rssize, MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc); PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PRI), pr_pri, MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OTTYDEV), pr_ottydev, MSG_ORIG(MSG_CNOTE_T_PR_LTTYDEV), pr_lttydev); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs); if (data_present(state, &layout->pr_syscall)) { w = extract_as_word(state, &layout->pr_syscall); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL), conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv)); } PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc); PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_BYSIZE), pr_bysize, MSG_ORIG(MSG_CNOTE_T_PR_BYRSSIZE), pr_byrssize); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc, SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ARGV), &layout->pr_argv, SL_FMT_NUM_ZHEX); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ENVP), &layout->pr_envp, SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat, SL_FMT_NUM_HEX); prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU), &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM)); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid, MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid); if (data_present(state, &layout->pr_dmodel)) { w = extract_as_word(state, &layout->pr_dmodel); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL), conv_cnote_pr_dmodel(w, 0, &conv_buf.inv)); } indent_exit(state); } /* * Output information from prcred_t structure. */ static void dump_prcred(note_state_t *state, const char *title) { const sl_prcred_layout_t *layout = state->ns_arch->prcred; Word ngroups; indent_enter(state, title, &layout->pr_euid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid, MSG_ORIG(MSG_CNOTE_T_PR_RUID), pr_ruid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_SUID), pr_suid, MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RGID), pr_rgid, MSG_ORIG(MSG_CNOTE_T_PR_SGID), pr_sgid); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NGROUPS), pr_ngroups); if (data_present(state, &layout->pr_ngroups)) { ngroups = extract_as_word(state, &layout->pr_ngroups); print_array(state, &layout->pr_groups, SL_FMT_NUM_DEC, ngroups, 0, MSG_ORIG(MSG_CNOTE_T_PR_GROUPS)); } indent_exit(state); } /* * Output information from prpriv_t structure. */ static void dump_prpriv(note_state_t *state, const char *title) { const sl_prpriv_layout_t *layout = state->ns_arch->prpriv; Word nsets; indent_enter(state, title, &layout->pr_nsets); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSETS), pr_nsets); PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_SETSIZE), pr_setsize); PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_INFOSIZE), pr_infosize); if (data_present(state, &layout->pr_nsets)) { nsets = extract_as_word(state, &layout->pr_nsets); print_array(state, &layout->pr_sets, SL_FMT_NUM_ZHEX, nsets, 0, MSG_ORIG(MSG_CNOTE_T_PR_SETS)); } indent_exit(state); } static void dump_prfdinfo(note_state_t *state, const char *title) { const sl_prfdinfo_layout_t *layout = state->ns_arch->prfdinfo; char buf[1024]; uint32_t fileflags, mode; indent_enter(state, title, &layout->pr_fd); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_FD), pr_fd); mode = extract_as_word(state, &layout->pr_mode); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_MODE), conv_cnote_filemode(mode, 0, buf, sizeof (buf))); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid, MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_MAJOR), pr_major, MSG_ORIG(MSG_CNOTE_T_PR_MINOR), pr_minor); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RMAJOR), pr_rmajor, MSG_ORIG(MSG_CNOTE_T_PR_RMINOR), pr_rminor); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_INO), pr_ino); PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_SIZE), pr_size, MSG_ORIG(MSG_CNOTE_T_PR_OFFSET), pr_offset); fileflags = extract_as_word(state, &layout->pr_fileflags); print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FILEFLAGS), conv_cnote_fileflags(fileflags, 0, buf, sizeof (buf))); PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_FDFLAGS), pr_fdflags); PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PATH), pr_path); indent_exit(state); } /* * Output information from priv_impl_info_t structure. */ static void dump_priv_impl_info(note_state_t *state, const char *title) { const sl_priv_impl_info_layout_t *layout; layout = state->ns_arch->priv_impl_info; indent_enter(state, title, &layout->priv_headersize); PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PRIV_HEADERSIZE), priv_headersize, MSG_ORIG(MSG_CNOTE_T_PRIV_FLAGS), priv_flags); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_NSETS), &layout->priv_nsets, SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PRIV_SETSIZE), &layout->priv_setsize, SL_FMT_NUM_HEX); print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_MAX), &layout->priv_max, SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PRIV_INFOSIZE), &layout->priv_infosize, SL_FMT_NUM_HEX); PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PRIV_GLOBALINFOSIZE), priv_globalinfosize); indent_exit(state); } /* * Dump information from an asrset_t array. This data * structure is specific to sparcv9, and does not appear * on any other platform. * * asrset_t is a simple array, defined in as * typedef int64_t asrset_t[16]; %asr16 - > %asr31 * * As such, we do not make use of the struct_layout facilities * for this routine. */ static void dump_asrset(note_state_t *state, const char *title) { static const sl_field_t ftemplate = { 0, sizeof (int64_t), 16, 0 }; sl_field_t fdesc1, fdesc2; sl_fmtbuf_t buf1, buf2; char index1[MAXNDXSIZE * 2], index2[MAXNDXSIZE * 2]; Word w, nelts; fdesc1 = fdesc2 = ftemplate; /* We expect 16 values, but will print whatever is actually there */ nelts = state->ns_len / ftemplate.slf_eltlen; if (nelts == 0) return; indent_enter(state, title, &fdesc1); for (w = 0; w < nelts; ) { (void) snprintf(index1, sizeof (index1), MSG_ORIG(MSG_FMT_ASRINDEX), w + 16); if (w == (nelts - 1)) { /* One last register is left */ dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT, state->ns_vcol - state->ns_indent, index1, fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1)); fdesc1.slf_offset += fdesc1.slf_eltlen; w++; continue; } /* There are at least 2 more registers left. Show 2 up */ (void) snprintf(index2, sizeof (index2), MSG_ORIG(MSG_FMT_ASRINDEX), w + 17); fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen; dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT, state->ns_vcol - state->ns_indent, index1, state->ns_t2col - state->ns_vcol, fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1), state->ns_v2col - state->ns_t2col, index2, fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2)); fdesc1.slf_offset += 2 * fdesc1.slf_eltlen; w += 2; } indent_exit(state); } static void dump_upanic(note_state_t *state, const char *title) { const sl_prupanic_layout_t *layout = state->ns_arch->prupanic; Conv_upanic_buf_t inv; Word w; indent_enter(state, title, &layout->pru_version); w = extract_as_word(state, &layout->pru_version); if (w != PRUPANIC_VERSION_1) { PRINT_DEC(MSG_INTL(MSG_NOTE_BAD_UPANIC_VER), pru_version); dump_hex_bytes(state->ns_data, state->ns_len, state->ns_indent, 4, 3); } else { PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PRU_VERSION), pru_version); w = extract_as_word(state, &layout->pru_flags); print_str(state, MSG_ORIG(MSG_CNOTE_T_PRU_FLAGS), conv_prupanic(w, 0, &inv)); if ((w & PRUPANIC_FLAG_MSG_VALID) != 0) { /* * We have a message that is _probably_ a text string, * but the interface allows for arbitrary data. The only * guarantee is that someone using this is probably up * to no good. As a result, we basically try to print * this as a string, but in the face of certain types of * data, we hex escape it. */ print_strbuf(state, MSG_ORIG(MSG_CNOTE_T_PRU_DATA), &layout->pru_data); } } } corenote_ret_t corenote(Half mach, int do_swap, Word type, const char *desc, Word descsz) { note_state_t state; /* * Get the per-architecture layout definition */ state.ns_mach = mach; state.ns_arch = sl_mach(state.ns_mach); if (sl_mach(state.ns_mach) == NULL) return (CORENOTE_R_BADARCH); state.ns_swap = do_swap; state.ns_indent = 4; state.ns_t2col = state.ns_v2col = 0; state.ns_data = desc; state.ns_len = descsz; switch (type) { case NT_PRSTATUS: /* prstatus_t */ state.ns_vcol = 26; state.ns_t2col = 46; state.ns_v2col = 60; dump_prstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSTATUS_T)); return (CORENOTE_R_OK); case NT_PRFPREG: /* prfpregset_t */ return (CORENOTE_R_OK_DUMP); case NT_PRPSINFO: /* prpsinfo_t */ state.ns_vcol = 20; state.ns_t2col = 41; state.ns_v2col = 54; dump_prpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPSINFO_T)); return (CORENOTE_R_OK); case NT_PRXREG: /* prxregset_t */ return (CORENOTE_R_OK_DUMP); case NT_PLATFORM: /* string from sysinfo(SI_PLATFORM) */ dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz)); return (CORENOTE_R_OK); case NT_AUXV: /* auxv_t array */ state.ns_vcol = 18; dump_auxv(&state, MSG_ORIG(MSG_CNOTE_DESC_AUXV_T)); return (CORENOTE_R_OK); case NT_GWINDOWS: /* gwindows_t SPARC only */ return (CORENOTE_R_OK_DUMP); case NT_ASRS: /* asrset_t sparcv9 only */ state.ns_vcol = 18; state.ns_t2col = 38; state.ns_v2col = 46; dump_asrset(&state, MSG_ORIG(MSG_CNOTE_DESC_ASRSET_T)); return (CORENOTE_R_OK); case NT_LDT: /* ssd array IA32 only */ return (CORENOTE_R_OK_DUMP); case NT_PSTATUS: /* pstatus_t */ state.ns_vcol = 22; state.ns_t2col = 42; state.ns_v2col = 54; dump_pstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PSTATUS_T)); return (CORENOTE_R_OK); case NT_PSINFO: /* psinfo_t */ state.ns_vcol = 25; state.ns_t2col = 45; state.ns_v2col = 58; dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T)); return (CORENOTE_R_OK); case NT_PRCRED: /* prcred_t */ state.ns_vcol = 20; state.ns_t2col = 34; state.ns_v2col = 44; dump_prcred(&state, MSG_ORIG(MSG_CNOTE_DESC_PRCRED_T)); return (CORENOTE_R_OK); case NT_UTSNAME: /* struct utsname */ state.ns_vcol = 18; dump_utsname(&state, MSG_ORIG(MSG_CNOTE_DESC_STRUCT_UTSNAME)); return (CORENOTE_R_OK); case NT_LWPSTATUS: /* lwpstatus_t */ state.ns_vcol = 24; state.ns_t2col = 44; state.ns_v2col = 54; dump_lwpstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSTATUS_T)); return (CORENOTE_R_OK); case NT_LWPSINFO: /* lwpsinfo_t */ state.ns_vcol = 22; state.ns_t2col = 42; state.ns_v2col = 54; dump_lwpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSINFO_T)); return (CORENOTE_R_OK); case NT_PRPRIV: /* prpriv_t */ state.ns_vcol = 21; state.ns_t2col = 34; state.ns_v2col = 38; dump_prpriv(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPRIV_T)); return (CORENOTE_R_OK); case NT_PRPRIVINFO: /* priv_impl_info_t */ state.ns_vcol = 29; state.ns_t2col = 41; state.ns_v2col = 56; dump_priv_impl_info(&state, MSG_ORIG(MSG_CNOTE_DESC_PRIV_IMPL_INFO_T)); return (CORENOTE_R_OK); case NT_CONTENT: /* core_content_t */ if (sizeof (core_content_t) > descsz) return (CORENOTE_R_BADDATA); { static sl_field_t fdesc = { 0, 8, 0, 0 }; Conv_cnote_cc_content_buf_t conv_buf; core_content_t content; state.ns_vcol = 8; indent_enter(&state, MSG_ORIG(MSG_CNOTE_DESC_CORE_CONTENT_T), &fdesc); content = extract_as_lword(&state, &fdesc); print_str(&state, MSG_ORIG(MSG_STR_EMPTY), conv_cnote_cc_content(content, 0, &conv_buf)); indent_exit(&state); } return (CORENOTE_R_OK); case NT_ZONENAME: /* string from getzonenamebyid(3C) */ dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz)); return (CORENOTE_R_OK); case NT_FDINFO: state.ns_vcol = 22; state.ns_t2col = 41; state.ns_v2col = 54; dump_prfdinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRFDINFO_T)); return (CORENOTE_R_OK); case NT_SPYMASTER: state.ns_vcol = 25; state.ns_t2col = 45; state.ns_v2col = 58; dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T)); return (CORENOTE_R_OK); case NT_SECFLAGS: state.ns_vcol = 23; state.ns_t2col = 41; state.ns_v2col = 54; dump_secflags(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSECFLAGS_T)); return (CORENOTE_R_OK); case NT_LWPNAME: state.ns_vcol = 20; dump_lwpname(&state, MSG_ORIG(MSG_CNOTE_DESC_PRLWPNAME_T)); return (CORENOTE_R_OK); case NT_UPANIC: state.ns_vcol = 23; dump_upanic(&state, MSG_ORIG(MSG_CNOTE_DESC_PRUPANIC_T)); return (CORENOTE_R_OK); } return (CORENOTE_R_BADTYPE); }