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 } 658