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