xref: /openbsd-src/sys/ddb/db_ctf.c (revision 949c1c4ec8cc03255798b09f6078e1d0aed70a6a)
1 /*	$OpenBSD: db_ctf.c,v 1.35 2024/11/07 16:02:29 miod Exp $	*/
2 
3 /*
4  * Copyright (c) 2016-2017 Martin Pieuchot
5  * Copyright (c) 2016 Jasper Lievisse Adriaanse <jasper@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/param.h>
21 #include <sys/stdint.h>
22 #include <sys/systm.h>
23 #include <sys/exec.h>
24 
25 #include <machine/db_machdep.h>
26 
27 #include <ddb/db_extern.h>
28 #include <ddb/db_command.h>
29 #include <ddb/db_elf.h>
30 #include <ddb/db_lex.h>
31 #include <ddb/db_output.h>
32 #include <ddb/db_sym.h>
33 #include <ddb/db_access.h>
34 
35 #include <sys/exec_elf.h>
36 #include <sys/ctf.h>
37 #include <sys/malloc.h>
38 #include <lib/libz/zlib.h>
39 
40 extern db_symtab_t		db_symtab;
41 
42 struct ddb_ctf {
43 	struct ctf_header	*cth;
44 	const char		*rawctf;	/* raw .SUNW_ctf section */
45 	size_t			 rawctflen;	/* raw .SUNW_ctf section size */
46 	const char		*data;		/* decompressed CTF data */
47 	size_t			 dlen;		/* decompressed CTF data size */
48 	const char		*strtab;	/* ELF string table */
49 	uint32_t		 ctf_found;
50 };
51 
52 struct ddb_ctf db_ctf;
53 
54 static const char	*db_ctf_off2name(uint32_t);
55 static Elf_Sym		*db_ctf_idx2sym(size_t *, uint8_t);
56 static char		*db_ctf_decompress(const char *, size_t, size_t);
57 
58 uint32_t		 db_ctf_type_len(const struct ctf_type *);
59 size_t			 db_ctf_type_size(const struct ctf_type *);
60 const struct ctf_type	*db_ctf_type_by_name(const char *, unsigned int);
61 const struct ctf_type	*db_ctf_type_by_symbol(Elf_Sym *);
62 const struct ctf_type	*db_ctf_type_by_index(uint16_t);
63 void			 db_ctf_pprint(const struct ctf_type *, vaddr_t);
64 void			 db_ctf_pprint_struct(const struct ctf_type *, vaddr_t);
65 void			 db_ctf_pprint_enum(const struct ctf_type *, vaddr_t);
66 void			 db_ctf_pprint_ptr(const struct ctf_type *, vaddr_t);
67 
68 /*
69  * Entrypoint to verify CTF presence, initialize the header, decompress
70  * the data, etc.
71  */
72 void
73 db_ctf_init(void)
74 {
75 	db_symtab_t *stab = &db_symtab;
76 	size_t rawctflen;
77 
78 	/* Assume nothing was correct found until proven otherwise. */
79 	db_ctf.ctf_found = 0;
80 
81 	if (stab->private == NULL)
82 		return;
83 
84 	db_ctf.strtab = db_elf_find_strtab(stab);
85 	if (db_ctf.strtab == NULL)
86 		return;
87 
88 	db_ctf.rawctf = db_elf_find_section(stab, &rawctflen, ELF_CTF);
89 	if (db_ctf.rawctf == NULL)
90 		return;
91 
92 	db_ctf.rawctflen = rawctflen;
93 	db_ctf.cth = (struct ctf_header *)db_ctf.rawctf;
94 	db_ctf.dlen = db_ctf.cth->cth_stroff + db_ctf.cth->cth_strlen;
95 
96 	if ((db_ctf.cth->cth_flags & CTF_F_COMPRESS) == 0) {
97 		db_printf("unsupported non-compressed CTF section\n");
98 		return;
99 	}
100 
101 	/* Now decompress the section, take into account to skip the header */
102 	db_ctf.data = db_ctf_decompress(db_ctf.rawctf + sizeof(*db_ctf.cth),
103 	    db_ctf.rawctflen - sizeof(*db_ctf.cth), db_ctf.dlen);
104 	if (db_ctf.data == NULL)
105 		return;
106 
107 	/* We made it this far, everything seems fine. */
108 	db_ctf.ctf_found = 1;
109 }
110 
111 /*
112  * Convert an index to a symbol name while ensuring the type is matched.
113  * It must be noted this only works if the CTF table has the same order
114  * as the symbol table.
115  */
116 Elf_Sym *
117 db_ctf_idx2sym(size_t *idx, uint8_t type)
118 {
119 	Elf_Sym *symp, *symtab_start, *symtab_end;
120 	size_t i = *idx + 1;
121 
122 	symtab_start = STAB_TO_SYMSTART(&db_symtab);
123 	symtab_end = STAB_TO_SYMEND(&db_symtab);
124 
125 	for (symp = &symtab_start[i]; symp < symtab_end; i++, symp++) {
126 		if (ELF_ST_TYPE(symp->st_info) != type)
127 			continue;
128 
129 		*idx = i;
130 		return symp;
131 	}
132 
133 	return NULL;
134 }
135 
136 /*
137  * For a given function name, return the number of arguments.
138  */
139 int
140 db_ctf_func_numargs(Elf_Sym *st)
141 {
142 	Elf_Sym			*symp;
143 	uint16_t		*fstart, *fend;
144 	uint16_t		*fsp, kind, vlen;
145 	size_t			 i, idx = 0;
146 
147 	if (!db_ctf.ctf_found || st == NULL)
148 		return -1;
149 
150 	fstart = (uint16_t *)(db_ctf.data + db_ctf.cth->cth_funcoff);
151 	fend = (uint16_t *)(db_ctf.data + db_ctf.cth->cth_typeoff);
152 
153 	fsp = fstart;
154 	while (fsp < fend) {
155 		symp = db_ctf_idx2sym(&idx, STT_FUNC);
156 		if (symp == NULL)
157 			break;
158 
159 		kind = CTF_INFO_KIND(*fsp);
160 		vlen = CTF_INFO_VLEN(*fsp);
161 		fsp++;
162 
163 		if (kind == CTF_K_UNKNOWN && vlen == 0)
164 			continue;
165 
166 		/* Skip return type */
167 		fsp++;
168 
169 		/* Skip argument types */
170 		for (i = 0; i < vlen; i++)
171 			fsp++;
172 
173 		if (symp == st)
174 			return vlen;
175 	}
176 
177 	return 0;
178 }
179 
180 /*
181  * Return the length of the type record in the CTF section.
182  */
183 uint32_t
184 db_ctf_type_len(const struct ctf_type *ctt)
185 {
186 	uint16_t		 kind, vlen, i;
187 	uint32_t		 tlen;
188 	uint64_t		 size;
189 
190 	kind = CTF_INFO_KIND(ctt->ctt_info);
191 	vlen = CTF_INFO_VLEN(ctt->ctt_info);
192 
193 	if (ctt->ctt_size <= CTF_MAX_SIZE) {
194 		size = ctt->ctt_size;
195 		tlen = sizeof(struct ctf_stype);
196 	} else {
197 		size = CTF_TYPE_LSIZE(ctt);
198 		tlen = sizeof(struct ctf_type);
199 	}
200 
201 	switch (kind) {
202 	case CTF_K_UNKNOWN:
203 	case CTF_K_FORWARD:
204 		break;
205 	case CTF_K_INTEGER:
206 		tlen += sizeof(uint32_t);
207 		break;
208 	case CTF_K_FLOAT:
209 		tlen += sizeof(uint32_t);
210 		break;
211 	case CTF_K_ARRAY:
212 		tlen += sizeof(struct ctf_array);
213 		break;
214 	case CTF_K_FUNCTION:
215 		tlen += (vlen + (vlen & 1)) * sizeof(uint16_t);
216 		break;
217 	case CTF_K_STRUCT:
218 	case CTF_K_UNION:
219 		if (size < CTF_LSTRUCT_THRESH) {
220 			for (i = 0; i < vlen; i++) {
221 				tlen += sizeof(struct ctf_member);
222 			}
223 		} else {
224 			for (i = 0; i < vlen; i++) {
225 				tlen += sizeof(struct ctf_lmember);
226 			}
227 		}
228 		break;
229 	case CTF_K_ENUM:
230 		for (i = 0; i < vlen; i++) {
231 			tlen += sizeof(struct ctf_enum);
232 		}
233 		break;
234 	case CTF_K_POINTER:
235 	case CTF_K_TYPEDEF:
236 	case CTF_K_VOLATILE:
237 	case CTF_K_CONST:
238 	case CTF_K_RESTRICT:
239 		break;
240 	default:
241 		return 0;
242 	}
243 
244 	return tlen;
245 }
246 
247 /*
248  * Return the size of the type.
249  */
250 size_t
251 db_ctf_type_size(const struct ctf_type *ctt)
252 {
253 	vaddr_t			 taddr = (vaddr_t)ctt;
254 	const struct ctf_type	*ref;
255 	const struct ctf_array	*arr;
256 	size_t			 tlen = 0;
257 	uint16_t		 kind;
258 	uint32_t		 toff;
259 	uint64_t		 size;
260 
261 	kind = CTF_INFO_KIND(ctt->ctt_info);
262 
263 	if (ctt->ctt_size <= CTF_MAX_SIZE) {
264 		size = ctt->ctt_size;
265 		toff = sizeof(struct ctf_stype);
266 	} else {
267 		size = CTF_TYPE_LSIZE(ctt);
268 		toff = sizeof(struct ctf_type);
269 	}
270 
271 	switch (kind) {
272 	case CTF_K_UNKNOWN:
273 	case CTF_K_FORWARD:
274 		break;
275 	case CTF_K_INTEGER:
276 	case CTF_K_FLOAT:
277 		tlen = size;
278 		break;
279 	case CTF_K_ARRAY:
280 		arr = (struct ctf_array *)(taddr + toff);
281 		ref = db_ctf_type_by_index(arr->cta_contents);
282 		tlen = arr->cta_nelems * db_ctf_type_size(ref);
283 		break;
284 	case CTF_K_FUNCTION:
285 		tlen = 0;
286 		break;
287 	case CTF_K_STRUCT:
288 	case CTF_K_UNION:
289 	case CTF_K_ENUM:
290 		tlen = size;
291 		break;
292 	case CTF_K_POINTER:
293 		tlen = sizeof(void *);
294 		break;
295 	case CTF_K_TYPEDEF:
296 	case CTF_K_VOLATILE:
297 	case CTF_K_CONST:
298 	case CTF_K_RESTRICT:
299 		ref = db_ctf_type_by_index(ctt->ctt_type);
300 		tlen = db_ctf_type_size(ref);
301 		break;
302 	default:
303 		return 0;
304 	}
305 
306 	return tlen;
307 }
308 
309 /*
310  * Return the CTF type associated to an ELF symbol.
311  */
312 const struct ctf_type *
313 db_ctf_type_by_symbol(Elf_Sym *st)
314 {
315 	Elf_Sym			*symp;
316 	uint32_t		 objtoff;
317 	uint16_t		*dsp;
318 	size_t			 idx = 0;
319 
320 	if (!db_ctf.ctf_found || st == NULL)
321 		return NULL;
322 
323 	objtoff = db_ctf.cth->cth_objtoff;
324 
325 	while (objtoff < db_ctf.cth->cth_funcoff) {
326 		dsp = (uint16_t *)(db_ctf.data + objtoff);
327 
328 		symp = db_ctf_idx2sym(&idx, STT_OBJECT);
329 		if (symp == NULL)
330 			break;
331 		if (symp == st)
332 			return db_ctf_type_by_index(*dsp);
333 
334 		objtoff += sizeof(*dsp);
335 	}
336 
337 	return NULL;
338 }
339 
340 const struct ctf_type *
341 db_ctf_type_by_name(const char *name, unsigned int kind)
342 {
343 	struct ctf_header	*cth;
344 	const struct ctf_type   *ctt;
345 	const char		*tname;
346 	uint32_t		 off, toff;
347 
348 	if (!db_ctf.ctf_found)
349 		return (NULL);
350 
351 	cth = db_ctf.cth;
352 
353 	for (off = cth->cth_typeoff; off < cth->cth_stroff; off += toff) {
354 		ctt = (struct ctf_type *)(db_ctf.data + off);
355 		toff = db_ctf_type_len(ctt);
356 		if (toff == 0) {
357 			db_printf("incorrect type at offset %u", off);
358 			break;
359 		}
360 
361 		if (CTF_INFO_KIND(ctt->ctt_info) != kind)
362 			continue;
363 
364 		tname = db_ctf_off2name(ctt->ctt_name);
365 		if (tname == NULL)
366 			continue;
367 
368 		if (strcmp(name, tname) == 0)
369 			return (ctt);
370 	}
371 
372 	return (NULL);
373 }
374 
375 /*
376  * Return the CTF type corresponding to a given index in the type section.
377  */
378 const struct ctf_type *
379 db_ctf_type_by_index(uint16_t index)
380 {
381 	uint32_t		 offset = db_ctf.cth->cth_typeoff;
382 	uint16_t		 idx = 1;
383 
384 	if (!db_ctf.ctf_found)
385 		return NULL;
386 
387 	while (offset < db_ctf.cth->cth_stroff) {
388 		const struct ctf_type   *ctt;
389 		uint32_t		 toff;
390 
391 		ctt = (struct ctf_type *)(db_ctf.data + offset);
392 		if (idx == index)
393 			return ctt;
394 
395 		toff = db_ctf_type_len(ctt);
396 		if (toff == 0) {
397 			db_printf("incorrect type at offset %u", offset);
398 			break;
399 		}
400 		offset += toff;
401 		idx++;
402 	}
403 
404 	return NULL;
405 }
406 
407 /*
408  * Pretty print `addr'.
409  */
410 void
411 db_ctf_pprint(const struct ctf_type *ctt, vaddr_t addr)
412 {
413 	vaddr_t			 taddr = (vaddr_t)ctt;
414 	const struct ctf_type	*ref;
415 	const struct ctf_array	*arr;
416 	uint16_t		 kind;
417 	uint32_t		 eob, toff, i;
418 	db_expr_t		 val;
419 	size_t			 elm_size;
420 
421 	if (ctt == NULL)
422 		return;
423 
424 	kind = CTF_INFO_KIND(ctt->ctt_info);
425 	if (ctt->ctt_size <= CTF_MAX_SIZE)
426 		toff = sizeof(struct ctf_stype);
427 	else
428 		toff = sizeof(struct ctf_type);
429 
430 	switch (kind) {
431 	case CTF_K_ARRAY:
432 		arr = (struct ctf_array *)(taddr + toff);
433 		ref = db_ctf_type_by_index(arr->cta_contents);
434 		elm_size = db_ctf_type_size(ref);
435 		db_printf("[");
436 		for (i = 0; i < arr->cta_nelems; i++) {
437 			db_ctf_pprint(ref, addr + i * elm_size);
438 			if (i + 1 < arr->cta_nelems)
439 				db_printf(",");
440 		}
441 		db_printf("]");
442 		break;
443 	case CTF_K_ENUM:
444 		db_ctf_pprint_enum(ctt, addr);
445 		break;
446 	case CTF_K_FLOAT:
447 	case CTF_K_FUNCTION:
448 		val = db_get_value(addr, sizeof(val), 0);
449 		db_printf("%lx", (unsigned long)val);
450 		break;
451 	case CTF_K_INTEGER:
452 		eob = db_get_value((taddr + toff), sizeof(eob), 0);
453 		switch (CTF_INT_BITS(eob)) {
454 #ifndef __LP64__
455 		case 64: {
456 			uint64_t val64;
457 #if BYTE_ORDER == LITTLE_ENDIAN
458 			val64 = db_get_value(addr + 4, CTF_INT_BITS(eob) / 8,
459 			   CTF_INT_ENCODING(eob) & CTF_INT_SIGNED);
460 			val64 <<= 32;
461 			val64 |= db_get_value(addr, CTF_INT_BITS(eob) / 8, 0);
462 #else
463 			val64 = db_get_value(addr, CTF_INT_BITS(eob) / 8,
464 			   CTF_INT_ENCODING(eob) & CTF_INT_SIGNED);
465 			val64 <<= 32;
466 			val64 |= db_get_value(addr + 4, CTF_INT_BITS(eob) / 8,
467 			    0);
468 #endif
469 			if (CTF_INT_ENCODING(eob) & CTF_INT_SIGNED)
470 				db_printf("%lld", val64);
471 			else
472 				db_printf("%llu", val64);
473 			break;
474 		}
475 #endif
476 		default:
477 			val = db_get_value(addr, CTF_INT_BITS(eob) / 8,
478 			   CTF_INT_ENCODING(eob) & CTF_INT_SIGNED);
479 			if (CTF_INT_ENCODING(eob) & CTF_INT_SIGNED)
480 				db_printf("%ld", val);
481 			else
482 				db_printf("%lu", val);
483 			break;
484 		}
485 		break;
486 	case CTF_K_STRUCT:
487 	case CTF_K_UNION:
488 		db_ctf_pprint_struct(ctt, addr);
489 		break;
490 	case CTF_K_POINTER:
491 		db_ctf_pprint_ptr(ctt, addr);
492 		break;
493 	case CTF_K_TYPEDEF:
494 	case CTF_K_VOLATILE:
495 	case CTF_K_CONST:
496 	case CTF_K_RESTRICT:
497 		ref = db_ctf_type_by_index(ctt->ctt_type);
498 		db_ctf_pprint(ref, addr);
499 		break;
500 	case CTF_K_UNKNOWN:
501 	case CTF_K_FORWARD:
502 	default:
503 		break;
504 	}
505 }
506 
507 void
508 db_ctf_pprint_struct(const struct ctf_type *ctt, vaddr_t addr)
509 {
510 	const char		*name, *p = (const char *)ctt;
511 	const struct ctf_type	*ref;
512 	uint32_t		 toff;
513 	uint64_t		 size;
514 	uint16_t		 i, vlen;
515 
516 	vlen = CTF_INFO_VLEN(ctt->ctt_info);
517 
518 	if (ctt->ctt_size <= CTF_MAX_SIZE) {
519 		size = ctt->ctt_size;
520 		toff = sizeof(struct ctf_stype);
521 	} else {
522 		size = CTF_TYPE_LSIZE(ctt);
523 		toff = sizeof(struct ctf_type);
524 	}
525 
526 	db_printf("{");
527 	if (size < CTF_LSTRUCT_THRESH) {
528 		for (i = 0; i < vlen; i++) {
529 			struct ctf_member	*ctm;
530 
531 			ctm = (struct ctf_member *)(p + toff);
532 			toff += sizeof(struct ctf_member);
533 
534 			name = db_ctf_off2name(ctm->ctm_name);
535 			if (name != NULL)
536 				db_printf("%s = ", name);
537 			ref = db_ctf_type_by_index(ctm->ctm_type);
538 			db_ctf_pprint(ref, addr + ctm->ctm_offset / 8);
539 			if (i < vlen - 1)
540 				db_printf(", ");
541 		}
542 	} else {
543 		for (i = 0; i < vlen; i++) {
544 			struct ctf_lmember	*ctlm;
545 
546 			ctlm = (struct ctf_lmember *)(p + toff);
547 			toff += sizeof(struct ctf_lmember);
548 
549 			name = db_ctf_off2name(ctlm->ctlm_name);
550 			if (name != NULL)
551 				db_printf("%s = ", name);
552 			ref = db_ctf_type_by_index(ctlm->ctlm_type);
553 			db_ctf_pprint(ref, addr +
554 			    CTF_LMEM_OFFSET(ctlm) / 8);
555 			if (i < vlen - 1)
556 				db_printf(", ");
557 		}
558 	}
559 	db_printf("}");
560 }
561 
562 void
563 db_ctf_pprint_enum(const struct ctf_type *ctt, vaddr_t addr)
564 {
565 	const char		*name = NULL, *p = (const char *)ctt;
566 	struct ctf_enum		*cte;
567 	uint32_t		 toff;
568 	int32_t			 val;
569 	uint16_t		 i, vlen;
570 
571 	vlen = CTF_INFO_VLEN(ctt->ctt_info);
572 	toff = sizeof(struct ctf_stype);
573 
574 	val = (int32_t)db_get_value(addr, sizeof(val), 1);
575 	for (i = 0; i < vlen; i++) {
576 		cte = (struct ctf_enum *)(p + toff);
577 		toff += sizeof(*cte);
578 
579 		if (val == cte->cte_value) {
580 			name = db_ctf_off2name(cte->cte_name);
581 			break;
582 		}
583 	}
584 
585 	if (name != NULL)
586 		db_printf("%s", name);
587 	else
588 		db_printf("#%d", val);
589 }
590 
591 void
592 db_ctf_pprint_ptr(const struct ctf_type *ctt, vaddr_t addr)
593 {
594 	const char		*name, *modif = "";
595 	const struct ctf_type	*ref;
596 	uint16_t		 kind;
597 	unsigned long		 ptr;
598 
599 	ref = db_ctf_type_by_index(ctt->ctt_type);
600 	kind = CTF_INFO_KIND(ref->ctt_info);
601 
602 	switch (kind) {
603 	case CTF_K_VOLATILE:
604 		modif = "volatile ";
605 		ref = db_ctf_type_by_index(ref->ctt_type);
606 		break;
607 	case CTF_K_CONST:
608 		modif = "const ";
609 		ref = db_ctf_type_by_index(ref->ctt_type);
610 		break;
611 	case CTF_K_STRUCT:
612 		modif = "struct ";
613 		break;
614 	case CTF_K_UNION:
615 		modif = "union ";
616 		break;
617 	default:
618 		break;
619 	}
620 
621 	name = db_ctf_off2name(ref->ctt_name);
622 	if (name != NULL)
623 		db_printf("(%s%s *)", modif, name);
624 
625 	ptr = (unsigned long)db_get_value(addr, sizeof(ptr), 0);
626 
627 	db_printf("0x%lx", ptr);
628 }
629 
630 static const char *
631 db_ctf_off2name(uint32_t offset)
632 {
633 	const char		*name;
634 
635 	if (!db_ctf.ctf_found)
636 		return NULL;
637 
638 	if (CTF_NAME_STID(offset) != CTF_STRTAB_0)
639 		return "external";
640 
641 	if (CTF_NAME_OFFSET(offset) >= db_ctf.cth->cth_strlen)
642 		return "exceeds strlab";
643 
644 	if (db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset) >= db_ctf.dlen)
645 		return "invalid";
646 
647 	name = db_ctf.data + db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset);
648 	if (*name == '\0')
649 		return NULL;
650 
651 	return name;
652 }
653 
654 static char *
655 db_ctf_decompress(const char *buf, size_t size, size_t len)
656 {
657 	z_stream		 stream;
658 	char			*data;
659 	int			 error;
660 
661 	data = malloc(len, M_TEMP, M_WAITOK|M_ZERO|M_CANFAIL);
662 	if (data == NULL)
663 		return NULL;
664 
665 	memset(&stream, 0, sizeof(stream));
666 	stream.next_in = (void *)buf;
667 	stream.avail_in = size;
668 	stream.next_out = data;
669 	stream.avail_out = len;
670 
671 	if ((error = inflateInit(&stream)) != Z_OK) {
672 		db_printf("zlib inflateInit failed: %s", zError(error));
673 		goto exit;
674 	}
675 
676 	if ((error = inflate(&stream, Z_FINISH)) != Z_STREAM_END) {
677 		db_printf("zlib inflate failed: %s", zError(error));
678 		inflateEnd(&stream);
679 		goto exit;
680 	}
681 
682 	if ((error = inflateEnd(&stream)) != Z_OK) {
683 		db_printf("zlib inflateEnd failed: %s", zError(error));
684 		goto exit;
685 	}
686 
687 	if (stream.total_out != len) {
688 		db_printf("decompression failed: %lu != %zu",
689 		    stream.total_out, len);
690 		goto exit;
691 	}
692 
693 	return data;
694 
695 exit:
696 	free(data, M_DEVBUF, len);
697 	return NULL;
698 }
699 
700 /*
701  * pprint <symbol name>
702  */
703 void
704 db_ctf_pprint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
705 {
706 	Elf_Sym *st;
707 	const struct ctf_type *ctt;
708 	int t;
709 
710 	if (!db_ctf.ctf_found) {
711 		db_printf("No CTF data found\n");
712 		db_flush_lex();
713 		return;
714 	}
715 
716 	/*
717 	 * Read the struct name from the debugger input.
718 	 */
719 	t = db_read_token();
720 	if (t != tIDENT) {
721 		db_printf("Bad symbol name\n");
722 		db_flush_lex();
723 		return;
724 	}
725 
726 	if ((st = db_symbol_by_name(db_tok_string, &addr)) == NULL) {
727 		db_printf("Symbol not found %s\n", db_tok_string);
728 		db_flush_lex();
729 		return;
730 	}
731 
732 	if ((ctt = db_ctf_type_by_symbol(st)) == NULL) {
733 		modif[0] = '\0';
734 		db_print_cmd(addr, 0, 0, modif);
735 		db_flush_lex();
736 		return;
737 	}
738 
739 	db_printf("%s:\t", db_tok_string);
740 	db_ctf_pprint(ctt, addr);
741 	db_printf("\n");
742 }
743 
744 /*
745  * show struct <struct name> [addr]: displays the data starting at addr
746  * (`dot' if unspecified) as a struct of the given type.
747  */
748 void
749 db_ctf_show_struct(db_expr_t addr, int have_addr, db_expr_t count,
750     char *modifiers)
751 {
752 	const struct ctf_type *ctt;
753 	const char *name;
754 	uint64_t sz;
755 	int t;
756 
757 	/*
758 	 * Read the struct name from the debugger input.
759 	 */
760 	t = db_read_token();
761 	if (t != tIDENT) {
762 		db_printf("Bad struct name\n");
763 		db_flush_lex();
764 		return;
765 	}
766 	name = db_tok_string;
767 
768 	ctt = db_ctf_type_by_name(name, CTF_K_STRUCT);
769 	if (ctt == NULL) {
770 		db_printf("unknown struct %s\n", name);
771 		db_flush_lex();
772 		return;
773 	}
774 
775 	/*
776 	 * Read the address, if any, from the debugger input.
777 	 * In that case, update `dot' value.
778 	 */
779 	if (db_expression(&addr)) {
780 		db_dot = (vaddr_t)addr;
781 		db_last_addr = db_dot;
782 	} else
783 		addr = (db_expr_t)db_dot;
784 
785 	db_skip_to_eol();
786 
787 	/*
788 	 * Display the structure contents.
789 	 */
790 	sz = (ctt->ctt_size <= CTF_MAX_SIZE) ?
791 	    ctt->ctt_size : CTF_TYPE_LSIZE(ctt);
792 	db_printf("struct %s at %p (%llu bytes) ", name, (void *)addr, sz);
793 	db_ctf_pprint_struct(ctt, addr);
794 }
795