xref: /onnv-gate/usr/src/cmd/sgs/elfdump/common/corenote.c (revision 7122:51f3b40bdc33)
16635Sab196087 /*
26635Sab196087  * CDDL HEADER START
36635Sab196087  *
46635Sab196087  * The contents of this file are subject to the terms of the
56635Sab196087  * Common Development and Distribution License (the "License").
66635Sab196087  * You may not use this file except in compliance with the License.
76635Sab196087  *
86635Sab196087  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96635Sab196087  * or http://www.opensolaris.org/os/licensing.
106635Sab196087  * See the License for the specific language governing permissions
116635Sab196087  * and limitations under the License.
126635Sab196087  *
136635Sab196087  * When distributing Covered Code, include this CDDL HEADER in each
146635Sab196087  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156635Sab196087  * If applicable, add the following below this CDDL HEADER, with the
166635Sab196087  * fields enclosed by brackets "[]" replaced with your own identifying
176635Sab196087  * information: Portions Copyright [yyyy] [name of copyright owner]
186635Sab196087  *
196635Sab196087  * CDDL HEADER END
206635Sab196087  */
216635Sab196087 
226635Sab196087 /*
236635Sab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
246635Sab196087  * Use is subject to license terms.
256635Sab196087  */
266635Sab196087 #pragma ident	"%Z%%M%	%I%	%E% SMI"
276635Sab196087 
286635Sab196087 #include <stdlib.h>
296635Sab196087 #include <stdio.h>
306635Sab196087 #include <string.h>
316635Sab196087 #include <sys/types.h>
326635Sab196087 #include <unistd.h>
336635Sab196087 #include <sys/corectl.h>
346635Sab196087 #include <msg.h>
356635Sab196087 #include <_elfdump.h>
366635Sab196087 #include <struct_layout.h>
376635Sab196087 #include <conv.h>
386635Sab196087 
396635Sab196087 
406635Sab196087 /*
416635Sab196087  * This module contains the code that displays data from the note
426635Sab196087  * sections found in Solaris core files. The format of these
436635Sab196087  * note sections are described in the core(4) manpage.
446635Sab196087  */
456635Sab196087 
466635Sab196087 
476635Sab196087 
486635Sab196087 
496635Sab196087 /*
506635Sab196087  * Much of the code in this file uses the "%*s" format to set
516635Sab196087  * the left margin indentation. This macro combines the indent
526635Sab196087  * integer argument and the NULL string that follows it.
536635Sab196087  */
546635Sab196087 #define	INDENT state->ns_indent, MSG_ORIG(MSG_STR_EMPTY)
556635Sab196087 
566635Sab196087 /*
576635Sab196087  * Indent unit, used for each nesting
586635Sab196087  */
596635Sab196087 #define	INDENT_STEP 4
606635Sab196087 
616635Sab196087 /*
626635Sab196087  * The PRINT_ macros are convenience wrappers on print_num(),
636635Sab196087  * print_subtype(), and print_strbuf(). They reduce code
646635Sab196087  * clutter by hiding the boilerplate arguments.
656635Sab196087  *
666635Sab196087  * Assumptions:
676635Sab196087  *	- A variable named "layout" exists in the compilation
686635Sab196087  *		environment, referencing the layout information for the
696635Sab196087  *		current type.
706635Sab196087  *	- The variable "state" references the current note state.
716635Sab196087  */
726635Sab196087 #define	PRINT_DEC(_title, _field) \
736635Sab196087 	print_num(state, _title, &layout->_field, SL_FMT_NUM_DEC)
746635Sab196087 #define	PRINT_DEC_2UP(_title1, _field1, _title2, _field2) \
756635Sab196087 	print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_DEC, \
766635Sab196087 	    _title2, &layout->_field2, SL_FMT_NUM_DEC)
776635Sab196087 #define	PRINT_HEX(_title, _field) \
786635Sab196087 	print_num(state, _title, &layout->_field, SL_FMT_NUM_HEX)
796635Sab196087 #define	PRINT_HEX_2UP(_title1, _field1, _title2, _field2) \
806635Sab196087 	print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_HEX, \
816635Sab196087 	    _title2, &layout->_field2, SL_FMT_NUM_HEX)
826635Sab196087 #define	PRINT_ZHEX(_title, _field) \
836635Sab196087 	print_num(state, _title, &layout->_field, SL_FMT_NUM_ZHEX)
846635Sab196087 #define	PRINT_ZHEX_2UP(_title1, _field1, _title2, _field2) \
856635Sab196087 	print_num_2up(state, _title1, &layout->_field1, SL_FMT_NUM_ZHEX, \
866635Sab196087 	    _title2, &layout->_field2, SL_FMT_NUM_ZHEX)
876635Sab196087 #define	PRINT_SUBTYPE(_title, _field, _func) \
886635Sab196087 	print_subtype(state, _title, &layout->_field, _func)
896635Sab196087 #define	PRINT_STRBUF(_title, _field) \
906635Sab196087 	print_strbuf(state, _title, &layout->_field)
916635Sab196087 
926635Sab196087 
936635Sab196087 
946635Sab196087 /*
956635Sab196087  * Structure used to maintain state data for a core note, or a subregion
966635Sab196087  * (sub-struct) of a core note. These values would otherwise need to be
976635Sab196087  * passed to nearly every routine.
986635Sab196087  */
996635Sab196087 typedef struct {
1006635Sab196087 	Half		ns_mach;	/* ELF machine type of core file */
1016635Sab196087 	const sl_arch_layout_t *ns_arch; /* structure layout def for mach */
1026635Sab196087 	int		ns_swap;	/* True if byte swapping is needed */
1036635Sab196087 	int		ns_indent;	/* Left margin indentation */
1046635Sab196087 	int		ns_vcol;	/* Column where value starts */
1056635Sab196087 	int		ns_t2col;	/* Column where 2up title starts */
1066635Sab196087 	int		ns_v2col;	/* Column where 2up value starts */
1076635Sab196087 	const char	*ns_data;	/* Pointer to struct data area */
1086635Sab196087 	Word		ns_len;		/* Length of struct data area */
1096635Sab196087 } note_state_t;
1106635Sab196087 
1116635Sab196087 /*
1126635Sab196087  * Standard signature for a dump function used to process a note
1136635Sab196087  * or a sub-structure within a note.
1146635Sab196087  */
1156635Sab196087 typedef void (* dump_func_t)(note_state_t *state, const char *title);
1166635Sab196087 
1176635Sab196087 
1186635Sab196087 
1196635Sab196087 
1206635Sab196087 
1216635Sab196087 
1226635Sab196087 /*
1236635Sab196087  * Some core notes contain string buffers of fixed size
1246635Sab196087  * that are expected to contain NULL terminated strings.
1256635Sab196087  * If the NULL is there, we can print these strings directly.
1266635Sab196087  * However, the potential exists for a corrupt file to have
1276635Sab196087  * a non-terminated buffer. This routine examines the given
1286635Sab196087  * string, and if the string is terminated, the string itself
1296635Sab196087  * is returned. Otherwise, it is copied to a static buffer,
1306635Sab196087  * and a pointer to the buffer is returned.
1316635Sab196087  */
1326635Sab196087 static const char *
safe_str(const char * str,size_t n)1336635Sab196087 safe_str(const char *str, size_t n)
1346635Sab196087 {
1356635Sab196087 	static char	buf[512];
1366635Sab196087 	char		*s;
1376635Sab196087 	size_t		i;
1386635Sab196087 
1396635Sab196087 	if (n == 0)
1406635Sab196087 		return (MSG_ORIG(MSG_STR_EMPTY));
1416635Sab196087 
1426635Sab196087 	for (i = 0; i < n; i++)
1436635Sab196087 		if (str[i] == '\0')
1446635Sab196087 			return (str);
1456635Sab196087 
1466635Sab196087 	i = (n >= sizeof (buf)) ? (sizeof (buf) - 4) : (n - 1);
1476635Sab196087 	(void) memcpy(buf, str, i);
1486635Sab196087 	s = buf + i;
1496635Sab196087 	if (n >= sizeof (buf)) {
1506635Sab196087 		*s++ = '.';
1516635Sab196087 		*s++ = '.';
1526635Sab196087 		*s++ = '.';
1536635Sab196087 	}
1546635Sab196087 	*s = '\0';
1556635Sab196087 	return (buf);
1566635Sab196087 }
1576635Sab196087 
1586635Sab196087 /*
1596635Sab196087  * Convenience wrappers on top of the corresponding sl_XXX() functions.
1606635Sab196087  */
1616635Sab196087 static Word
extract_as_word(note_state_t * state,const sl_field_t * fdesc)1626635Sab196087 extract_as_word(note_state_t *state, const sl_field_t *fdesc)
1636635Sab196087 {
1646635Sab196087 	return (sl_extract_as_word(state->ns_data, state->ns_swap, fdesc));
1656635Sab196087 }
1666635Sab196087 static Word
extract_as_lword(note_state_t * state,const sl_field_t * fdesc)1676635Sab196087 extract_as_lword(note_state_t *state, const sl_field_t *fdesc)
1686635Sab196087 {
1696635Sab196087 	return (sl_extract_as_lword(state->ns_data, state->ns_swap, fdesc));
1706635Sab196087 }
1716635Sab196087 static int
extract_as_sword(note_state_t * state,const sl_field_t * fdesc)1726635Sab196087 extract_as_sword(note_state_t *state, const sl_field_t *fdesc)
1736635Sab196087 {
1746635Sab196087 	return (sl_extract_as_sword(state->ns_data, state->ns_swap, fdesc));
1756635Sab196087 }
1766635Sab196087 static const char *
fmt_num(note_state_t * state,const sl_field_t * fdesc,sl_fmt_num_t fmt_type,sl_fmtbuf_t buf)1776635Sab196087 fmt_num(note_state_t *state, const sl_field_t *fdesc,
1786635Sab196087     sl_fmt_num_t fmt_type, sl_fmtbuf_t buf)
1796635Sab196087 {
1806635Sab196087 	return (sl_fmt_num(state->ns_data, state->ns_swap, fdesc,
1816635Sab196087 	    fmt_type, buf));
1826635Sab196087 }
1836635Sab196087 
1846635Sab196087 
1856635Sab196087 /*
1866635Sab196087  * Return true of the data for the specified field is available.
1876635Sab196087  */
1886635Sab196087 inline static int
data_present(note_state_t * state,const sl_field_t * fdesc)1896635Sab196087 data_present(note_state_t *state, const sl_field_t *fdesc)
1906635Sab196087 {
1916635Sab196087 	return ((fdesc->slf_offset + fdesc->slf_eltlen) <= state->ns_len);
1926635Sab196087 }
1936635Sab196087 
1946635Sab196087 /*
1956635Sab196087  * indent_enter/exit are used to start/end output for a subitem.
1966635Sab196087  * On entry, a title is output, and the indentation level is raised
1976635Sab196087  * by one unit. On exit, the indentation level is restrored to its
1986635Sab196087  * previous value.
1996635Sab196087  */
2006635Sab196087 static void
indent_enter(note_state_t * state,const char * title,const sl_field_t * first_fdesc)2016635Sab196087 indent_enter(note_state_t *state, const char *title,
2026635Sab196087     const sl_field_t *first_fdesc)
2036635Sab196087 {
2046635Sab196087 	/*
2056635Sab196087 	 * If the first field offset and extent fall past the end of the
2066635Sab196087 	 * available data, then return without printing a title. That note
2076635Sab196087 	 * is from an older core file that doesn't have all the fields
2086635Sab196087 	 * that we know about.
2096635Sab196087 	 */
2106635Sab196087 	if (data_present(state, first_fdesc))
2116635Sab196087 		dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_TITLE), INDENT, title);
2126635Sab196087 
2136635Sab196087 	state->ns_indent += INDENT_STEP;
2146635Sab196087 }
2156635Sab196087 static void
indent_exit(note_state_t * state)2166635Sab196087 indent_exit(note_state_t *state)
2176635Sab196087 {
2186635Sab196087 	state->ns_indent -= INDENT_STEP;
2196635Sab196087 }
2206635Sab196087 
2216635Sab196087 
2226635Sab196087 /*
2236635Sab196087  * print_num outputs a field on one line, in the format:
2246635Sab196087  *
2256635Sab196087  *	title: value
2266635Sab196087  */
2276635Sab196087 static void
print_num(note_state_t * state,const char * title,const sl_field_t * fdesc,sl_fmt_num_t fmt_type)2286635Sab196087 print_num(note_state_t *state, const char *title,
2296635Sab196087     const sl_field_t *fdesc, sl_fmt_num_t fmt_type)
2306635Sab196087 {
2316635Sab196087 	sl_fmtbuf_t	buf;
2326635Sab196087 
2336635Sab196087 	/*
2346635Sab196087 	 * If the field offset and extent fall past the end of the
2356635Sab196087 	 * available data, then return without doing anything. That note
2366635Sab196087 	 * is from an older core file that doesn't have all the fields
2376635Sab196087 	 * that we know about.
2386635Sab196087 	 */
2396635Sab196087 	if (!data_present(state, fdesc))
2406635Sab196087 		return;
2416635Sab196087 
2426635Sab196087 	dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT,
2436635Sab196087 	    state->ns_vcol - state->ns_indent, title,
2446635Sab196087 	    fmt_num(state, fdesc, fmt_type, buf));
2456635Sab196087 }
2466635Sab196087 
2476635Sab196087 /*
2486635Sab196087  * print_num_2up outputs two fields on one line, in the format:
2496635Sab196087  *
2506635Sab196087  *	title1: value1	title2: value2
2516635Sab196087  */
2526635Sab196087 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)2536635Sab196087 print_num_2up(note_state_t *state, const char *title1,
2546635Sab196087     const sl_field_t *fdesc1, sl_fmt_num_t fmt_type1, const char *title2,
2556635Sab196087     const sl_field_t *fdesc2, sl_fmt_num_t fmt_type2)
2566635Sab196087 {
2576635Sab196087 	sl_fmtbuf_t	buf1, buf2;
2586635Sab196087 
2596635Sab196087 	/*
2606635Sab196087 	 * If the field offset and extent fall past the end of the
2616635Sab196087 	 * available data, then return without doing anything. That note
2626635Sab196087 	 * is from an older core file that doesn't have all the fields
2636635Sab196087 	 * that we know about.
2646635Sab196087 	 */
2656635Sab196087 	if (!(data_present(state, fdesc1) &&
2666635Sab196087 	    data_present(state, fdesc2)))
2676635Sab196087 		return;
2686635Sab196087 
2696635Sab196087 	dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT,
2706635Sab196087 	    state->ns_vcol - state->ns_indent, title1,
2716635Sab196087 	    state->ns_t2col - state->ns_vcol,
2726635Sab196087 	    fmt_num(state, fdesc1, fmt_type1, buf1),
2736635Sab196087 	    state->ns_v2col - state->ns_t2col, title2,
2746635Sab196087 	    fmt_num(state, fdesc2, fmt_type2, buf2));
2756635Sab196087 }
2766635Sab196087 
2776635Sab196087 /*
2786635Sab196087  * print_strbuf outputs a fixed sized character buffer field
2796635Sab196087  * on one line, in the format:
2806635Sab196087  *
2816635Sab196087  *	title: value
2826635Sab196087  */
2836635Sab196087 static void
print_strbuf(note_state_t * state,const char * title,const sl_field_t * fdesc)2846635Sab196087 print_strbuf(note_state_t *state, const char *title,
2856635Sab196087     const sl_field_t *fdesc)
2866635Sab196087 {
2876635Sab196087 	Word	n;
2886635Sab196087 
2896635Sab196087 	/*
2906635Sab196087 	 * If we are past the end of the data area, then return
2916635Sab196087 	 * without doing anything. That note is from an older core
2926635Sab196087 	 * file that doesn't have all the fields that we know about.
2936635Sab196087 	 *
2946635Sab196087 	 * Note that we are willing to accept a partial buffer,
2956635Sab196087 	 * so we don't use data_present() for this test.
2966635Sab196087 	 */
2976635Sab196087 	if (fdesc->slf_offset >= state->ns_len)
2986635Sab196087 		return;
2996635Sab196087 
3006635Sab196087 	/*
3016635Sab196087 	 * We expect the full buffer to be present, but if there
3026635Sab196087 	 * is less than that, we will still proceed. The use of safe_str()
3036635Sab196087 	 * protects us from the effect of printing garbage data.
3046635Sab196087 	 */
3056635Sab196087 	n = state->ns_len - fdesc->slf_offset;
3066635Sab196087 	if (n > fdesc->slf_nelts)
3076635Sab196087 		n = fdesc->slf_nelts;
3086635Sab196087 
3096635Sab196087 	dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT,
3106635Sab196087 	    state->ns_vcol - state->ns_indent,
3116635Sab196087 	    title, safe_str(fdesc->slf_offset + state->ns_data, n));
3126635Sab196087 }
3136635Sab196087 
3146635Sab196087 /*
3156635Sab196087  * print_str outputs an arbitrary string value item
3166635Sab196087  * on one line, in the format:
3176635Sab196087  *
3186635Sab196087  *	title: str
3196635Sab196087  */
3206635Sab196087 static void
print_str(note_state_t * state,const char * title,const char * str)3216635Sab196087 print_str(note_state_t *state, const char *title, const char *str)
3226635Sab196087 {
3236635Sab196087 	dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE), INDENT,
3246635Sab196087 	    state->ns_vcol - state->ns_indent, title, str);
3256635Sab196087 }
3266635Sab196087 
3276635Sab196087 /*
3286635Sab196087  * Used when one dump function needs to call another dump function
3296635Sab196087  * in order to display a subitem. This routine constructs a state
3306635Sab196087  * block for the sub-region, and then calls the dump function with it.
3316635Sab196087  * This limits the amount of data visible to the sub-function to that
3326635Sab196087  * for the sub-item.
3336635Sab196087  */
3346635Sab196087 static void
print_subtype(note_state_t * state,const char * title,const sl_field_t * fdesc,dump_func_t dump_func)3356635Sab196087 print_subtype(note_state_t *state, const char *title,
3366635Sab196087     const sl_field_t *fdesc, dump_func_t dump_func)
3376635Sab196087 {
3386635Sab196087 	note_state_t sub_state;
3396635Sab196087 
3406635Sab196087 	/*
3416635Sab196087 	 * If there is no data for the sub-item, return immediately.
3426635Sab196087 	 * Partial data is left to the dump function to handle,
3436635Sab196087 	 * as that can be a sign of an older core file with less data,
3446635Sab196087 	 * which can still be interpreted.
3456635Sab196087 	 */
3466635Sab196087 	if (fdesc->slf_offset >= state->ns_len)
3476635Sab196087 		return;
3486635Sab196087 
3496635Sab196087 	/*
3506635Sab196087 	 * Construct a state block that reflects the sub-item
3516635Sab196087 	 */
3526635Sab196087 	sub_state = *state;
3536635Sab196087 	sub_state.ns_data += fdesc->slf_offset;
3546635Sab196087 	sub_state.ns_len -= fdesc->slf_offset;
3556635Sab196087 	if (sub_state.ns_len > fdesc->slf_eltlen)
3566635Sab196087 		sub_state.ns_len = fdesc->slf_eltlen;
3576635Sab196087 
3586635Sab196087 	(* dump_func)(&sub_state, title);
3596635Sab196087 }
3606635Sab196087 
3616635Sab196087 
3626635Sab196087 /*
3636635Sab196087  * Output a sequence of array elements, giving each
3646635Sab196087  * element an index, in the format:
3656635Sab196087  *
3666635Sab196087  *	[ndx] value
3676635Sab196087  *
3686635Sab196087  * entry:
3696635Sab196087  *	state - Current state
3706635Sab196087  *	base_desc - Field descriptor for 1st element of array
3716635Sab196087  *	nelts - # of array elements to display
3726635Sab196087  *	check_nelts - If True (1), nelts is clipped to fdesc->slf_nelts.
3736635Sab196087  *		If False (1), nelts is not clipped.
3746635Sab196087  *	title - Name of array
3756635Sab196087  */
3766635Sab196087 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)3776635Sab196087 print_array(note_state_t *state, const sl_field_t *base_desc,
3786635Sab196087     sl_fmt_num_t fmt_type, int nelts, int check_nelts, const char *title)
3796635Sab196087 {
3806635Sab196087 	char		index1[MAXNDXSIZE], index2[MAXNDXSIZE];
3816635Sab196087 	int		i;
3826635Sab196087 	sl_field_t	fdesc1, fdesc2;
3836635Sab196087 
3846635Sab196087 	if (check_nelts && (check_nelts > base_desc->slf_nelts))
3856635Sab196087 		nelts = base_desc->slf_nelts;
3866635Sab196087 	if (nelts == 0)
3876635Sab196087 		return;
3886635Sab196087 
3896635Sab196087 	indent_enter(state, title, base_desc);
3906635Sab196087 
3916635Sab196087 	fdesc1 = fdesc2 = *base_desc;
3926635Sab196087 	for (i = 0; i < nelts; ) {
3936635Sab196087 		if (i == (nelts - 1)) {
3946635Sab196087 			/*  One final value is left  */
3956635Sab196087 			if (!data_present(state, &fdesc1))
3966635Sab196087 				break;
3976635Sab196087 			(void) snprintf(index1, sizeof (index1),
3986635Sab196087 			    MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i));
3996635Sab196087 			print_num(state, index1, &fdesc1, fmt_type);
4006635Sab196087 			fdesc1.slf_offset += fdesc1.slf_eltlen;
4016635Sab196087 			i++;
4026635Sab196087 			continue;
4036635Sab196087 		}
4046635Sab196087 
4056635Sab196087 		/* There are at least 2 items left. Show 2 up. */
4066635Sab196087 		fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen;
4076635Sab196087 		if (!(data_present(state, &fdesc1) &&
4086635Sab196087 		    data_present(state, &fdesc2)))
4096635Sab196087 			break;
4106635Sab196087 		(void) snprintf(index1, sizeof (index1),
4116635Sab196087 		    MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i));
4126635Sab196087 		(void) snprintf(index2, sizeof (index2),
4136635Sab196087 		    MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(i + 1));
4146635Sab196087 		print_num_2up(state, index1, &fdesc1, fmt_type,
4156635Sab196087 		    index2, &fdesc2, fmt_type);
4166635Sab196087 		fdesc1.slf_offset += 2 * fdesc1.slf_eltlen;
4176635Sab196087 		i += 2;
4186635Sab196087 	}
4196635Sab196087 
4206635Sab196087 	indent_exit(state);
4216635Sab196087 }
4226635Sab196087 
4236635Sab196087 
4246635Sab196087 /*
4256635Sab196087  * Output information from auxv_t structure.
4266635Sab196087  */
4276635Sab196087 static void
dump_auxv(note_state_t * state,const char * title)4286635Sab196087 dump_auxv(note_state_t *state, const char *title)
4296635Sab196087 {
4306635Sab196087 	const sl_auxv_layout_t	*layout = state->ns_arch->auxv;
4316635Sab196087 	union {
4326635Sab196087 		Conv_cap_val_hw1_buf_t		hw1;
4336635Sab196087 		Conv_cnote_auxv_af_buf_t	auxv_af;
4346635Sab196087 		Conv_ehdr_flags_buf_t		ehdr_flags;
4356635Sab196087 		Conv_inv_buf_t			inv;
4366635Sab196087 	} conv_buf;
4376635Sab196087 	sl_fmtbuf_t	buf;
4386635Sab196087 	int		ndx, ndx_start;
4396635Sab196087 	Word		sizeof_auxv;
4406635Sab196087 
4416635Sab196087 	sizeof_auxv = layout->sizeof_struct.slf_eltlen;
4426635Sab196087 
4436635Sab196087 	indent_enter(state, title, &layout->sizeof_struct);
4446635Sab196087 
4456635Sab196087 	/*
4466635Sab196087 	 * Immediate indent_exit() restores the indent level to
4476635Sab196087 	 * that of the title. We include indentation as part of
4486635Sab196087 	 * the index string, which is right justified, and don't
4496635Sab196087 	 * want the usual indentation spacing.
4506635Sab196087 	 */
4516635Sab196087 	indent_exit(state);
4526635Sab196087 
4536635Sab196087 	ndx = 0;
4546635Sab196087 	while (state->ns_len > sizeof_auxv) {
4556635Sab196087 		char		index[(MAXNDXSIZE * 2) + 1];
4566635Sab196087 		sl_fmt_num_t	num_fmt = SL_FMT_NUM_ZHEX;
4576635Sab196087 		const char	*vstr = NULL;
4586635Sab196087 		Word		w;
4596635Sab196087 		int		type;
4606635Sab196087 		sl_field_t	a_type_next;
4616635Sab196087 
4626635Sab196087 		type = extract_as_word(state, &layout->a_type);
4636635Sab196087 		ndx_start = ndx;
4646635Sab196087 		switch (type) {
4656635Sab196087 		case AT_NULL:
4666635Sab196087 			a_type_next = layout->a_type;
4676635Sab196087 			a_type_next.slf_offset += sizeof_auxv;
4686635Sab196087 			while ((state->ns_len - sizeof_auxv) >= sizeof_auxv) {
4696635Sab196087 				type = extract_as_word(state, &a_type_next);
4706635Sab196087 				if (type != AT_NULL)
4716635Sab196087 					break;
4726635Sab196087 				ndx++;
4736635Sab196087 				state->ns_data += sizeof_auxv;
4746635Sab196087 				state->ns_len -= sizeof_auxv;
4756635Sab196087 			}
4766635Sab196087 			num_fmt = SL_FMT_NUM_HEX;
4776635Sab196087 			break;
4786635Sab196087 
4796635Sab196087 
4806635Sab196087 
4816635Sab196087 		case AT_IGNORE:
4826635Sab196087 		case AT_SUN_IFLUSH:
4836635Sab196087 			num_fmt = SL_FMT_NUM_HEX;
4846635Sab196087 			break;
4856635Sab196087 
4866635Sab196087 		case AT_EXECFD:
4876635Sab196087 		case AT_PHENT:
4886635Sab196087 		case AT_PHNUM:
4896635Sab196087 		case AT_PAGESZ:
4906635Sab196087 		case AT_SUN_UID:
4916635Sab196087 		case AT_SUN_RUID:
4926635Sab196087 		case AT_SUN_GID:
4936635Sab196087 		case AT_SUN_RGID:
4946635Sab196087 		case AT_SUN_LPAGESZ:
4956635Sab196087 			num_fmt = SL_FMT_NUM_DEC;
4966635Sab196087 			break;
4976635Sab196087 
4986635Sab196087 		case AT_FLAGS:	/* processor flags */
4996635Sab196087 			w = extract_as_word(state, &layout->a_val);
5006635Sab196087 			vstr = conv_ehdr_flags(state->ns_mach, w,
5016635Sab196087 			    0, &conv_buf.ehdr_flags);
5026635Sab196087 			break;
5036635Sab196087 
5046635Sab196087 		case AT_SUN_HWCAP:
5056635Sab196087 			w = extract_as_word(state, &layout->a_val);
5066635Sab196087 			vstr = conv_cap_val_hw1(w, state->ns_mach,
5076635Sab196087 			    0, &conv_buf.hw1);
5086635Sab196087 			/*
5096635Sab196087 			 * conv_cap_val_hw1() produces output like:
5106635Sab196087 			 *
5116635Sab196087 			 *	0xfff [ flg1 flg2 0xff]
5126635Sab196087 			 *
5136635Sab196087 			 * where the first hex value is the complete value,
5146635Sab196087 			 * and the second is the leftover bits. We only
5156635Sab196087 			 * want the part in brackets, and failing that,
5166635Sab196087 			 * would rather fall back to formatting the full
5176635Sab196087 			 * value ourselves.
5186635Sab196087 			 */
5196635Sab196087 			while ((*vstr != '\0') && (*vstr != '['))
5206635Sab196087 				vstr++;
5216635Sab196087 			if (*vstr != '[')
5226635Sab196087 				vstr = NULL;
5236635Sab196087 			num_fmt = SL_FMT_NUM_HEX;
5246635Sab196087 			break;
5256635Sab196087 
5266635Sab196087 
5276635Sab196087 		case AT_SUN_AUXFLAGS:
5286635Sab196087 			w = extract_as_word(state, &layout->a_val);
5296635Sab196087 			vstr = conv_cnote_auxv_af(w, 0, &conv_buf.auxv_af);
5306635Sab196087 			num_fmt = SL_FMT_NUM_HEX;
5316635Sab196087 			break;
5326635Sab196087 		}
5336635Sab196087 
5346635Sab196087 		if (ndx == ndx_start)
5356635Sab196087 			(void) snprintf(index, sizeof (index),
5366635Sab196087 			    MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(ndx));
5376635Sab196087 		else
5386635Sab196087 			(void) snprintf(index, sizeof (index),
5396635Sab196087 			    MSG_ORIG(MSG_FMT_INDEXRNG),
5406635Sab196087 			    EC_WORD(ndx_start), EC_WORD(ndx));
5416635Sab196087 
5426635Sab196087 		if (vstr == NULL)
5436635Sab196087 			vstr = fmt_num(state, &layout->a_val, num_fmt, buf);
5446635Sab196087 		dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_AUXVLINE), INDENT, index,
5456635Sab196087 		    state->ns_vcol - state->ns_indent,
5466635Sab196087 		    conv_cnote_auxv_type(type, CONV_FMT_DECIMAL,
5476635Sab196087 		    &conv_buf.inv), vstr);
5486635Sab196087 
5496635Sab196087 		state->ns_data += sizeof_auxv;
5506635Sab196087 		state->ns_len -= sizeof_auxv;
5516635Sab196087 		ndx++;
5526635Sab196087 	}
5536635Sab196087 }
5546635Sab196087 
5556635Sab196087 
5566635Sab196087 /*
5576635Sab196087  * Output information from fltset_t structure.
5586635Sab196087  */
5596635Sab196087 static void
dump_fltset(note_state_t * state,const char * title)5606635Sab196087 dump_fltset(note_state_t *state, const char *title)
5616635Sab196087 {
5626635Sab196087 #define	NELTS 4
5636635Sab196087 
5646635Sab196087 	const sl_fltset_layout_t	*layout = state->ns_arch->fltset;
5656635Sab196087 	Conv_cnote_fltset_buf_t	buf;
5666635Sab196087 	sl_field_t		fdesc;
5676635Sab196087 	uint32_t		mask[NELTS];
5686635Sab196087 	int			i, nelts;
5696635Sab196087 
5706635Sab196087 	if (!data_present(state, &layout->sizeof_struct))
5716635Sab196087 		return;
5726635Sab196087 
5736635Sab196087 	fdesc = layout->word;
5746635Sab196087 	nelts = fdesc.slf_nelts;
5756635Sab196087 	if (nelts > NELTS)	/* Type has grown? Show what we understand */
5766635Sab196087 		nelts = NELTS;
5776635Sab196087 	for (i = 0; i < nelts; i++) {
5786635Sab196087 		mask[i] = extract_as_word(state, &fdesc);
5796635Sab196087 		fdesc.slf_offset += fdesc.slf_eltlen;
5806635Sab196087 	}
5816635Sab196087 
5826635Sab196087 	print_str(state, title, conv_cnote_fltset(mask, nelts, 0, &buf));
5836635Sab196087 
5846635Sab196087 #undef NELTS
5856635Sab196087 }
5866635Sab196087 
5876635Sab196087 
5886635Sab196087 /*
5896635Sab196087  * Output information from sigset_t structure.
5906635Sab196087  */
5916635Sab196087 static void
dump_sigset(note_state_t * state,const char * title)5926635Sab196087 dump_sigset(note_state_t *state, const char *title)
5936635Sab196087 {
5946635Sab196087 #define	NELTS 4
5956635Sab196087 
5966635Sab196087 	const sl_sigset_layout_t	*layout = state->ns_arch->sigset;
5976635Sab196087 	Conv_cnote_sigset_buf_t	buf;
5986635Sab196087 	sl_field_t		fdesc;
5996635Sab196087 	uint32_t		mask[NELTS];
6006635Sab196087 	int			i, nelts;
6016635Sab196087 
6026635Sab196087 	if (!data_present(state, &layout->sizeof_struct))
6036635Sab196087 		return;
6046635Sab196087 
6056635Sab196087 	fdesc = layout->sigbits;
6066635Sab196087 	nelts = fdesc.slf_nelts;
6076635Sab196087 	if (nelts > NELTS)	/* Type has grown? Show what we understand */
6086635Sab196087 		nelts = NELTS;
6096635Sab196087 	for (i = 0; i < nelts; i++) {
6106635Sab196087 		mask[i] = extract_as_word(state, &fdesc);
6116635Sab196087 		fdesc.slf_offset += fdesc.slf_eltlen;
6126635Sab196087 	}
6136635Sab196087 
6146635Sab196087 	print_str(state, title, conv_cnote_sigset(mask, nelts, 0, &buf));
6156635Sab196087 
6166635Sab196087 #undef NELTS
6176635Sab196087 }
6186635Sab196087 
6196635Sab196087 
6206635Sab196087 /*
6216635Sab196087  * Output information from sigaction structure.
6226635Sab196087  */
6236635Sab196087 static void
dump_sigaction(note_state_t * state,const char * title)6246635Sab196087 dump_sigaction(note_state_t *state, const char *title)
6256635Sab196087 {
6266635Sab196087 	const sl_sigaction_layout_t	*layout = state->ns_arch->sigaction;
6276635Sab196087 	Conv_cnote_sa_flags_buf_t	conv_buf;
6286635Sab196087 	Word	w;
6296635Sab196087 
6306635Sab196087 	indent_enter(state, title, &layout->sa_flags);
6316635Sab196087 
6326635Sab196087 	if (data_present(state, &layout->sa_flags)) {
6336635Sab196087 		w = extract_as_word(state, &layout->sa_flags);
6346635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_SA_FLAGS),
6356635Sab196087 		    conv_cnote_sa_flags(w, 0, &conv_buf));
6366635Sab196087 	}
6376635Sab196087 
6386635Sab196087 	PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_SA_HANDLER), sa_hand,
6396635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_SA_SIGACTION), sa_sigact);
6406635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_SA_MASK), sa_mask, dump_sigset);
6416635Sab196087 
6426635Sab196087 	indent_exit(state);
6436635Sab196087 }
6446635Sab196087 
6456635Sab196087 
6466635Sab196087 /*
6476635Sab196087  * Output information from siginfo structure.
6486635Sab196087  */
6496635Sab196087 static void
dump_siginfo(note_state_t * state,const char * title)6506635Sab196087 dump_siginfo(note_state_t *state, const char *title)
6516635Sab196087 {
6526635Sab196087 	const sl_siginfo_layout_t	*layout = state->ns_arch->siginfo;
6536635Sab196087 	Conv_inv_buf_t	inv_buf;
6546635Sab196087 	Word		w;
6556635Sab196087 	int		v_si_code, v_si_signo;
6566635Sab196087 
657*7122Sab196087 	if (!data_present(state, &layout->sizeof_struct))
6586635Sab196087 		return;
6596635Sab196087 
6606635Sab196087 	indent_enter(state, title, &layout->f_si_signo);
6616635Sab196087 
6626635Sab196087 	v_si_signo = extract_as_sword(state, &layout->f_si_signo);
6636635Sab196087 	print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_SIGNO),
6646635Sab196087 	    conv_cnote_signal(v_si_signo, CONV_FMT_DECIMAL, &inv_buf));
6656635Sab196087 
6666635Sab196087 	w = extract_as_word(state, &layout->f_si_errno);
6676635Sab196087 	print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_ERRNO),
6686635Sab196087 	    conv_cnote_errno(w, CONV_FMT_DECIMAL, &inv_buf));
6696635Sab196087 
6706635Sab196087 	v_si_code = extract_as_sword(state, &layout->f_si_code);
6716635Sab196087 	print_str(state, MSG_ORIG(MSG_CNOTE_T_SI_CODE),
6726635Sab196087 	    conv_cnote_si_code(state->ns_mach, v_si_signo, v_si_code,
6736635Sab196087 	    CONV_FMT_DECIMAL, &inv_buf));
6746635Sab196087 
6756635Sab196087 	if ((v_si_signo == 0) || (v_si_code == SI_NOINFO)) {
6766635Sab196087 		indent_exit(state);
6776635Sab196087 		return;
6786635Sab196087 	}
6796635Sab196087 
6806635Sab196087 	/* User generated signals have (si_code <= 0) */
6816635Sab196087 	if (v_si_code <= 0) {
6826635Sab196087 		PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_PID), f_si_pid);
6836635Sab196087 		PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_UID), f_si_uid);
6846635Sab196087 		PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_CTID), f_si_ctid);
6856635Sab196087 		PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_ZONEID), f_si_zoneid);
6866635Sab196087 		switch (v_si_code) {
6876635Sab196087 		case SI_QUEUE:
6886635Sab196087 		case SI_TIMER:
6896635Sab196087 		case SI_ASYNCIO:
6906635Sab196087 		case SI_MESGQ:
6916635Sab196087 			indent_enter(state, MSG_ORIG(MSG_CNOTE_T_SI_VALUE),
6926635Sab196087 			    &layout->f_si_value_int);
6936635Sab196087 			PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SIVAL_INT),
6946635Sab196087 			    f_si_value_int);
6956635Sab196087 			PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SIVAL_PTR),
6966635Sab196087 			    f_si_value_ptr);
6976635Sab196087 			indent_exit(state);
6986635Sab196087 			break;
6996635Sab196087 		}
7006635Sab196087 		indent_exit(state);
7016635Sab196087 		return;
7026635Sab196087 	}
7036635Sab196087 
7046635Sab196087 	/*
7056635Sab196087 	 * Remaining cases are kernel generated signals. Output any
7066635Sab196087 	 * signal or code specific information.
7076635Sab196087 	 */
7086635Sab196087 	if (v_si_code == SI_RCTL)
7096635Sab196087 		PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_SI_ENTITY), f_si_entity);
7106635Sab196087 	switch (v_si_signo) {
7116635Sab196087 	case SIGILL:
7126635Sab196087 	case SIGFPE:
7136635Sab196087 	case SIGSEGV:
7146635Sab196087 	case SIGBUS:
7156635Sab196087 		PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_SI_ADDR), f_si_addr);
7166635Sab196087 		break;
7176635Sab196087 	case SIGCHLD:
7186635Sab196087 		PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_PID), f_si_pid);
7196635Sab196087 		PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_STATUS), f_si_status);
7206635Sab196087 		break;
7216635Sab196087 	case SIGPOLL:
7226635Sab196087 		PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_SI_BAND), f_si_band);
7236635Sab196087 		break;
7246635Sab196087 	}
7256635Sab196087 
7266635Sab196087 	indent_exit(state);
7276635Sab196087 }
7286635Sab196087 
7296635Sab196087 
7306635Sab196087 /*
7316635Sab196087  * Output information from stack_t structure.
7326635Sab196087  */
7336635Sab196087 static void
dump_stack(note_state_t * state,const char * title)7346635Sab196087 dump_stack(note_state_t *state, const char *title)
7356635Sab196087 {
7366635Sab196087 	const sl_stack_layout_t		*layout = state->ns_arch->stack;
7376635Sab196087 	Conv_cnote_ss_flags_buf_t	conv_buf;
7386635Sab196087 	Word		w;
7396635Sab196087 
7406635Sab196087 	indent_enter(state, title, &layout->ss_size);
7416635Sab196087 
7426635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_SS_SP), &layout->ss_sp,
7436635Sab196087 	    SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_SS_SIZE), &layout->ss_size,
7446635Sab196087 	    SL_FMT_NUM_HEX);
7456635Sab196087 
7466635Sab196087 	if (data_present(state, &layout->ss_flags)) {
7476635Sab196087 		w = extract_as_word(state, &layout->ss_flags);
7486635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_SS_FLAGS),
7496635Sab196087 		    conv_cnote_ss_flags(w, 0, &conv_buf));
7506635Sab196087 	}
7516635Sab196087 
7526635Sab196087 	indent_exit(state);
7536635Sab196087 }
7546635Sab196087 
7556635Sab196087 
7566635Sab196087 /*
7576635Sab196087  * Output information from sysset_t structure.
7586635Sab196087  */
7596635Sab196087 static void
dump_sysset(note_state_t * state,const char * title)7606635Sab196087 dump_sysset(note_state_t *state, const char *title)
7616635Sab196087 {
7626635Sab196087 #define	NELTS 16
7636635Sab196087 
7646635Sab196087 	const sl_sysset_layout_t	*layout = state->ns_arch->sysset;
7656635Sab196087 	Conv_cnote_sysset_buf_t	buf;
7666635Sab196087 	sl_field_t		fdesc;
7676635Sab196087 	uint32_t		mask[NELTS];
7686635Sab196087 	int			i, nelts;
7696635Sab196087 
7706635Sab196087 	if (!data_present(state, &layout->sizeof_struct))
7716635Sab196087 		return;
7726635Sab196087 
7736635Sab196087 	fdesc = layout->word;
7746635Sab196087 	nelts = fdesc.slf_nelts;
7756635Sab196087 	if (nelts > NELTS)	/* Type has grown? Show what we understand */
7766635Sab196087 		nelts = NELTS;
7776635Sab196087 	for (i = 0; i < nelts; i++) {
7786635Sab196087 		mask[i] = extract_as_word(state, &fdesc);
7796635Sab196087 		fdesc.slf_offset += fdesc.slf_eltlen;
7806635Sab196087 	}
7816635Sab196087 
7826635Sab196087 	print_str(state, title, conv_cnote_sysset(mask, nelts, 0, &buf));
7836635Sab196087 
7846635Sab196087 #undef NELTS
7856635Sab196087 }
7866635Sab196087 
7876635Sab196087 
7886635Sab196087 /*
7896635Sab196087  * Output information from timestruc_t structure.
7906635Sab196087  */
7916635Sab196087 static void
dump_timestruc(note_state_t * state,const char * title)7926635Sab196087 dump_timestruc(note_state_t *state, const char *title)
7936635Sab196087 {
7946635Sab196087 	const sl_timestruc_layout_t *layout = state->ns_arch->timestruc;
7956635Sab196087 
7966635Sab196087 	indent_enter(state, title, &layout->tv_sec);
7976635Sab196087 
7986635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_TV_SEC), tv_sec,
7996635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_TV_NSEC), tv_nsec);
8006635Sab196087 
8016635Sab196087 	indent_exit(state);
8026635Sab196087 }
8036635Sab196087 
8046635Sab196087 
8056635Sab196087 /*
8066635Sab196087  * Output information from utsname structure.
8076635Sab196087  */
8086635Sab196087 static void
dump_utsname(note_state_t * state,const char * title)8096635Sab196087 dump_utsname(note_state_t *state, const char *title)
8106635Sab196087 {
8116635Sab196087 	const sl_utsname_layout_t	*layout = state->ns_arch->utsname;
8126635Sab196087 
8136635Sab196087 	indent_enter(state, title, &layout->sysname);
8146635Sab196087 
8156635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_SYSNAME), sysname);
8166635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_NODENAME), nodename);
8176635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_RELEASE), release);
8186635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_VERSION), version);
8196635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_MACHINE), machine);
8206635Sab196087 
8216635Sab196087 	indent_exit(state);
8226635Sab196087 }
8236635Sab196087 
8246635Sab196087 
8256635Sab196087 /*
8266635Sab196087  * Dump register contents
8276635Sab196087  */
8286635Sab196087 static void
dump_prgregset(note_state_t * state,const char * title)8296635Sab196087 dump_prgregset(note_state_t *state, const char *title)
8306635Sab196087 {
8316635Sab196087 	sl_field_t	fdesc1, fdesc2;
8326635Sab196087 	sl_fmtbuf_t	buf1, buf2;
8336635Sab196087 	Conv_inv_buf_t	inv_buf1, inv_buf2;
8346635Sab196087 	Word		w;
8356635Sab196087 
8366635Sab196087 	indent_enter(state, title, &fdesc1);
8376635Sab196087 
8386635Sab196087 	fdesc1 = fdesc2 = state->ns_arch->prgregset->elt0;
8396635Sab196087 	for (w = 0; w < fdesc1.slf_nelts; ) {
8406635Sab196087 		if (w == (fdesc1.slf_nelts - 1)) {
8416635Sab196087 			/* One last register is left */
8426635Sab196087 			if (!data_present(state, &fdesc1))
8436635Sab196087 				break;
8446635Sab196087 			dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE),
8456635Sab196087 			    INDENT, state->ns_vcol - state->ns_indent,
8466635Sab196087 			    conv_cnote_pr_regname(state->ns_mach, w,
8476635Sab196087 			    CONV_FMT_DECIMAL, &inv_buf1),
8486635Sab196087 			    fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1));
8496635Sab196087 			fdesc1.slf_offset += fdesc1.slf_eltlen;
8506635Sab196087 			w++;
8516635Sab196087 			continue;
8526635Sab196087 		}
8536635Sab196087 
8546635Sab196087 		/* There are at least 2 more registers left. Show 2 up */
8556635Sab196087 		fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen;
8566635Sab196087 		if (!(data_present(state, &fdesc1) &&
8576635Sab196087 		    data_present(state, &fdesc2)))
8586635Sab196087 			break;
8596635Sab196087 		dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT,
8606635Sab196087 		    state->ns_vcol - state->ns_indent,
8616635Sab196087 		    conv_cnote_pr_regname(state->ns_mach, w,
8626635Sab196087 		    CONV_FMT_DECIMAL, &inv_buf1),
8636635Sab196087 		    state->ns_t2col - state->ns_vcol,
8646635Sab196087 		    fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1),
8656635Sab196087 		    state->ns_v2col - state->ns_t2col,
8666635Sab196087 		    conv_cnote_pr_regname(state->ns_mach, w + 1,
8676635Sab196087 		    CONV_FMT_DECIMAL, &inv_buf2),
8686635Sab196087 		    fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2));
8696635Sab196087 		fdesc1.slf_offset += 2 * fdesc1.slf_eltlen;
8706635Sab196087 		w += 2;
8716635Sab196087 	}
8726635Sab196087 
8736635Sab196087 	indent_exit(state);
8746635Sab196087 }
8756635Sab196087 
8766635Sab196087 /*
8776635Sab196087  * Output information from lwpstatus_t structure.
8786635Sab196087  */
8796635Sab196087 static void
dump_lwpstatus(note_state_t * state,const char * title)8806635Sab196087 dump_lwpstatus(note_state_t *state, const char *title)
8816635Sab196087 {
8826635Sab196087 	const sl_lwpstatus_layout_t	*layout = state->ns_arch->lwpstatus;
8836635Sab196087 	Word		w, w2;
8846635Sab196087 	int32_t		i;
8856635Sab196087 	union {
8866635Sab196087 		Conv_inv_buf_t			inv;
8876635Sab196087 		Conv_cnote_pr_flags_buf_t	flags;
8886635Sab196087 	} conv_buf;
8896635Sab196087 
8906635Sab196087 	indent_enter(state, title, &layout->pr_flags);
8916635Sab196087 
8926635Sab196087 	if (data_present(state, &layout->pr_flags)) {
8936635Sab196087 		w = extract_as_word(state, &layout->pr_flags);
8946635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS),
8956635Sab196087 		    conv_cnote_pr_flags(w, 0, &conv_buf.flags));
8966635Sab196087 	}
8976635Sab196087 
8986635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LWPID), pr_lwpid);
8996635Sab196087 
9006635Sab196087 	if (data_present(state, &layout->pr_why)) {
9016635Sab196087 		w = extract_as_word(state, &layout->pr_why);
9026635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHY),
9036635Sab196087 		    conv_cnote_pr_why(w, 0, &conv_buf.inv));
9046635Sab196087 	}
9056635Sab196087 
9066635Sab196087 	if (data_present(state, &layout->pr_what)) {
9076635Sab196087 		w2 = extract_as_word(state, &layout->pr_what);
9086635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHAT),
9096635Sab196087 		    conv_cnote_pr_what(w, w2, 0, &conv_buf.inv));
9106635Sab196087 	}
9116635Sab196087 
9126635Sab196087 	if (data_present(state, &layout->pr_cursig)) {
9136635Sab196087 		w = extract_as_word(state, &layout->pr_cursig);
9146635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_CURSIG),
9156635Sab196087 		    conv_cnote_signal(w, CONV_FMT_DECIMAL, &conv_buf.inv));
9166635Sab196087 	}
9176635Sab196087 
9186635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_INFO), pr_info, dump_siginfo);
9196635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPPEND), pr_lwppend,
9206635Sab196087 	    dump_sigset);
9216635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPHOLD), pr_lwphold,
9226635Sab196087 	    dump_sigset);
9236635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ACTION), pr_action,
9246635Sab196087 	    dump_sigaction);
9256635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ALTSTACK), pr_altstack,
9266635Sab196087 	    dump_stack);
9276635Sab196087 
9286635Sab196087 	PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_OLDCONTEXT), pr_oldcontext);
9296635Sab196087 
9306635Sab196087 	if (data_present(state, &layout->pr_syscall)) {
9316635Sab196087 		w = extract_as_word(state, &layout->pr_syscall);
9326635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL),
9336635Sab196087 		    conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv));
9346635Sab196087 	}
9356635Sab196087 
9366635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSYSARG), pr_nsysarg);
9376635Sab196087 
9386635Sab196087 	if (data_present(state, &layout->pr_errno)) {
9396635Sab196087 		w = extract_as_word(state, &layout->pr_errno);
9406635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_ERRNO),
9416635Sab196087 		    conv_cnote_errno(w, CONV_FMT_DECIMAL, &conv_buf.inv));
9426635Sab196087 	}
9436635Sab196087 
9446635Sab196087 	if (data_present(state, &layout->pr_nsysarg)) {
9456635Sab196087 		w2 = extract_as_word(state, &layout->pr_nsysarg);
9466635Sab196087 		print_array(state, &layout->pr_sysarg, SL_FMT_NUM_ZHEX, w2, 1,
9476635Sab196087 		    MSG_ORIG(MSG_CNOTE_T_PR_SYSARG));
9486635Sab196087 	}
9496635Sab196087 
9506635Sab196087 	PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RVAL1), pr_rval1,
9516635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_RVAL2), pr_rval2);
9526635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname);
9536635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TSTAMP), pr_tstamp,
9546635Sab196087 	    dump_timestruc);
9556635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc);
9566635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc);
9576635Sab196087 
9586635Sab196087 	if (data_present(state, &layout->pr_errpriv)) {
9596635Sab196087 		i = extract_as_sword(state, &layout->pr_errpriv);
9606635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_ERRPRIV),
9616635Sab196087 		    conv_cnote_priv(i, CONV_FMT_DECIMAL, &conv_buf.inv));
9626635Sab196087 	}
9636635Sab196087 
9646635Sab196087 	PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_USTACK), pr_ustack,
9656635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_INSTR), pr_instr);
9666635Sab196087 
9676635Sab196087 	/*
9686635Sab196087 	 * In order to line up all the values in a single column,
9696635Sab196087 	 * we would have to set vcol to a very high value, which results
9706635Sab196087 	 * in ugly looking output that runs off column 80. So, we use
9716635Sab196087 	 * two levels of vcol, one for the contents so far, and a
9726635Sab196087 	 * higher one for the pr_reg sub-struct.
9736635Sab196087 	 */
9746635Sab196087 	state->ns_vcol += 3;
9756635Sab196087 	state->ns_t2col += 3;
9766635Sab196087 	state->ns_v2col += 2;
9776635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_REG), pr_reg, dump_prgregset);
9786635Sab196087 	state->ns_vcol -= 3;
9796635Sab196087 	state->ns_t2col -= 3;
9806635Sab196087 	state->ns_v2col -= 2;
9816635Sab196087 
9826635Sab196087 	/*
9836635Sab196087 	 * The floating point register state is complex, and highly
9846635Sab196087 	 * platform dependent. For now, we simply display it as
9856635Sab196087 	 * a hex dump. This can be replaced if better information
9866635Sab196087 	 * is required.
9876635Sab196087 	 */
9886635Sab196087 	if (data_present(state, &layout->pr_fpreg)) {
9896635Sab196087 		indent_enter(state, MSG_ORIG(MSG_CNOTE_T_PR_FPREG),
9906635Sab196087 		    &layout->pr_fpreg);
9916635Sab196087 		dump_hex_bytes(layout->pr_fpreg.slf_offset + state->ns_data,
9926635Sab196087 		    layout->pr_fpreg.slf_eltlen, state->ns_indent, 4, 3);
9936635Sab196087 		indent_exit(state);
9946635Sab196087 	}
9956635Sab196087 
9966635Sab196087 	indent_exit(state);
9976635Sab196087 }
9986635Sab196087 
9996635Sab196087 
10006635Sab196087 /*
10016635Sab196087  * Output information from pstatus_t structure.
10026635Sab196087  */
10036635Sab196087 static void
dump_pstatus(note_state_t * state,const char * title)10046635Sab196087 dump_pstatus(note_state_t *state, const char *title)
10056635Sab196087 {
10066635Sab196087 	const sl_pstatus_layout_t	*layout = state->ns_arch->pstatus;
10076635Sab196087 	Word				w;
10086635Sab196087 	union {
10096635Sab196087 		Conv_inv_buf_t			inv;
10106635Sab196087 		Conv_cnote_pr_flags_buf_t	flags;
10116635Sab196087 	} conv_buf;
10126635Sab196087 
10136635Sab196087 	indent_enter(state, title, &layout->pr_flags);
10146635Sab196087 
10156635Sab196087 	if (data_present(state, &layout->pr_flags)) {
10166635Sab196087 		w = extract_as_word(state, &layout->pr_flags);
10176635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS),
10186635Sab196087 		    conv_cnote_pr_flags(w, 0, &conv_buf.flags));
10196635Sab196087 	}
10206635Sab196087 
10216635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp);
10226635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid,
10236635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid);
10246635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid,
10256635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid);
10266635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid,
10276635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_AGENTID), pr_agentid);
10286635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGPEND), pr_sigpend,
10296635Sab196087 	    dump_sigset);
10306635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_BRKBASE),
10316635Sab196087 	    &layout->pr_brkbase, SL_FMT_NUM_ZHEX,
10326635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_BRKSIZE),
10336635Sab196087 	    &layout->pr_brksize, SL_FMT_NUM_HEX);
10346635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_STKBASE),
10356635Sab196087 	    &layout->pr_stkbase, SL_FMT_NUM_ZHEX,
10366635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_STKSIZE),
10376635Sab196087 	    &layout->pr_stksize, SL_FMT_NUM_HEX);
10386635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc);
10396635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc);
10406635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CUTIME), pr_cutime,
10416635Sab196087 	    dump_timestruc);
10426635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CSTIME), pr_cstime,
10436635Sab196087 	    dump_timestruc);
10446635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGTRACE), pr_sigtrace,
10456635Sab196087 	    dump_sigset);
10466635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_FLTTRACE), pr_flttrace,
10476635Sab196087 	    dump_fltset);
10486635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SYSENTRY), pr_sysentry,
10496635Sab196087 	    dump_sysset);
10506635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SYSEXIT), pr_sysexit,
10516635Sab196087 	    dump_sysset);
10526635Sab196087 
10536635Sab196087 	if (data_present(state, &layout->pr_dmodel)) {
10546635Sab196087 		w = extract_as_word(state, &layout->pr_dmodel);
10556635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL),
10566635Sab196087 		    conv_cnote_pr_dmodel(w, 0, &conv_buf.inv));
10576635Sab196087 	}
10586635Sab196087 
10596635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid,
10606635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid);
10616635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb,
10626635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid);
10636635Sab196087 
10646635Sab196087 	/*
10656635Sab196087 	 * In order to line up all the values in a single column,
10666635Sab196087 	 * we would have to set vcol to a very high value, which results
10676635Sab196087 	 * in ugly looking output that runs off column 80. So, we use
10686635Sab196087 	 * two levels of vcol, one for the contents so far, and a
10696635Sab196087 	 * higher one for the pr_lwp sub-struct.
10706635Sab196087 	 */
10716635Sab196087 	state->ns_vcol += 5;
10726635Sab196087 	state->ns_t2col += 5;
10736635Sab196087 	state->ns_v2col += 5;
10746635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpstatus);
10756635Sab196087 	state->ns_vcol -= 5;
10766635Sab196087 	state->ns_t2col -= 5;
10776635Sab196087 	state->ns_v2col -= 5;
10786635Sab196087 
10796635Sab196087 	indent_exit(state);
10806635Sab196087 }
10816635Sab196087 
10826635Sab196087 
10836635Sab196087 /*
10846635Sab196087  * Output information from prstatus_t (<sys/old_procfs.h>) structure.
10856635Sab196087  */
10866635Sab196087 static void
dump_prstatus(note_state_t * state,const char * title)10876635Sab196087 dump_prstatus(note_state_t *state, const char *title)
10886635Sab196087 {
10896635Sab196087 	const sl_prstatus_layout_t	*layout = state->ns_arch->prstatus;
10906635Sab196087 	Word				w, w2;
10916635Sab196087 	int				i;
10926635Sab196087 	union {
10936635Sab196087 		Conv_inv_buf_t			inv;
10946635Sab196087 		Conv_cnote_old_pr_flags_buf_t	flags;
10956635Sab196087 	} conv_buf;
10966635Sab196087 
10976635Sab196087 	indent_enter(state, title, &layout->pr_flags);
10986635Sab196087 
10996635Sab196087 	if (data_present(state, &layout->pr_flags)) {
11006635Sab196087 		w = extract_as_word(state, &layout->pr_flags);
11016635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAGS),
11026635Sab196087 		    conv_cnote_old_pr_flags(w, 0, &conv_buf.flags));
11036635Sab196087 	}
11046635Sab196087 
11056635Sab196087 	if (data_present(state, &layout->pr_why)) {
11066635Sab196087 		w = extract_as_word(state, &layout->pr_why);
11076635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHY),
11086635Sab196087 		    conv_cnote_pr_why(w, 0, &conv_buf.inv));
11096635Sab196087 	}
11106635Sab196087 
11116635Sab196087 	if (data_present(state, &layout->pr_what)) {
11126635Sab196087 		w2 = extract_as_word(state, &layout->pr_what);
11136635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_WHAT),
11146635Sab196087 		    conv_cnote_pr_what(w, w2, 0, &conv_buf.inv));
11156635Sab196087 	}
11166635Sab196087 
11176635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_INFO), pr_info, dump_siginfo);
11186635Sab196087 
11196635Sab196087 	if (data_present(state, &layout->pr_cursig)) {
11206635Sab196087 		w = extract_as_word(state, &layout->pr_cursig);
11216635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_CURSIG),
11226635Sab196087 		    conv_cnote_signal(w, CONV_FMT_DECIMAL, &conv_buf.inv));
11236635Sab196087 	}
11246635Sab196087 
11256635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp);
11266635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGPEND), pr_sigpend,
11276635Sab196087 	    dump_sigset);
11286635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_SIGHOLD), pr_sighold,
11296635Sab196087 	    dump_sigset);
11306635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ALTSTACK), pr_altstack,
11316635Sab196087 	    dump_stack);
11326635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_ACTION), pr_action,
11336635Sab196087 	    dump_sigaction);
11346635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid,
11356635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid);
11366635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp,
11376635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid);
11386635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_UTIME), pr_utime, dump_timestruc);
11396635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_STIME), pr_stime, dump_timestruc);
11406635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CUTIME), pr_cutime,
11416635Sab196087 	    dump_timestruc);
11426635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CSTIME), pr_cstime,
11436635Sab196087 	    dump_timestruc);
11446635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname);
11456635Sab196087 
11466635Sab196087 	if (data_present(state, &layout->pr_syscall)) {
11476635Sab196087 		w = extract_as_word(state, &layout->pr_syscall);
11486635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL),
11496635Sab196087 		    conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv));
11506635Sab196087 	}
11516635Sab196087 
11526635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSYSARG), pr_nsysarg);
11536635Sab196087 
11546635Sab196087 	if (data_present(state, &layout->pr_nsysarg)) {
11556635Sab196087 		w2 = extract_as_word(state, &layout->pr_nsysarg);
11566635Sab196087 		print_array(state, &layout->pr_sysarg, SL_FMT_NUM_ZHEX, w2, 1,
11576635Sab196087 		    MSG_ORIG(MSG_CNOTE_T_PR_SYSARG));
11586635Sab196087 	}
11596635Sab196087 
11606635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_WHO), pr_who);
11616635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWPPEND), pr_sigpend,
11626635Sab196087 	    dump_sigset);
11636635Sab196087 	PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_OLDCONTEXT), pr_oldcontext);
11646635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_BRKBASE),
11656635Sab196087 	    &layout->pr_brkbase, SL_FMT_NUM_ZHEX,
11666635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_BRKSIZE),
11676635Sab196087 	    &layout->pr_brksize, SL_FMT_NUM_HEX);
11686635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_STKBASE),
11696635Sab196087 	    &layout->pr_stkbase, SL_FMT_NUM_ZHEX,
11706635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_STKSIZE),
11716635Sab196087 	    &layout->pr_stksize, SL_FMT_NUM_HEX);
11726635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_PROCESSOR), pr_processor);
11736635Sab196087 
11746635Sab196087 	if (data_present(state, &layout->pr_bind)) {
11756635Sab196087 		i = extract_as_sword(state, &layout->pr_bind);
11766635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BIND),
11776635Sab196087 		    conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv));
11786635Sab196087 	}
11796635Sab196087 
11806635Sab196087 	PRINT_ZHEX(MSG_ORIG(MSG_CNOTE_T_PR_INSTR), pr_instr);
11816635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_REG), pr_reg, dump_prgregset);
11826635Sab196087 
11836635Sab196087 	indent_exit(state);
11846635Sab196087 }
11856635Sab196087 
11866635Sab196087 
11876635Sab196087 /*
11886635Sab196087  * Print percent from 16-bit binary fraction [0 .. 1]
11896635Sab196087  * Round up .01 to .1 to indicate some small percentage (the 0x7000 below).
11906635Sab196087  *
11916635Sab196087  * Note: This routine was copied from ps(1) and then modified.
11926635Sab196087  */
11936635Sab196087 static const char *
prtpct_value(note_state_t * state,const sl_field_t * fdesc,sl_fmtbuf_t buf)11946635Sab196087 prtpct_value(note_state_t *state, const sl_field_t *fdesc,
11956635Sab196087     sl_fmtbuf_t buf)
11966635Sab196087 {
11976635Sab196087 	uint_t value;		/* need 32 bits to compute with */
11986635Sab196087 
11996635Sab196087 	value = extract_as_word(state, fdesc);
12006635Sab196087 	value = ((value * 1000) + 0x7000) >> 15;	/* [0 .. 1000] */
12016635Sab196087 	if (value >= 1000)
12026635Sab196087 		value = 999;
12036635Sab196087 
12046635Sab196087 	(void) snprintf(buf, sizeof (sl_fmtbuf_t),
12056635Sab196087 	    MSG_ORIG(MSG_CNOTE_FMT_PRTPCT), value / 10, value % 10);
12066635Sab196087 
12076635Sab196087 	return (buf);
12086635Sab196087 }
12096635Sab196087 
12106635Sab196087 
12116635Sab196087 
12126635Sab196087 /*
12136635Sab196087  * Version of prtpct() used for a 2-up display of two adjacent percentages.
12146635Sab196087  */
12156635Sab196087 static void
prtpct_2up(note_state_t * state,const sl_field_t * fdesc1,const char * title1,const sl_field_t * fdesc2,const char * title2)12166635Sab196087 prtpct_2up(note_state_t *state, const sl_field_t *fdesc1,
12176635Sab196087     const char *title1, const sl_field_t *fdesc2, const char *title2)
12186635Sab196087 {
12196635Sab196087 	sl_fmtbuf_t	buf1, buf2;
12206635Sab196087 
12216635Sab196087 	if (!(data_present(state, fdesc1) &&
12226635Sab196087 	    data_present(state, fdesc2)))
12236635Sab196087 		return;
12246635Sab196087 
12256635Sab196087 	dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT,
12266635Sab196087 	    state->ns_vcol - state->ns_indent, title1,
12276635Sab196087 	    state->ns_t2col - state->ns_vcol,
12286635Sab196087 	    prtpct_value(state, fdesc1, buf1),
12296635Sab196087 	    state->ns_v2col - state->ns_t2col, title2,
12306635Sab196087 	    prtpct_value(state, fdesc2, buf2));
12316635Sab196087 }
12326635Sab196087 
12336635Sab196087 
12346635Sab196087 /*
12356635Sab196087  * The psinfo_t and prpsinfo_t structs have pr_state and pr_sname
12366635Sab196087  * fields that we wish to print in a 2up format. The pr_state is
12376635Sab196087  * an integer, while pr_sname is a single character.
12386635Sab196087  */
12396635Sab196087 static void
print_state_sname_2up(note_state_t * state,const sl_field_t * state_fdesc,const sl_field_t * sname_fdesc)12406635Sab196087 print_state_sname_2up(note_state_t *state,
12416635Sab196087     const sl_field_t *state_fdesc,
12426635Sab196087     const sl_field_t *sname_fdesc)
12436635Sab196087 {
12446635Sab196087 	sl_fmtbuf_t	buf1, buf2;
12456635Sab196087 	int		sname;
12466635Sab196087 
12476635Sab196087 	/*
12486635Sab196087 	 * If the field slf_offset and extent fall past the end of the
12496635Sab196087 	 * available data, then return without doing anything. That note
12506635Sab196087 	 * is from an older core file that doesn't have all the fields
12516635Sab196087 	 * that we know about.
12526635Sab196087 	 */
12536635Sab196087 	if (!(data_present(state, state_fdesc) &&
12546635Sab196087 	    data_present(state, sname_fdesc)))
12556635Sab196087 		return;
12566635Sab196087 
12576635Sab196087 	sname = extract_as_sword(state, sname_fdesc);
12586635Sab196087 	buf2[0] = sname;
12596635Sab196087 	buf2[1] = '\0';
12606635Sab196087 
12616635Sab196087 	dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT,
12626635Sab196087 	    state->ns_vcol - state->ns_indent, MSG_ORIG(MSG_CNOTE_T_PR_STATE),
12636635Sab196087 	    state->ns_t2col - state->ns_vcol,
12646635Sab196087 	    fmt_num(state, state_fdesc, SL_FMT_NUM_DEC, buf1),
12656635Sab196087 	    state->ns_v2col - state->ns_t2col, MSG_ORIG(MSG_CNOTE_T_PR_SNAME),
12666635Sab196087 	    buf2);
12676635Sab196087 }
12686635Sab196087 
12696635Sab196087 /*
12706635Sab196087  * Output information from lwpsinfo_t structure.
12716635Sab196087  */
12726635Sab196087 static void
dump_lwpsinfo(note_state_t * state,const char * title)12736635Sab196087 dump_lwpsinfo(note_state_t *state, const char *title)
12746635Sab196087 {
12756635Sab196087 	const sl_lwpsinfo_layout_t	*layout = state->ns_arch->lwpsinfo;
12766635Sab196087 	Word			w;
12776635Sab196087 	int32_t			i;
12786635Sab196087 	union {
12796635Sab196087 		Conv_cnote_proc_flag_buf_t	proc_flag;
12806635Sab196087 		Conv_inv_buf_t			inv;
12816635Sab196087 	} conv_buf;
12826635Sab196087 
12836635Sab196087 	indent_enter(state, title, &layout->pr_flag);
12846635Sab196087 
12856635Sab196087 	if (data_present(state, &layout->pr_flag)) {
12866635Sab196087 		w = extract_as_word(state, &layout->pr_flag);
12876635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG),
12886635Sab196087 		    conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag));
12896635Sab196087 	}
12906635Sab196087 
12916635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_LWPID), &layout->pr_lwpid,
12926635Sab196087 	    SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr,
12936635Sab196087 	    SL_FMT_NUM_ZHEX);
12946635Sab196087 	PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan);
12956635Sab196087 
12966635Sab196087 	if (data_present(state, &layout->pr_stype)) {
12976635Sab196087 		w = extract_as_word(state, &layout->pr_stype);
12986635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_STYPE),
12996635Sab196087 		    conv_cnote_pr_stype(w, CONV_FMT_DECIMAL, &conv_buf.inv));
13006635Sab196087 	}
13016635Sab196087 
13026635Sab196087 	print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname);
13036635Sab196087 
13046635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice);
13056635Sab196087 
13066635Sab196087 	if (data_present(state, &layout->pr_syscall)) {
13076635Sab196087 		w = extract_as_word(state, &layout->pr_syscall);
13086635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL),
13096635Sab196087 		    conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv));
13106635Sab196087 	}
13116635Sab196087 
13126635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri,
13136635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu);
13146635Sab196087 
13156635Sab196087 	if (data_present(state, &layout->pr_pri) &&
13166635Sab196087 	    data_present(state, &layout->pr_pctcpu)) {
13176635Sab196087 		sl_fmtbuf_t	buf1, buf2;
13186635Sab196087 
13196635Sab196087 		dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT,
13206635Sab196087 		    state->ns_vcol - state->ns_indent,
13216635Sab196087 		    MSG_ORIG(MSG_CNOTE_T_PR_PRI),
13226635Sab196087 		    state->ns_t2col - state->ns_vcol,
13236635Sab196087 		    fmt_num(state, &layout->pr_pri, SL_FMT_NUM_DEC, buf1),
13246635Sab196087 		    state->ns_v2col - state->ns_t2col,
13256635Sab196087 		    MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU),
13266635Sab196087 		    prtpct_value(state, &layout->pr_pctcpu, buf2));
13276635Sab196087 	}
13286635Sab196087 
13296635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc);
13306635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc);
13316635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname);
13326635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_NAME), pr_name);
13336635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ONPRO), pr_onpro,
13346635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_BINDPRO), pr_bindpro);
13356635Sab196087 
13366635Sab196087 	if (data_present(state, &layout->pr_bindpset)) {
13376635Sab196087 		i = extract_as_sword(state, &layout->pr_bindpset);
13386635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_BINDPSET),
13396635Sab196087 		    conv_cnote_psetid(i, CONV_FMT_DECIMAL, &conv_buf.inv));
13406635Sab196087 	}
13416635Sab196087 
13426635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LGRP), pr_lgrp);
13436635Sab196087 
13446635Sab196087 	indent_exit(state);
13456635Sab196087 }
13466635Sab196087 
13476635Sab196087 
13486635Sab196087 /*
13496635Sab196087  * Output information from psinfo_t structure.
13506635Sab196087  */
13516635Sab196087 static void
dump_psinfo(note_state_t * state,const char * title)13526635Sab196087 dump_psinfo(note_state_t *state, const char *title)
13536635Sab196087 {
13546635Sab196087 	const sl_psinfo_layout_t	*layout = state->ns_arch->psinfo;
13556635Sab196087 	Word				w;
13566635Sab196087 	union {
13576635Sab196087 		Conv_cnote_proc_flag_buf_t	proc_flag;
13586635Sab196087 		Conv_inv_buf_t			inv;
13596635Sab196087 	} conv_buf;
13606635Sab196087 
13616635Sab196087 	indent_enter(state, title, &layout->pr_flag);
13626635Sab196087 
13636635Sab196087 	if (data_present(state, &layout->pr_flag)) {
13646635Sab196087 		w = extract_as_word(state, &layout->pr_flag);
13656635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG),
13666635Sab196087 		    conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag));
13676635Sab196087 	}
13686635Sab196087 
13696635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NLWP), pr_nlwp);
13706635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid,
13716635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid);
13726635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGID), pr_pgid,
13736635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid);
13746635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid,
13756635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid);
13766635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid,
13776635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid);
13786635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr,
13796635Sab196087 	    SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size,
13806635Sab196087 	    SL_FMT_NUM_HEX);
13816635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE),
13826635Sab196087 	    &layout->pr_rssize, SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_TTYDEV),
13836635Sab196087 	    &layout->pr_ttydev, SL_FMT_NUM_DEC);
13846635Sab196087 	prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU),
13856635Sab196087 	    &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM));
13866635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc);
13876635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc);
13886635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc);
13896635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname);
13906635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs);
13916635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat,
13926635Sab196087 	    SL_FMT_NUM_HEX, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc,
13936635Sab196087 	    SL_FMT_NUM_DEC);
13946635Sab196087 	PRINT_ZHEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ARGV), pr_argv,
13956635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_ENVP), pr_envp);
13966635Sab196087 
13976635Sab196087 	if (data_present(state, &layout->pr_dmodel)) {
13986635Sab196087 		w = extract_as_word(state, &layout->pr_dmodel);
13996635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL),
14006635Sab196087 		    conv_cnote_pr_dmodel(w, 0, &conv_buf.inv));
14016635Sab196087 	}
14026635Sab196087 
14036635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid,
14046635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid);
14056635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb,
14066635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_POOLID), pr_poolid);
14076635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid,
14086635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_CONTRACT), pr_contract);
14096635Sab196087 
14106635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpsinfo);
14116635Sab196087 
14126635Sab196087 	indent_exit(state);
14136635Sab196087 }
14146635Sab196087 
14156635Sab196087 
14166635Sab196087 /*
14176635Sab196087  * Output information from prpsinfo_t structure.
14186635Sab196087  */
14196635Sab196087 static void
dump_prpsinfo(note_state_t * state,const char * title)14206635Sab196087 dump_prpsinfo(note_state_t *state, const char *title)
14216635Sab196087 {
14226635Sab196087 	const sl_prpsinfo_layout_t	*layout = state->ns_arch->prpsinfo;
14236635Sab196087 	Word				w;
14246635Sab196087 	union {
14256635Sab196087 		Conv_cnote_proc_flag_buf_t	proc_flag;
14266635Sab196087 		Conv_inv_buf_t			inv;
14276635Sab196087 	} conv_buf;
14286635Sab196087 
14296635Sab196087 	indent_enter(state, title, &layout->pr_state);
14306635Sab196087 
14316635Sab196087 	print_state_sname_2up(state, &layout->pr_state, &layout->pr_sname);
14326635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_ZOMB), pr_zomb,
14336635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_NICE), pr_nice);
14346635Sab196087 
14356635Sab196087 	if (data_present(state, &layout->pr_flag)) {
14366635Sab196087 		w = extract_as_word(state, &layout->pr_flag);
14376635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_FLAG),
14386635Sab196087 		    conv_cnote_proc_flag(w, 0, &conv_buf.proc_flag));
14396635Sab196087 	}
14406635Sab196087 
14416635Sab196087 
14426635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_UID), pr_uid,
14436635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_GID), pr_gid);
14446635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PID), pr_pid,
14456635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_PPID), pr_ppid);
14466635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PGRP), pr_pgrp,
14476635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_SID), pr_sid);
14486635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ADDR), &layout->pr_addr,
14496635Sab196087 	    SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_SIZE), &layout->pr_size,
14506635Sab196087 	    SL_FMT_NUM_HEX);
14516635Sab196087 	PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RSSIZE), pr_rssize,
14526635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_WCHAN), pr_wchan);
14536635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_START), pr_start, dump_timestruc);
14546635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_TIME), pr_time, dump_timestruc);
14556635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_PRI), pr_pri,
14566635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_OLDPRI), pr_oldpri);
14576635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_CPU), pr_cpu);
14586635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_OTTYDEV), pr_ottydev,
14596635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_LTTYDEV), pr_lttydev);
14606635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_CLNAME), pr_clname);
14616635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_FNAME), pr_fname);
14626635Sab196087 	PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_PSARGS), pr_psargs);
14636635Sab196087 
14646635Sab196087 	if (data_present(state, &layout->pr_syscall)) {
14656635Sab196087 		w = extract_as_word(state, &layout->pr_syscall);
14666635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_SYSCALL),
14676635Sab196087 		    conv_cnote_syscall(w, CONV_FMT_DECIMAL, &conv_buf.inv));
14686635Sab196087 	}
14696635Sab196087 
14706635Sab196087 	PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_CTIME), pr_ctime, dump_timestruc);
14716635Sab196087 	PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PR_BYSIZE), pr_bysize,
14726635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_BYRSSIZE), pr_byrssize);
14736635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ARGC), &layout->pr_argc,
14746635Sab196087 	    SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PR_ARGV), &layout->pr_argv,
14756635Sab196087 	    SL_FMT_NUM_ZHEX);
14766635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PR_ENVP), &layout->pr_envp,
14776635Sab196087 	    SL_FMT_NUM_ZHEX, MSG_ORIG(MSG_CNOTE_T_PR_WSTAT), &layout->pr_wstat,
14786635Sab196087 	    SL_FMT_NUM_HEX);
14796635Sab196087 	prtpct_2up(state, &layout->pr_pctcpu, MSG_ORIG(MSG_CNOTE_T_PR_PCTCPU),
14806635Sab196087 	    &layout->pr_pctmem, MSG_ORIG(MSG_CNOTE_T_PR_PCTMEM));
14816635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid,
14826635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid);
14836635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_ASLWPID), pr_aslwpid);
14846635Sab196087 
14856635Sab196087 	if (data_present(state, &layout->pr_dmodel)) {
14866635Sab196087 		w = extract_as_word(state, &layout->pr_dmodel);
14876635Sab196087 		print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL),
14886635Sab196087 		    conv_cnote_pr_dmodel(w, 0, &conv_buf.inv));
14896635Sab196087 	}
14906635Sab196087 
14916635Sab196087 	indent_exit(state);
14926635Sab196087 }
14936635Sab196087 
14946635Sab196087 
14956635Sab196087 /*
14966635Sab196087  * Output information from prcred_t structure.
14976635Sab196087  */
14986635Sab196087 static void
dump_prcred(note_state_t * state,const char * title)14996635Sab196087 dump_prcred(note_state_t *state, const char *title)
15006635Sab196087 {
15016635Sab196087 	const sl_prcred_layout_t *layout = state->ns_arch->prcred;
15026635Sab196087 	Word		ngroups;
15036635Sab196087 
15046635Sab196087 	indent_enter(state, title, &layout->pr_euid);
15056635Sab196087 
15066635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_EUID), pr_euid,
15076635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_RUID), pr_ruid);
15086635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_SUID), pr_suid,
15096635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_EGID), pr_egid);
15106635Sab196087 	PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_RGID), pr_rgid,
15116635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PR_SGID), pr_sgid);
15126635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NGROUPS), pr_ngroups);
15136635Sab196087 
15146635Sab196087 	if (data_present(state, &layout->pr_ngroups)) {
15156635Sab196087 		ngroups = extract_as_word(state, &layout->pr_ngroups);
15166635Sab196087 		print_array(state, &layout->pr_groups, SL_FMT_NUM_DEC, ngroups,
15176635Sab196087 		    0, MSG_ORIG(MSG_CNOTE_T_PR_GROUPS));
15186635Sab196087 	}
15196635Sab196087 
15206635Sab196087 	indent_exit(state);
15216635Sab196087 }
15226635Sab196087 
15236635Sab196087 
15246635Sab196087 /*
15256635Sab196087  * Output information from prpriv_t structure.
15266635Sab196087  */
15276635Sab196087 static void
dump_prpriv(note_state_t * state,const char * title)15286635Sab196087 dump_prpriv(note_state_t *state, const char *title)
15296635Sab196087 {
15306635Sab196087 	const sl_prpriv_layout_t *layout = state->ns_arch->prpriv;
15316635Sab196087 	Word		nsets;
15326635Sab196087 
15336635Sab196087 	indent_enter(state, title, &layout->pr_nsets);
15346635Sab196087 
15356635Sab196087 	PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_NSETS), pr_nsets);
15366635Sab196087 	PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_SETSIZE), pr_setsize);
15376635Sab196087 	PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PR_INFOSIZE), pr_infosize);
15386635Sab196087 
15396635Sab196087 	if (data_present(state, &layout->pr_nsets)) {
15406635Sab196087 		nsets = extract_as_word(state, &layout->pr_nsets);
15416635Sab196087 		print_array(state, &layout->pr_sets, SL_FMT_NUM_ZHEX, nsets,
15426635Sab196087 		    0, MSG_ORIG(MSG_CNOTE_T_PR_SETS));
15436635Sab196087 	}
15446635Sab196087 
15456635Sab196087 	indent_exit(state);
15466635Sab196087 }
15476635Sab196087 
15486635Sab196087 
15496635Sab196087 /*
15506635Sab196087  * Output information from priv_impl_info_t structure.
15516635Sab196087  */
15526635Sab196087 static void
dump_priv_impl_info(note_state_t * state,const char * title)15536635Sab196087 dump_priv_impl_info(note_state_t *state, const char *title)
15546635Sab196087 {
15556635Sab196087 	const sl_priv_impl_info_layout_t *layout;
15566635Sab196087 
15576635Sab196087 	layout = state->ns_arch->priv_impl_info;
15586635Sab196087 	indent_enter(state, title, &layout->priv_headersize);
15596635Sab196087 
15606635Sab196087 	PRINT_HEX_2UP(MSG_ORIG(MSG_CNOTE_T_PRIV_HEADERSIZE), priv_headersize,
15616635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PRIV_FLAGS), priv_flags);
15626635Sab196087 
15636635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_NSETS),
15646635Sab196087 	    &layout->priv_nsets, SL_FMT_NUM_DEC,
15656635Sab196087 	    MSG_ORIG(MSG_CNOTE_T_PRIV_SETSIZE), &layout->priv_setsize,
15666635Sab196087 	    SL_FMT_NUM_HEX);
15676635Sab196087 	print_num_2up(state, MSG_ORIG(MSG_CNOTE_T_PRIV_MAX), &layout->priv_max,
15686635Sab196087 	    SL_FMT_NUM_DEC, MSG_ORIG(MSG_CNOTE_T_PRIV_INFOSIZE),
15696635Sab196087 	    &layout->priv_infosize, SL_FMT_NUM_HEX);
15706635Sab196087 	PRINT_HEX(MSG_ORIG(MSG_CNOTE_T_PRIV_GLOBALINFOSIZE),
15716635Sab196087 	    priv_globalinfosize);
15726635Sab196087 
15736635Sab196087 	indent_exit(state);
15746635Sab196087 }
15756635Sab196087 
15766635Sab196087 
15776635Sab196087 /*
15786635Sab196087  * Dump information from an asrset_t array. This data
15796635Sab196087  * structure is specific to sparcv9, and does not appear
15806635Sab196087  * on any other platform.
15816635Sab196087  *
15826635Sab196087  * asrset_t is a simple array, defined in <sys/regset.h> as
15836635Sab196087  *	typedef	int64_t	asrset_t[16];	 %asr16 - > %asr31
15846635Sab196087  *
15856635Sab196087  * As such, we do not make use of the struct_layout facilities
15866635Sab196087  * for this routine.
15876635Sab196087  */
15886635Sab196087 static void
dump_asrset(note_state_t * state,const char * title)15896635Sab196087 dump_asrset(note_state_t *state, const char *title)
15906635Sab196087 {
15916635Sab196087 	static const sl_field_t ftemplate = { 0, sizeof (int64_t), 16, 0 };
15926635Sab196087 	sl_field_t	fdesc1, fdesc2;
15936635Sab196087 	sl_fmtbuf_t	buf1, buf2;
15946635Sab196087 	char		index1[MAXNDXSIZE * 2], index2[MAXNDXSIZE * 2];
15956635Sab196087 	Word		w, nelts;
15966635Sab196087 
15976635Sab196087 	fdesc1 = fdesc2 =  ftemplate;
15986635Sab196087 
15996635Sab196087 	/* We expect 16 values, but will print whatever is actually there */
16006635Sab196087 	nelts = state->ns_len / ftemplate.slf_eltlen;
16016635Sab196087 	if (nelts == 0)
16026635Sab196087 		return;
16036635Sab196087 
16046635Sab196087 	indent_enter(state, title, &fdesc1);
16056635Sab196087 
16066635Sab196087 	for (w = 0; w < nelts; ) {
16076635Sab196087 		(void) snprintf(index1, sizeof (index1),
16086635Sab196087 		    MSG_ORIG(MSG_FMT_ASRINDEX), w + 16);
16096635Sab196087 
16106635Sab196087 		if (w == (nelts - 1)) {
16116635Sab196087 			/* One last register is left */
16126635Sab196087 			dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE),
16136635Sab196087 			    INDENT, state->ns_vcol - state->ns_indent, index1,
16146635Sab196087 			    fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1));
16156635Sab196087 			fdesc1.slf_offset += fdesc1.slf_eltlen;
16166635Sab196087 			w++;
16176635Sab196087 			continue;
16186635Sab196087 		}
16196635Sab196087 
16206635Sab196087 		/* There are at least 2 more registers left. Show 2 up */
16216635Sab196087 		(void) snprintf(index2, sizeof (index2),
16226635Sab196087 		    MSG_ORIG(MSG_FMT_ASRINDEX), w + 17);
16236635Sab196087 
16246635Sab196087 		fdesc2.slf_offset = fdesc1.slf_offset + fdesc1.slf_eltlen;
16256635Sab196087 		dbg_print(0, MSG_ORIG(MSG_CNOTE_FMT_LINE_2UP), INDENT,
16266635Sab196087 		    state->ns_vcol - state->ns_indent, index1,
16276635Sab196087 		    state->ns_t2col - state->ns_vcol,
16286635Sab196087 		    fmt_num(state, &fdesc1, SL_FMT_NUM_ZHEX, buf1),
16296635Sab196087 		    state->ns_v2col - state->ns_t2col, index2,
16306635Sab196087 		    fmt_num(state, &fdesc2, SL_FMT_NUM_ZHEX, buf2));
16316635Sab196087 		fdesc1.slf_offset += 2 * fdesc1.slf_eltlen;
16326635Sab196087 		w += 2;
16336635Sab196087 	}
16346635Sab196087 
16356635Sab196087 	indent_exit(state);
16366635Sab196087 }
16376635Sab196087 
16386635Sab196087 corenote_ret_t
corenote(Half mach,int do_swap,Word type,const char * desc,Word descsz)16396635Sab196087 corenote(Half mach, int do_swap, Word type,
16406635Sab196087     const char *desc, Word descsz)
16416635Sab196087 {
16426635Sab196087 	note_state_t		state;
16436635Sab196087 
16446635Sab196087 	/*
16456635Sab196087 	 * Get the per-architecture layout definition
16466635Sab196087 	 */
16476635Sab196087 	state.ns_mach = mach;
16486635Sab196087 	state.ns_arch = sl_mach(state.ns_mach);
16496635Sab196087 	if (sl_mach(state.ns_mach) == NULL)
16506635Sab196087 		return (CORENOTE_R_BADARCH);
16516635Sab196087 
16526635Sab196087 	state.ns_swap = do_swap;
16536635Sab196087 	state.ns_indent = 4;
16546635Sab196087 	state.ns_t2col = state.ns_v2col = 0;
16556635Sab196087 	state.ns_data = desc;
16566635Sab196087 	state.ns_len = descsz;
16576635Sab196087 
16586635Sab196087 	switch (type) {
16596635Sab196087 	case NT_PRSTATUS:		/* prstatus_t <sys/old_procfs.h> */
16606635Sab196087 		state.ns_vcol = 26;
16616635Sab196087 		state.ns_t2col = 46;
16626635Sab196087 		state.ns_v2col = 60;
16636635Sab196087 		dump_prstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSTATUS_T));
16646635Sab196087 		return (CORENOTE_R_OK);
16656635Sab196087 
16666635Sab196087 	case NT_PRFPREG:		/* prfpregset_t	<sys/procfs_isa.h> */
16676635Sab196087 		return (CORENOTE_R_OK_DUMP);
16686635Sab196087 
16696635Sab196087 	case NT_PRPSINFO:		/* prpsinfo_t	<sys/old_procfs.h> */
16706635Sab196087 		state.ns_vcol = 20;
16716635Sab196087 		state.ns_t2col = 41;
16726635Sab196087 		state.ns_v2col = 54;
16736635Sab196087 		dump_prpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPSINFO_T));
16746635Sab196087 		return (CORENOTE_R_OK);
16756635Sab196087 
16766635Sab196087 	case NT_PRXREG:			/* prxregset_t <sys/procfs_isa.h> */
16776635Sab196087 		return (CORENOTE_R_OK_DUMP);
16786635Sab196087 
16796635Sab196087 	case NT_PLATFORM:		/* string from sysinfo(SI_PLATFORM) */
16806635Sab196087 		dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
16816635Sab196087 		dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz));
16826635Sab196087 		return (CORENOTE_R_OK);
16836635Sab196087 
16846635Sab196087 	case NT_AUXV:			/* auxv_t array	<sys/auxv.h> */
16856635Sab196087 		state.ns_vcol = 18;
16866635Sab196087 		dump_auxv(&state, MSG_ORIG(MSG_CNOTE_DESC_AUXV_T));
16876635Sab196087 		return (CORENOTE_R_OK);
16886635Sab196087 
16896635Sab196087 	case NT_GWINDOWS:		/* gwindows_t SPARC only */
16906635Sab196087 		return (CORENOTE_R_OK_DUMP);
16916635Sab196087 
16926635Sab196087 	case NT_ASRS:			/* asrset_t <sys/regset> sparcv9 only */
16936635Sab196087 		state.ns_vcol = 18;
16946635Sab196087 		state.ns_t2col = 38;
16956635Sab196087 		state.ns_v2col = 46;
16966635Sab196087 		dump_asrset(&state, MSG_ORIG(MSG_CNOTE_DESC_ASRSET_T));
16976635Sab196087 		return (CORENOTE_R_OK);
16986635Sab196087 
16996635Sab196087 	case NT_LDT:			/* ssd array <sys/sysi86.h> IA32 only */
17006635Sab196087 		return (CORENOTE_R_OK_DUMP);
17016635Sab196087 
17026635Sab196087 	case NT_PSTATUS:		/* pstatus_t <sys/procfs.h> */
17036635Sab196087 		state.ns_vcol = 22;
17046635Sab196087 		state.ns_t2col = 42;
17056635Sab196087 		state.ns_v2col = 54;
17066635Sab196087 		dump_pstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_PSTATUS_T));
17076635Sab196087 		return (CORENOTE_R_OK);
17086635Sab196087 
17096635Sab196087 	case NT_PSINFO:			/* psinfo_t <sys/procfs.h> */
17106635Sab196087 		state.ns_vcol = 25;
17116635Sab196087 		state.ns_t2col = 45;
17126635Sab196087 		state.ns_v2col = 58;
17136635Sab196087 		dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T));
17146635Sab196087 		return (CORENOTE_R_OK);
17156635Sab196087 
17166635Sab196087 	case NT_PRCRED:			/* prcred_t <sys/procfs.h> */
17176635Sab196087 		state.ns_vcol = 20;
17186635Sab196087 		state.ns_t2col = 34;
17196635Sab196087 		state.ns_v2col = 44;
17206635Sab196087 		dump_prcred(&state, MSG_ORIG(MSG_CNOTE_DESC_PRCRED_T));
17216635Sab196087 		return (CORENOTE_R_OK);
17226635Sab196087 
17236635Sab196087 	case NT_UTSNAME:		/* struct utsname <sys/utsname.h> */
17246635Sab196087 		state.ns_vcol = 18;
17256635Sab196087 		dump_utsname(&state, MSG_ORIG(MSG_CNOTE_DESC_STRUCT_UTSNAME));
17266635Sab196087 		return (CORENOTE_R_OK);
17276635Sab196087 
17286635Sab196087 	case NT_LWPSTATUS:		/* lwpstatus_t <sys/procfs.h> */
17296635Sab196087 		state.ns_vcol = 24;
17306635Sab196087 		state.ns_t2col = 44;
17316635Sab196087 		state.ns_v2col = 54;
17326635Sab196087 		dump_lwpstatus(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSTATUS_T));
17336635Sab196087 		return (CORENOTE_R_OK);
17346635Sab196087 
17356635Sab196087 	case NT_LWPSINFO:		/* lwpsinfo_t <sys/procfs.h> */
17366635Sab196087 		state.ns_vcol = 22;
17376635Sab196087 		state.ns_t2col = 42;
17386635Sab196087 		state.ns_v2col = 54;
17396635Sab196087 		dump_lwpsinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_LWPSINFO_T));
17406635Sab196087 		return (CORENOTE_R_OK);
17416635Sab196087 
17426635Sab196087 	case NT_PRPRIV:			/* prpriv_t <sys/procfs.h> */
17436635Sab196087 		state.ns_vcol = 21;
17446635Sab196087 		state.ns_t2col = 34;
17456635Sab196087 		state.ns_v2col = 38;
17466635Sab196087 		dump_prpriv(&state, MSG_ORIG(MSG_CNOTE_DESC_PRPRIV_T));
17476635Sab196087 		return (CORENOTE_R_OK);
17486635Sab196087 
17496635Sab196087 	case NT_PRPRIVINFO:		/* priv_impl_info_t <sys/priv.h> */
17506635Sab196087 		state.ns_vcol = 29;
17516635Sab196087 		state.ns_t2col = 41;
17526635Sab196087 		state.ns_v2col = 56;
17536635Sab196087 		dump_priv_impl_info(&state,
17546635Sab196087 		    MSG_ORIG(MSG_CNOTE_DESC_PRIV_IMPL_INFO_T));
17556635Sab196087 		return (CORENOTE_R_OK);
17566635Sab196087 
17576635Sab196087 	case NT_CONTENT:		/* core_content_t <sys/corectl.h> */
17586635Sab196087 		if (sizeof (core_content_t) > descsz)
17596635Sab196087 			return (CORENOTE_R_BADDATA);
17606635Sab196087 		{
17616635Sab196087 			static sl_field_t fdesc = { 0, 8, 0, 0 };
17626635Sab196087 			Conv_cnote_cc_content_buf_t conv_buf;
17636635Sab196087 			core_content_t content;
17646635Sab196087 
17656635Sab196087 			state.ns_vcol = 8;
17666635Sab196087 			indent_enter(&state,
17676635Sab196087 			    MSG_ORIG(MSG_CNOTE_DESC_CORE_CONTENT_T),
17686635Sab196087 			    &fdesc);
17696635Sab196087 			content = extract_as_lword(&state, &fdesc);
17706635Sab196087 			print_str(&state, MSG_ORIG(MSG_STR_EMPTY),
17716635Sab196087 			    conv_cnote_cc_content(content, 0, &conv_buf));
17726635Sab196087 			indent_exit(&state);
17736635Sab196087 		}
17746635Sab196087 		return (CORENOTE_R_OK);
17756635Sab196087 
17766635Sab196087 	case NT_ZONENAME:		/* string from getzonenamebyid(3C) */
17776635Sab196087 		dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
17786635Sab196087 		dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz));
17796635Sab196087 		return (CORENOTE_R_OK);
17806635Sab196087 	}
17816635Sab196087 
17826635Sab196087 	return (CORENOTE_R_BADTYPE);
17836635Sab196087 }
1784