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