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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * Copyright (c) 2011 by Delphix. All rights reserved.
27 */
28 /*
29 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
30 * Copyright (c) 2023, Domagoj Stolfa. All rights reserved.
31 */
32
33 /*
34 * DTrace print() action
35 *
36 * This file contains the post-processing logic for the print() action. The
37 * print action behaves identically to trace() in that it generates a
38 * DTRACEACT_DIFEXPR action, but the action argument field refers to a CTF type
39 * string stored in the DOF string table (similar to printf formats). We
40 * take the result of the trace action and post-process it in the fashion of
41 * MDB's ::print dcmd.
42 *
43 * This implementation differs from MDB's in the following ways:
44 *
45 * - We do not expose any options or flags. The behavior of print() is
46 * equivalent to "::print -tn".
47 *
48 * - MDB will display "holes" in structures (unused padding between
49 * members).
50 *
51 * - When printing arrays of structures, MDB will leave a trailing ','
52 * after the last element.
53 *
54 * - MDB will print time_t types as date and time.
55 *
56 * - MDB will detect when an enum is actually the OR of several flags,
57 * and print it out with the constituent flags separated.
58 *
59 * - For large arrays, MDB will print the first few members and then
60 * print a "..." continuation line.
61 *
62 * - MDB will break and wrap arrays at 80 columns.
63 *
64 * - MDB prints out floats and doubles by hand, as it must run in kmdb
65 * context. We're able to leverage the printf() format strings,
66 * but the result is a slightly different format.
67 */
68
69 #include <sys/sysmacros.h>
70 #include <strings.h>
71 #include <stdlib.h>
72 #include <alloca.h>
73 #include <assert.h>
74 #include <ctype.h>
75 #include <errno.h>
76 #include <limits.h>
77 #include <sys/socket.h>
78 #include <netdb.h>
79 #include <netinet/in.h>
80 #include <arpa/inet.h>
81
82 #include <dt_module.h>
83 #include <dt_printf.h>
84 #include <dt_string.h>
85 #include <dt_impl.h>
86 #include <dt_oformat.h>
87
88 /* determines whether the given integer CTF encoding is a character */
89 #define CTF_IS_CHAR(e) \
90 (((e).cte_format & (CTF_INT_CHAR | CTF_INT_SIGNED)) == \
91 (CTF_INT_CHAR | CTF_INT_SIGNED) && (e).cte_bits == NBBY)
92 /* determines whether the given CTF kind is a struct or union */
93 #define CTF_IS_STRUCTLIKE(k) \
94 ((k) == CTF_K_STRUCT || (k) == CTF_K_UNION)
95
96 /*
97 * Print structure passed down recursively through printing algorithm.
98 */
99 typedef struct dt_printarg {
100 dtrace_hdl_t *pa_dtp; /* libdtrace handle */
101 caddr_t pa_addr; /* base address of trace data */
102 ctf_file_t *pa_ctfp; /* CTF container */
103 int pa_depth; /* member depth */
104 int pa_nest; /* nested array depth */
105 FILE *pa_file; /* output file */
106 const char *pa_object; /* object name */
107 } dt_printarg_t;
108
109 static int dt_format_member(const char *, ctf_id_t, ulong_t, int, void *);
110 static int dt_print_member(const char *, ctf_id_t, ulong_t, int, void *);
111
112 /*
113 * Safe version of ctf_type_name() that will fall back to just "<ctfid>" if it
114 * can't resolve the type.
115 */
116 static void
dt_print_type_name(ctf_file_t * ctfp,ctf_id_t id,char * buf,size_t buflen)117 dt_print_type_name(ctf_file_t *ctfp, ctf_id_t id, char *buf, size_t buflen)
118 {
119 if (ctf_type_name(ctfp, id, buf, buflen) == NULL)
120 (void) snprintf(buf, buflen, "<%ld>", id);
121 }
122
123 /*
124 * Print any necessary trailing braces for structures or unions. We don't get
125 * invoked when a struct or union ends, so we infer the need to print braces
126 * based on the depth the last time we printed something and the new depth.
127 */
128 static void
dt_print_trailing_braces(dt_printarg_t * pap,int depth)129 dt_print_trailing_braces(dt_printarg_t *pap, int depth)
130 {
131 int d;
132
133 for (d = pap->pa_depth; d > depth; d--) {
134 (void) fprintf(pap->pa_file, "%*s}%s",
135 (d + pap->pa_nest - 1) * 4, "",
136 d == depth + 1 ? "" : "\n");
137 }
138 }
139
140 /*
141 * Print the appropriate amount of indentation given the current depth and
142 * array nesting.
143 */
144 static void
dt_print_indent(dt_printarg_t * pap)145 dt_print_indent(dt_printarg_t *pap)
146 {
147 (void) fprintf(pap->pa_file, "%*s",
148 (pap->pa_depth + pap->pa_nest) * 4, "");
149 }
150
151 /*
152 * Print a bitfield. It's worth noting that the D compiler support for
153 * bitfields is currently broken; printing "D`user_desc_t" (pulled in by the
154 * various D provider files) will produce incorrect results compared to
155 * "genunix`user_desc_t".
156 */
157 static void
print_bitfield(dt_printarg_t * pap,ulong_t off,ctf_encoding_t * ep)158 print_bitfield(dt_printarg_t *pap, ulong_t off, ctf_encoding_t *ep)
159 {
160 FILE *fp = pap->pa_file;
161 caddr_t addr = pap->pa_addr + off / NBBY;
162 uint64_t mask = (1ULL << ep->cte_bits) - 1;
163 uint64_t value = 0;
164 size_t size = (ep->cte_bits + (NBBY - 1)) / NBBY;
165 uint8_t *buf = (uint8_t *)&value;
166 uint8_t shift;
167
168 /*
169 * On big-endian machines, we need to adjust the buf pointer to refer
170 * to the lowest 'size' bytes in 'value', and we need to shift based on
171 * the offset from the end of the data, not the offset of the start.
172 */
173 #if BYTE_ORDER == _BIG_ENDIAN
174 buf += sizeof (value) - size;
175 off += ep->cte_bits;
176 #endif
177 bcopy(addr, buf, size);
178 shift = off % NBBY;
179
180 /*
181 * Offsets are counted from opposite ends on little- and
182 * big-endian machines.
183 */
184 #if BYTE_ORDER == _BIG_ENDIAN
185 shift = NBBY - shift;
186 #endif
187
188 /*
189 * If the bits we want do not begin on a byte boundary, shift the data
190 * right so that the value is in the lowest 'cte_bits' of 'value'.
191 */
192 if (off % NBBY != 0)
193 value >>= shift;
194 value &= mask;
195
196 xo_emit("{:value/%#llx}", (u_longlong_t)value);
197
198 /* Flush in order to ensure output is aligned properly */
199 xo_flush();
200 }
201
202 /*
203 * Dump the contents of memory as a fixed-size integer in hex.
204 */
205 static void
dt_print_hex(FILE * fp,caddr_t addr,size_t size)206 dt_print_hex(FILE *fp, caddr_t addr, size_t size)
207 {
208 switch (size) {
209 case sizeof (uint8_t):
210 xo_emit("{:value/%#x}", *(uint8_t *)addr);
211 break;
212 case sizeof (uint16_t):
213 xo_emit("{:value/%#x}", *(uint16_t *)addr);
214 break;
215 case sizeof (uint32_t):
216 xo_emit("{:value/%#x}", *(uint32_t *)addr);
217 break;
218 case sizeof (uint64_t):
219 xo_emit("{:value/%#llx}",
220 (unsigned long long)*(uint64_t *)addr);
221 break;
222 default:
223 xo_emit("<{:warning} {:size/%u}>", "invalid size",
224 (uint_t)size);
225 }
226
227 /* Flush in order to ensure output is aligned properly */
228 xo_flush();
229 }
230
231 /*
232 * Print an integer type. Before dumping the contents via dt_print_hex(), we
233 * first check the encoding to see if it's part of a bitfield or a character.
234 */
235 static void
dt_print_int(ctf_id_t base,ulong_t off,dt_printarg_t * pap)236 dt_print_int(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
237 {
238 FILE *fp = pap->pa_file;
239 ctf_file_t *ctfp = pap->pa_ctfp;
240 dtrace_hdl_t *dtp = pap->pa_dtp;
241 ctf_encoding_t e;
242 size_t size;
243 caddr_t addr = pap->pa_addr + off / NBBY;
244
245 if (ctf_type_encoding(ctfp, base, &e) == CTF_ERR) {
246 xo_emit("<{:warning}>", "unknown encoding");
247
248 /* Flush in order to ensure output is aligned properly */
249 xo_flush();
250 return;
251 }
252
253 /*
254 * This comes from MDB - it's not clear under what circumstances this
255 * would be found.
256 */
257 if (e.cte_format & CTF_INT_VARARGS) {
258 if (!dtp->dt_oformat)
259 (void)fprintf(fp, "...");
260 return;
261 }
262
263 /*
264 * We print this as a bitfield if the bit encoding indicates it's not
265 * an even power of two byte size, or is larger than 8 bytes.
266 */
267 size = e.cte_bits / NBBY;
268 if (size > 8 || (e.cte_bits % NBBY) != 0 || (size & (size - 1)) != 0) {
269 print_bitfield(pap, off, &e);
270 return;
271 }
272
273 /*
274 * If this is a character, print it out as such.
275 */
276 if (CTF_IS_CHAR(e)) {
277 char c = *(char *)addr;
278 if (isprint(c))
279 xo_emit("'{:value/%c}'", c);
280 else if (c == 0)
281 xo_emit("'\\{:value/0}'");
282 else
283 xo_emit("'\\{:value/%03o}'", c);
284
285 /* Flush in order to ensure output is aligned properly */
286 xo_flush();
287 return;
288 }
289
290 dt_print_hex(fp, addr, size);
291 }
292
293 /*
294 * Print a floating point (float, double, long double) value.
295 */
296 /* ARGSUSED */
297 static void
dt_print_float(ctf_id_t base,ulong_t off,dt_printarg_t * pap)298 dt_print_float(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
299 {
300 FILE *fp = pap->pa_file;
301 ctf_file_t *ctfp = pap->pa_ctfp;
302 ctf_encoding_t e;
303 caddr_t addr = pap->pa_addr + off / NBBY;
304 dtrace_hdl_t *dtp = pap->pa_dtp;
305
306 if (ctf_type_encoding(ctfp, base, &e) == 0) {
307 if (e.cte_format == CTF_FP_SINGLE &&
308 e.cte_bits == sizeof (float) * NBBY) {
309 xo_emit("{:value/%+.7e}", *((float *)addr));
310 } else if (e.cte_format == CTF_FP_DOUBLE &&
311 e.cte_bits == sizeof (double) * NBBY) {
312 xo_emit("{:value/%+.7e}", *((double *)addr));
313 } else if (e.cte_format == CTF_FP_LDOUBLE &&
314 e.cte_bits == sizeof (long double) * NBBY) {
315 xo_emit("{:value/%+.16LE}", *((long double *)addr));
316 } else {
317 xo_emit("<{:warning}>", "unknown encoding");
318 }
319 }
320 }
321
322 /*
323 * A pointer is generally printed as a fixed-size integer. If we have a
324 * function pointer, we try to look up its name.
325 */
326 static void
dt_print_ptr(ctf_id_t base,ulong_t off,dt_printarg_t * pap)327 dt_print_ptr(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
328 {
329 FILE *fp = pap->pa_file;
330 ctf_file_t *ctfp = pap->pa_ctfp;
331 caddr_t addr = pap->pa_addr + off / NBBY;
332 size_t size = ctf_type_size(ctfp, base);
333 ctf_id_t bid = ctf_type_reference(ctfp, base);
334 uint64_t pc;
335 dtrace_syminfo_t dts;
336 GElf_Sym sym;
337
338 if (bid == CTF_ERR || ctf_type_kind(ctfp, bid) != CTF_K_FUNCTION) {
339 dt_print_hex(fp, addr, size);
340 } else {
341 /* LINTED - alignment */
342 pc = *((uint64_t *)addr);
343 if (dtrace_lookup_by_addr(pap->pa_dtp, pc, &sym, &dts) != 0) {
344 dt_print_hex(fp, addr, size);
345 } else {
346 xo_emit("{:value/%s`%s}", dts.dts_object, dts.dts_name);
347 }
348 }
349 }
350
351 /*
352 * Print out an array. This is somewhat complex, as we must manually visit
353 * each member, and recursively invoke ctf_type_visit() for each member. If
354 * the members are non-structs, then we print them out directly:
355 *
356 * [ 0x14, 0x2e, 0 ]
357 *
358 * If they are structs, then we print out the necessary leading and trailing
359 * braces, to end up with:
360 *
361 * [
362 * type {
363 * ...
364 * },
365 * type {
366 * ...
367 * }
368 * ]
369 *
370 * We also use a heuristic to detect whether the array looks like a character
371 * array. If the encoding indicates it's a character, and we have all
372 * printable characters followed by a null byte, then we display it as a
373 * string:
374 *
375 * [ "string" ]
376 */
377 static void
dt_print_array(ctf_id_t base,ulong_t off,dt_printarg_t * pap)378 dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
379 {
380 FILE *fp = pap->pa_file;
381 ctf_file_t *ctfp = pap->pa_ctfp;
382 caddr_t addr = pap->pa_addr + off / NBBY;
383 char *str;
384 ctf_arinfo_t car;
385 ssize_t eltsize;
386 ctf_encoding_t e;
387 int i;
388 boolean_t isstring;
389 int kind;
390 ctf_id_t rtype;
391 dtrace_hdl_t *dtp = pap->pa_dtp;
392
393 if (ctf_array_info(ctfp, base, &car) == CTF_ERR) {
394 xo_emit("{:value/%p}", (void *)addr);
395 return;
396 }
397
398 if ((eltsize = ctf_type_size(ctfp, car.ctr_contents)) < 0 ||
399 (rtype = ctf_type_resolve(ctfp, car.ctr_contents)) == CTF_ERR ||
400 (kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR) {
401 xo_emit("<{:warning} {:type-identifier/%lu}>", "invalid type",
402 car.ctr_contents);
403 return;
404 }
405
406 /* see if this looks like a string */
407 isstring = B_FALSE;
408 if (kind == CTF_K_INTEGER &&
409 ctf_type_encoding(ctfp, rtype, &e) != CTF_ERR && CTF_IS_CHAR(e)) {
410 char c;
411 for (i = 0; i < car.ctr_nelems; i++) {
412 c = *((char *)addr + eltsize * i);
413 if (!isprint(c) || c == '\0')
414 break;
415 }
416
417 if (i != car.ctr_nelems && c == '\0')
418 isstring = B_TRUE;
419 }
420
421 /*
422 * As a slight aesthetic optimization, if we are a top-level type, then
423 * don't bother printing out the brackets. This lets print("foo") look
424 * like:
425 *
426 * string "foo"
427 *
428 * As D will internally represent this as a char[256] array.
429 */
430 if (dtp->dt_oformat) {
431 if (!isstring)
432 xo_open_list("value");
433 else {
434 str = malloc(car.ctr_nelems);
435 if (str == NULL)
436 return;
437 *str = 0;
438 }
439 } else {
440 if (!isstring || pap->pa_depth != 0)
441 (void)fprintf(fp, "[ ");
442
443 if (isstring)
444 (void)fprintf(fp, "\"");
445 }
446
447 for (i = 0; i < car.ctr_nelems; i++) {
448 if (isstring) {
449 char c = *((char *)addr + eltsize * i);
450 if (c == '\0') {
451 if (dtp->dt_oformat)
452 str[i] = 0;
453 break;
454 }
455
456 if (dtp->dt_oformat)
457 str[i] = c;
458 else
459 (void)fprintf(fp, "%c", c);
460 } else if (dtp->dt_oformat) {
461 dt_printarg_t pa = *pap;
462 pa.pa_nest += pap->pa_depth + 1;
463 pa.pa_depth = 0;
464 pa.pa_addr = addr + eltsize * i;
465
466 (void) ctf_type_visit(ctfp, car.ctr_contents,
467 dt_format_member, &pa);
468 } else {
469 /*
470 * Recursively invoke ctf_type_visit() on each member.
471 * We setup a new printarg struct with 'pa_nest' set to
472 * indicate that we are within a nested array.
473 */
474 dt_printarg_t pa = *pap;
475 pa.pa_nest += pap->pa_depth + 1;
476 pa.pa_depth = 0;
477 pa.pa_addr = addr + eltsize * i;
478 (void) ctf_type_visit(ctfp, car.ctr_contents,
479 dt_print_member, &pa);
480
481 dt_print_trailing_braces(&pa, 0);
482 if (i != car.ctr_nelems - 1)
483 (void) fprintf(fp, ", ");
484 else if (CTF_IS_STRUCTLIKE(kind))
485 (void) fprintf(fp, "\n");
486 }
487 }
488
489 if (dtp->dt_oformat) {
490 if (!isstring)
491 xo_close_list("value");
492 else {
493 xo_emit("{:value/%s}", str);
494 free(str);
495 }
496 } else {
497 if (isstring)
498 (void)fprintf(fp, "\"");
499
500 if (!isstring || pap->pa_depth != 0) {
501 if (CTF_IS_STRUCTLIKE(kind))
502 dt_print_indent(pap);
503 else
504 (void)fprintf(fp, " ");
505 (void)fprintf(fp, "]");
506 }
507 }
508 }
509
510 /*
511 * This isued by both structs and unions to print the leading brace.
512 */
513 /* ARGSUSED */
514 static void
dt_print_structlike(ctf_id_t id,ulong_t off,dt_printarg_t * pap)515 dt_print_structlike(ctf_id_t id, ulong_t off, dt_printarg_t *pap)
516 {
517 if (pap->pa_dtp->dt_oformat == DTRACE_OFORMAT_TEXT)
518 (void)fprintf(pap->pa_file, "{");
519 }
520
521 /*
522 * For enums, we try to print the enum name, and fall back to the value if it
523 * can't be determined. We do not do any fancy flag processing like mdb.
524 */
525 /* ARGSUSED */
526 static void
dt_print_enum(ctf_id_t base,ulong_t off,dt_printarg_t * pap)527 dt_print_enum(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
528 {
529 FILE *fp = pap->pa_file;
530 ctf_file_t *ctfp = pap->pa_ctfp;
531 const char *ename;
532 ssize_t size;
533 caddr_t addr = pap->pa_addr + off / NBBY;
534 int value = 0;
535 dtrace_hdl_t *dtp = pap->pa_dtp;
536
537 /*
538 * The C standard says that an enum will be at most the sizeof (int).
539 * But if all the values are less than that, the compiler can use a
540 * smaller size. Thanks standards.
541 */
542 size = ctf_type_size(ctfp, base);
543 switch (size) {
544 case sizeof (uint8_t):
545 value = *(uint8_t *)addr;
546 break;
547 case sizeof (uint16_t):
548 value = *(uint16_t *)addr;
549 break;
550 case sizeof (int32_t):
551 value = *(int32_t *)addr;
552 break;
553 default:
554 xo_emit("<{:warning} {:size/%u}>", "invalid enum size",
555 (uint_t)size);
556 return;
557 }
558
559 if ((ename = ctf_enum_name(ctfp, base, value)) != NULL) {
560 xo_emit("{:value/%s}", ename);
561 } else {
562 xo_emit("{:value/%d}", value);
563 }
564
565 /* Flush in order to ensure output is aligned properly */
566 xo_flush();
567 }
568
569 /*
570 * Forward declaration. There's not much to do here without the complete
571 * type information, so just print out this fact and drive on.
572 */
573 /* ARGSUSED */
574 static void
dt_print_tag(ctf_id_t base,ulong_t off,dt_printarg_t * pap)575 dt_print_tag(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
576 {
577 if (pap->pa_dtp->dt_oformat == DTRACE_OFORMAT_TEXT)
578 (void)fprintf(pap->pa_file, "<forward decl>");
579 }
580
581 typedef void dt_printarg_f(ctf_id_t, ulong_t, dt_printarg_t *);
582
583 static dt_printarg_f *const dt_printfuncs[] = {
584 dt_print_int, /* CTF_K_INTEGER */
585 dt_print_float, /* CTF_K_FLOAT */
586 dt_print_ptr, /* CTF_K_POINTER */
587 dt_print_array, /* CTF_K_ARRAY */
588 dt_print_ptr, /* CTF_K_FUNCTION */
589 dt_print_structlike, /* CTF_K_STRUCT */
590 dt_print_structlike, /* CTF_K_UNION */
591 dt_print_enum, /* CTF_K_ENUM */
592 dt_print_tag /* CTF_K_FORWARD */
593 };
594
595 static int
dt_format_member(const char * name,ctf_id_t id,ulong_t off,int depth,void * data)596 dt_format_member(const char *name, ctf_id_t id, ulong_t off, int depth,
597 void *data)
598 {
599 char type[DT_TYPE_NAMELEN];
600 int kind;
601 dt_printarg_t *pap = data;
602 FILE *fp = pap->pa_file;
603 ctf_file_t *ctfp = pap->pa_ctfp;
604 boolean_t arraymember;
605 boolean_t brief;
606 ctf_encoding_t e;
607 ctf_id_t rtype;
608
609 if ((rtype = ctf_type_resolve(ctfp, id)) == CTF_ERR ||
610 (kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR ||
611 kind < CTF_K_INTEGER || kind > CTF_K_FORWARD) {
612 xo_emit("{:name/%s} <{:warning} {:type-identifier/%lu}>"
613 " {:value/0x%llx}",
614 name, "invalid type", id, pap->pa_addr);
615 return (0);
616 }
617
618 dt_print_type_name(ctfp, id, type, sizeof (type));
619 xo_open_instance("type");
620 if (pap->pa_object) {
621 xo_emit("{:object-name/%s}", pap->pa_object);
622 /* Clear the object to avoid duplication */
623 pap->pa_object = NULL;
624 }
625
626 if (*name != 0)
627 xo_emit("{:member-name/%s}", name);
628 xo_emit("{:name/%s} {:ctfid/%ld}", type, id);
629 dt_printfuncs[kind - 1](rtype, off, pap);
630
631 xo_close_instance("type");
632 return (0);
633 }
634
635 /*
636 * Print one member of a structure. This callback is invoked from
637 * ctf_type_visit() recursively.
638 */
639 static int
dt_print_member(const char * name,ctf_id_t id,ulong_t off,int depth,void * data)640 dt_print_member(const char *name, ctf_id_t id, ulong_t off, int depth,
641 void *data)
642 {
643 char type[DT_TYPE_NAMELEN];
644 int kind;
645 dt_printarg_t *pap = data;
646 FILE *fp = pap->pa_file;
647 ctf_file_t *ctfp = pap->pa_ctfp;
648 boolean_t arraymember;
649 boolean_t brief;
650 ctf_encoding_t e;
651 ctf_id_t rtype;
652
653 dt_print_trailing_braces(pap, depth);
654 /*
655 * dt_print_trailing_braces() doesn't include the trailing newline; add
656 * it here if necessary.
657 */
658 if (depth < pap->pa_depth)
659 (void) fprintf(fp, "\n");
660 pap->pa_depth = depth;
661
662 if ((rtype = ctf_type_resolve(ctfp, id)) == CTF_ERR ||
663 (kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR ||
664 kind < CTF_K_INTEGER || kind > CTF_K_FORWARD) {
665 dt_print_indent(pap);
666 (void) fprintf(fp, "%s = <invalid type %lu>", name, id);
667 return (0);
668 }
669
670 dt_print_type_name(ctfp, id, type, sizeof (type));
671
672 arraymember = (pap->pa_nest != 0 && depth == 0);
673 brief = (arraymember && !CTF_IS_STRUCTLIKE(kind));
674
675 if (!brief) {
676 /*
677 * If this is a direct array member and a struct (otherwise
678 * brief would be true), then print a trailing newline, as the
679 * array printing code doesn't include it because it might be a
680 * simple type.
681 */
682 if (arraymember)
683 (void) fprintf(fp, "\n");
684 dt_print_indent(pap);
685
686 /* always print the type */
687 (void) fprintf(fp, "%s", type);
688 if (name[0] != '\0') {
689 /*
690 * For aesthetics, we don't include a space between the
691 * type name and member name if the type is a pointer.
692 * This will give us "void *foo =" instead of "void *
693 * foo =". Unions also have the odd behavior that the
694 * type name is returned as "union ", with a trailing
695 * space, so we also avoid printing a space if the type
696 * name already ends with a space.
697 */
698 if (type[strlen(type) - 1] != '*' &&
699 type[strlen(type) -1] != ' ') {
700 (void) fprintf(fp, " ");
701 }
702 (void) fprintf(fp, "%s", name);
703
704 /*
705 * If this looks like a bitfield, or is an integer not
706 * aligned on a byte boundary, print the number of
707 * bits after the name.
708 */
709 if (kind == CTF_K_INTEGER &&
710 ctf_type_encoding(ctfp, id, &e) == 0) {
711 ulong_t bits = e.cte_bits;
712 ulong_t size = bits / NBBY;
713
714 if (bits % NBBY != 0 ||
715 off % NBBY != 0 ||
716 size > 8 ||
717 size != ctf_type_size(ctfp, id)) {
718 (void) fprintf(fp, " :%lu", bits);
719 }
720 }
721
722 (void) fprintf(fp, " =");
723 }
724 (void) fprintf(fp, " ");
725 }
726
727 dt_printfuncs[kind - 1](rtype, off, pap);
728
729 /* direct simple array members are not separated by newlines */
730 if (!brief)
731 (void) fprintf(fp, "\n");
732
733 return (0);
734 }
735
736 static ctf_id_t
dt_print_prepare(dtrace_hdl_t * dtp,const char * typename,caddr_t addr,size_t len,dt_printarg_t * pa)737 dt_print_prepare(dtrace_hdl_t *dtp, const char *typename, caddr_t addr,
738 size_t len, dt_printarg_t *pa)
739 {
740 const char *s;
741 char *object;
742 ctf_id_t id;
743 dt_module_t *dmp;
744 ctf_file_t *ctfp;
745 int libid;
746
747 /*
748 * Split the fully-qualified type ID (module`id). This should
749 * always be the format, but if for some reason we don't find the
750 * expected value, return 0 to fall back to the generic trace()
751 * behavior. In the case of userland CTF modules this will actually be
752 * of the format (module`lib`id). This is due to the fact that those
753 * modules have multiple CTF containers which `lib` identifies.
754 */
755 for (s = typename; *s != '\0' && *s != '`'; s++)
756 ;
757
758 if (*s != '`')
759 return (CTF_ERR);
760
761 object = alloca(s - typename + 1);
762 bcopy(typename, object, s - typename);
763 object[s - typename] = '\0';
764 dmp = dt_module_lookup_by_name(dtp, object);
765 if (dmp == NULL)
766 return (CTF_ERR);
767
768 if (dmp->dm_pid != 0) {
769 libid = atoi(s + 1);
770 s = strchr(s + 1, '`');
771 if (s == NULL || libid > dmp->dm_nctflibs)
772 return (CTF_ERR);
773 ctfp = dmp->dm_libctfp[libid];
774 } else {
775 ctfp = dt_module_getctf(dtp, dmp);
776 }
777
778 id = atoi(s + 1);
779
780 /*
781 * Try to get the CTF kind for this id. If something has gone horribly
782 * wrong and we can't resolve the ID, bail out and let trace() do the
783 * work.
784 */
785 if (ctfp == NULL || ctf_type_kind(ctfp, id) == CTF_ERR)
786 return (CTF_ERR);
787
788 pa->pa_dtp = dtp;
789 pa->pa_addr = addr;
790 pa->pa_ctfp = ctfp;
791 pa->pa_nest = 0;
792 pa->pa_depth = 0;
793 pa->pa_object = strdup(object);
794 return (id);
795 }
796
797 /*
798 * Main print function invoked by dt_consume_cpu().
799 */
800 int
dtrace_print(dtrace_hdl_t * dtp,FILE * fp,const char * typename,caddr_t addr,size_t len)801 dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
802 caddr_t addr, size_t len)
803 {
804 dt_printarg_t pa;
805 ctf_id_t id;
806
807 id = dt_print_prepare(dtp, typename, addr, len, &pa);
808 if (id == CTF_ERR)
809 return (0);
810
811 pa.pa_file = fp;
812 (void) ctf_type_visit(pa.pa_ctfp, id, dt_print_member, &pa);
813
814 dt_print_trailing_braces(&pa, 0);
815 dt_free(dtp, (void *)pa.pa_object);
816
817 return (len);
818 }
819
820 /*
821 * Main format function invoked by dt_consume_cpu().
822 */
823 int
dtrace_format_print(dtrace_hdl_t * dtp,FILE * fp,const char * typename,caddr_t addr,size_t len)824 dtrace_format_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
825 caddr_t addr, size_t len)
826 {
827 dt_printarg_t pa;
828 ctf_id_t id;
829 char toplevel[1024];
830
831 id = dt_print_prepare(dtp, typename, addr, len, &pa);
832 if (id == CTF_ERR)
833 return (0);
834
835 if (ctf_type_name(pa.pa_ctfp, id, toplevel, sizeof(toplevel)) < 0)
836 return (0);
837
838 xo_open_list("type");
839 (void) ctf_type_visit(pa.pa_ctfp, id, dt_format_member, &pa);
840 xo_close_list("type");
841 dt_free(dtp, (void *)pa.pa_object);
842
843 return (len);
844 }
845
846