FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_ctf.c
1 /* $OpenBSD: db_ctf.c,v 1.33 2022/08/14 14:57:38 millert 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 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 const struct ctf_type *db_ctf_type_by_name(const char *, unsigned int);
59 const struct ctf_type *db_ctf_type_by_symbol(Elf_Sym *);
60 const struct ctf_type *db_ctf_type_by_index(uint16_t);
61 void db_ctf_pprint(const struct ctf_type *, vaddr_t);
62 void db_ctf_pprint_struct(const struct ctf_type *, vaddr_t);
63 void db_ctf_pprint_ptr(const struct ctf_type *, vaddr_t);
64
65 /*
66 * Entrypoint to verify CTF presence, initialize the header, decompress
67 * the data, etc.
68 */
69 void
70 db_ctf_init(void)
71 {
72 db_symtab_t *stab = &db_symtab;
73 size_t rawctflen;
74
75 /* Assume nothing was correct found until proven otherwise. */
76 db_ctf.ctf_found = 0;
77
78 if (stab->private == NULL)
79 return;
80
81 db_ctf.strtab = db_elf_find_strtab(stab);
82 if (db_ctf.strtab == NULL)
83 return;
84
85 db_ctf.rawctf = db_elf_find_section(stab, &rawctflen, ELF_CTF);
86 if (db_ctf.rawctf == NULL)
87 return;
88
89 db_ctf.rawctflen = rawctflen;
90 db_ctf.cth = (struct ctf_header *)db_ctf.rawctf;
91 db_ctf.dlen = db_ctf.cth->cth_stroff + db_ctf.cth->cth_strlen;
92
93 if ((db_ctf.cth->cth_flags & CTF_F_COMPRESS) == 0) {
94 db_printf("unsupported non-compressed CTF section\n");
95 return;
96 }
97
98 /* Now decompress the section, take into account to skip the header */
99 db_ctf.data = db_ctf_decompress(db_ctf.rawctf + sizeof(*db_ctf.cth),
100 db_ctf.rawctflen - sizeof(*db_ctf.cth), db_ctf.dlen);
101 if (db_ctf.data == NULL)
102 return;
103
104 /* We made it this far, everything seems fine. */
105 db_ctf.ctf_found = 1;
106 }
107
108 /*
109 * Convert an index to a symbol name while ensuring the type is matched.
110 * It must be noted this only works if the CTF table has the same order
111 * as the symbol table.
112 */
113 Elf_Sym *
114 db_ctf_idx2sym(size_t *idx, uint8_t type)
115 {
116 Elf_Sym *symp, *symtab_start, *symtab_end;
117 size_t i = *idx + 1;
118
119 symtab_start = STAB_TO_SYMSTART(&db_symtab);
120 symtab_end = STAB_TO_SYMEND(&db_symtab);
121
122 for (symp = &symtab_start[i]; symp < symtab_end; i++, symp++) {
123 if (ELF_ST_TYPE(symp->st_info) != type)
124 continue;
125
126 *idx = i;
127 return symp;
128 }
129
130 return NULL;
131 }
132
133 /*
134 * For a given function name, return the number of arguments.
135 */
136 int
137 db_ctf_func_numargs(Elf_Sym *st)
138 {
139 Elf_Sym *symp;
140 uint16_t *fstart, *fend;
141 uint16_t *fsp, kind, vlen;
142 size_t i, idx = 0;
143
144 if (!db_ctf.ctf_found || st == NULL)
145 return -1;
146
147 fstart = (uint16_t *)(db_ctf.data + db_ctf.cth->cth_funcoff);
148 fend = (uint16_t *)(db_ctf.data + db_ctf.cth->cth_typeoff);
149
150 fsp = fstart;
151 while (fsp < fend) {
152 symp = db_ctf_idx2sym(&idx, STT_FUNC);
153 if (symp == NULL)
154 break;
155
156 kind = CTF_INFO_KIND(*fsp);
157 vlen = CTF_INFO_VLEN(*fsp);
158 fsp++;
159
160 if (kind == CTF_K_UNKNOWN && vlen == 0)
161 continue;
162
163 /* Skip return type */
164 fsp++;
165
166 /* Skip argument types */
167 for (i = 0; i < vlen; i++)
168 fsp++;
169
170 if (symp == st)
171 return vlen;
172 }
173
174 return 0;
175 }
176
177 /*
178 * Return the length of the type record in the CTF section.
179 */
180 uint32_t
181 db_ctf_type_len(const struct ctf_type *ctt)
182 {
183 uint16_t kind, vlen, i;
184 uint32_t tlen;
185 uint64_t size;
186
187 kind = CTF_INFO_KIND(ctt->ctt_info);
188 vlen = CTF_INFO_VLEN(ctt->ctt_info);
189
190 if (ctt->ctt_size <= CTF_MAX_SIZE) {
191 size = ctt->ctt_size;
192 tlen = sizeof(struct ctf_stype);
193 } else {
194 size = CTF_TYPE_LSIZE(ctt);
195 tlen = sizeof(struct ctf_type);
196 }
197
198 switch (kind) {
199 case CTF_K_UNKNOWN:
200 case CTF_K_FORWARD:
201 break;
202 case CTF_K_INTEGER:
203 tlen += sizeof(uint32_t);
204 break;
205 case CTF_K_FLOAT:
206 tlen += sizeof(uint32_t);
207 break;
208 case CTF_K_ARRAY:
209 tlen += sizeof(struct ctf_array);
210 break;
211 case CTF_K_FUNCTION:
212 tlen += (vlen + (vlen & 1)) * sizeof(uint16_t);
213 break;
214 case CTF_K_STRUCT:
215 case CTF_K_UNION:
216 if (size < CTF_LSTRUCT_THRESH) {
217 for (i = 0; i < vlen; i++) {
218 tlen += sizeof(struct ctf_member);
219 }
220 } else {
221 for (i = 0; i < vlen; i++) {
222 tlen += sizeof(struct ctf_lmember);
223 }
224 }
225 break;
226 case CTF_K_ENUM:
227 for (i = 0; i < vlen; i++) {
228 tlen += sizeof(struct ctf_enum);
229 }
230 break;
231 case CTF_K_POINTER:
232 case CTF_K_TYPEDEF:
233 case CTF_K_VOLATILE:
234 case CTF_K_CONST:
235 case CTF_K_RESTRICT:
236 break;
237 default:
238 return 0;
239 }
240
241 return tlen;
242 }
243
244 /*
245 * Return the CTF type associated to an ELF symbol.
246 */
247 const struct ctf_type *
248 db_ctf_type_by_symbol(Elf_Sym *st)
249 {
250 Elf_Sym *symp;
251 uint32_t objtoff;
252 uint16_t *dsp;
253 size_t idx = 0;
254
255 if (!db_ctf.ctf_found || st == NULL)
256 return NULL;
257
258 objtoff = db_ctf.cth->cth_objtoff;
259
260 while (objtoff < db_ctf.cth->cth_funcoff) {
261 dsp = (uint16_t *)(db_ctf.data + objtoff);
262
263 symp = db_ctf_idx2sym(&idx, STT_OBJECT);
264 if (symp == NULL)
265 break;
266 if (symp == st)
267 return db_ctf_type_by_index(*dsp);
268
269 objtoff += sizeof(*dsp);
270 }
271
272 return NULL;
273 }
274
275 const struct ctf_type *
276 db_ctf_type_by_name(const char *name, unsigned int kind)
277 {
278 struct ctf_header *cth;
279 const struct ctf_type *ctt;
280 const char *tname;
281 uint32_t off, toff;
282
283 if (!db_ctf.ctf_found)
284 return (NULL);
285
286 cth = db_ctf.cth;
287
288 for (off = cth->cth_typeoff; off < cth->cth_stroff; off += toff) {
289 ctt = (struct ctf_type *)(db_ctf.data + off);
290 toff = db_ctf_type_len(ctt);
291 if (toff == 0) {
292 db_printf("incorrect type at offset %u", off);
293 break;
294 }
295
296 if (CTF_INFO_KIND(ctt->ctt_info) != kind)
297 continue;
298
299 tname = db_ctf_off2name(ctt->ctt_name);
300 if (tname == NULL)
301 continue;
302
303 if (strcmp(name, tname) == 0)
304 return (ctt);
305 }
306
307 return (NULL);
308 }
309
310 /*
311 * Return the CTF type corresponding to a given index in the type section.
312 */
313 const struct ctf_type *
314 db_ctf_type_by_index(uint16_t index)
315 {
316 uint32_t offset = db_ctf.cth->cth_typeoff;
317 uint16_t idx = 1;
318
319 if (!db_ctf.ctf_found)
320 return NULL;
321
322 while (offset < db_ctf.cth->cth_stroff) {
323 const struct ctf_type *ctt;
324 uint32_t toff;
325
326 ctt = (struct ctf_type *)(db_ctf.data + offset);
327 if (idx == index)
328 return ctt;
329
330 toff = db_ctf_type_len(ctt);
331 if (toff == 0) {
332 db_printf("incorrect type at offset %u", offset);
333 break;
334 }
335 offset += toff;
336 idx++;
337 }
338
339 return NULL;
340 }
341
342 /*
343 * Pretty print `addr'.
344 */
345 void
346 db_ctf_pprint(const struct ctf_type *ctt, vaddr_t addr)
347 {
348 vaddr_t taddr = (vaddr_t)ctt;
349 const struct ctf_type *ref;
350 uint16_t kind;
351 uint32_t eob, toff;
352
353 kind = CTF_INFO_KIND(ctt->ctt_info);
354 if (ctt->ctt_size <= CTF_MAX_SIZE)
355 toff = sizeof(struct ctf_stype);
356 else
357 toff = sizeof(struct ctf_type);
358
359 switch (kind) {
360 case CTF_K_FLOAT:
361 case CTF_K_ENUM:
362 case CTF_K_ARRAY:
363 case CTF_K_FUNCTION:
364 db_printf("%lu", *((unsigned long *)addr));
365 break;
366 case CTF_K_INTEGER:
367 eob = db_get_value((taddr + toff), sizeof(eob), 0);
368 switch (CTF_INT_BITS(eob)) {
369 case 64:
370 db_printf("0x%llx", *((long long *)addr));
371 break;
372 default:
373 db_printf("0x%x", *((int *)addr));
374 break;
375 }
376 break;
377 case CTF_K_STRUCT:
378 case CTF_K_UNION:
379 db_ctf_pprint_struct(ctt, addr);
380 break;
381 case CTF_K_POINTER:
382 db_ctf_pprint_ptr(ctt, addr);
383 break;
384 case CTF_K_TYPEDEF:
385 case CTF_K_VOLATILE:
386 case CTF_K_CONST:
387 case CTF_K_RESTRICT:
388 ref = db_ctf_type_by_index(ctt->ctt_type);
389 db_ctf_pprint(ref, addr);
390 break;
391 case CTF_K_UNKNOWN:
392 case CTF_K_FORWARD:
393 default:
394 break;
395 }
396 }
397
398 void
399 db_ctf_pprint_struct(const struct ctf_type *ctt, vaddr_t addr)
400 {
401 const char *name, *p = (const char *)ctt;
402 const struct ctf_type *ref;
403 uint32_t toff;
404 uint64_t size;
405 uint16_t i, vlen;
406
407 vlen = CTF_INFO_VLEN(ctt->ctt_info);
408
409 if (ctt->ctt_size <= CTF_MAX_SIZE) {
410 size = ctt->ctt_size;
411 toff = sizeof(struct ctf_stype);
412 } else {
413 size = CTF_TYPE_LSIZE(ctt);
414 toff = sizeof(struct ctf_type);
415 }
416
417 db_printf("{");
418 if (size < CTF_LSTRUCT_THRESH) {
419
420 for (i = 0; i < vlen; i++) {
421 struct ctf_member *ctm;
422
423 ctm = (struct ctf_member *)(p + toff);
424 toff += sizeof(struct ctf_member);
425
426 name = db_ctf_off2name(ctm->ctm_name);
427 if (name != NULL)
428 db_printf("%s = ", name);
429 ref = db_ctf_type_by_index(ctm->ctm_type);
430 db_ctf_pprint(ref, addr + ctm->ctm_offset / 8);
431 if (i < vlen - 1)
432 db_printf(", ");
433 }
434 } else {
435 for (i = 0; i < vlen; i++) {
436 struct ctf_lmember *ctlm;
437
438 ctlm = (struct ctf_lmember *)(p + toff);
439 toff += sizeof(struct ctf_lmember);
440
441 name = db_ctf_off2name(ctlm->ctlm_name);
442 if (name != NULL)
443 db_printf("%s = ", name);
444 ref = db_ctf_type_by_index(ctlm->ctlm_type);
445 db_ctf_pprint(ref, addr +
446 CTF_LMEM_OFFSET(ctlm) / 8);
447 if (i < vlen - 1)
448 db_printf(", ");
449 }
450 }
451 db_printf("}");
452 }
453
454 void
455 db_ctf_pprint_ptr(const struct ctf_type *ctt, vaddr_t addr)
456 {
457 const char *name, *modif = "";
458 const struct ctf_type *ref;
459 uint16_t kind;
460 unsigned long ptr;
461
462 ref = db_ctf_type_by_index(ctt->ctt_type);
463 kind = CTF_INFO_KIND(ref->ctt_info);
464
465 switch (kind) {
466 case CTF_K_VOLATILE:
467 modif = "volatile ";
468 ref = db_ctf_type_by_index(ref->ctt_type);
469 break;
470 case CTF_K_CONST:
471 modif = "const ";
472 ref = db_ctf_type_by_index(ref->ctt_type);
473 break;
474 case CTF_K_STRUCT:
475 modif = "struct ";
476 break;
477 case CTF_K_UNION:
478 modif = "union ";
479 break;
480 default:
481 break;
482 }
483
484 name = db_ctf_off2name(ref->ctt_name);
485 if (name != NULL)
486 db_printf("(%s%s *)", modif, name);
487
488 ptr = (unsigned long)db_get_value(addr, sizeof(ptr), 0);
489
490 db_printf("0x%lx", ptr);
491 }
492
493 static const char *
494 db_ctf_off2name(uint32_t offset)
495 {
496 const char *name;
497
498 if (!db_ctf.ctf_found)
499 return NULL;
500
501 if (CTF_NAME_STID(offset) != CTF_STRTAB_0)
502 return "external";
503
504 if (CTF_NAME_OFFSET(offset) >= db_ctf.cth->cth_strlen)
505 return "exceeds strlab";
506
507 if (db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset) >= db_ctf.dlen)
508 return "invalid";
509
510 name = db_ctf.data + db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset);
511 if (*name == '\0')
512 return NULL;
513
514 return name;
515 }
516
517 static char *
518 db_ctf_decompress(const char *buf, size_t size, size_t len)
519 {
520 z_stream stream;
521 char *data;
522 int error;
523
524 data = malloc(len, M_TEMP, M_WAITOK|M_ZERO|M_CANFAIL);
525 if (data == NULL)
526 return NULL;
527
528 memset(&stream, 0, sizeof(stream));
529 stream.next_in = (void *)buf;
530 stream.avail_in = size;
531 stream.next_out = data;
532 stream.avail_out = len;
533
534 if ((error = inflateInit(&stream)) != Z_OK) {
535 db_printf("zlib inflateInit failed: %s", zError(error));
536 goto exit;
537 }
538
539 if ((error = inflate(&stream, Z_FINISH)) != Z_STREAM_END) {
540 db_printf("zlib inflate failed: %s", zError(error));
541 inflateEnd(&stream);
542 goto exit;
543 }
544
545 if ((error = inflateEnd(&stream)) != Z_OK) {
546 db_printf("zlib inflateEnd failed: %s", zError(error));
547 goto exit;
548 }
549
550 if (stream.total_out != len) {
551 db_printf("decompression failed: %lu != %zu",
552 stream.total_out, len);
553 goto exit;
554 }
555
556 return data;
557
558 exit:
559 free(data, M_DEVBUF, len);
560 return NULL;
561 }
562
563 /*
564 * pprint <symbol name>
565 */
566 void
567 db_ctf_pprint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
568 {
569 Elf_Sym *st;
570 const struct ctf_type *ctt;
571 int t;
572
573 if (!db_ctf.ctf_found) {
574 db_printf("No CTF data found\n");
575 db_flush_lex();
576 return;
577 }
578
579 /*
580 * Read the struct name from the debugger input.
581 */
582 t = db_read_token();
583 if (t != tIDENT) {
584 db_printf("Bad symbol name\n");
585 db_flush_lex();
586 return;
587 }
588
589 if ((st = db_symbol_by_name(db_tok_string, &addr)) == NULL) {
590 db_printf("Symbol not found %s\n", db_tok_string);
591 db_flush_lex();
592 return;
593 }
594
595 if ((ctt = db_ctf_type_by_symbol(st)) == NULL) {
596 modif[0] = '\0';
597 db_print_cmd(addr, 0, 0, modif);
598 db_flush_lex();
599 return;
600 }
601
602 db_printf("%s:\t", db_tok_string);
603 db_ctf_pprint(ctt, addr);
604 db_printf("\n");
605 }
606
607 /*
608 * show struct <struct name> [addr]: displays the data starting at addr
609 * (`dot' if unspecified) as a struct of the given type.
610 */
611 void
612 db_ctf_show_struct(db_expr_t addr, int have_addr, db_expr_t count,
613 char *modifiers)
614 {
615 const struct ctf_type *ctt;
616 const char *name;
617 uint64_t sz;
618 int t;
619
620 /*
621 * Read the struct name from the debugger input.
622 */
623 t = db_read_token();
624 if (t != tIDENT) {
625 db_printf("Bad struct name\n");
626 db_flush_lex();
627 return;
628 }
629 name = db_tok_string;
630
631 ctt = db_ctf_type_by_name(name, CTF_K_STRUCT);
632 if (ctt == NULL) {
633 db_printf("unknown struct %s\n", name);
634 db_flush_lex();
635 return;
636 }
637
638 /*
639 * Read the address, if any, from the debugger input.
640 * In that case, update `dot' value.
641 */
642 if (db_expression(&addr)) {
643 db_dot = (vaddr_t)addr;
644 db_last_addr = db_dot;
645 } else
646 addr = (db_expr_t)db_dot;
647
648 db_skip_to_eol();
649
650 /*
651 * Display the structure contents.
652 */
653 sz = (ctt->ctt_size <= CTF_MAX_SIZE) ?
654 ctt->ctt_size : CTF_TYPE_LSIZE(ctt);
655 db_printf("struct %s at %p (%llu bytes) ", name, (void *)addr, sz);
656 db_ctf_pprint_struct(ctt, addr);
657 }
Cache object: 5d7beedc4fa0d47f719de0d9bb7814a9
|