1 /* $OpenBSD: db_ctf.c,v 1.30 2020/10/15 03:14:00 deraadt 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, off_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 = db_ctf.cth->cth_objtoff; 252 uint16_t *dsp; 253 size_t idx = 0; 254 255 if (!db_ctf.ctf_found || st == NULL) 256 return NULL; 257 258 while (objtoff < db_ctf.cth->cth_funcoff) { 259 dsp = (uint16_t *)(db_ctf.data + objtoff); 260 261 symp = db_ctf_idx2sym(&idx, STT_OBJECT); 262 if (symp == NULL) 263 break; 264 if (symp == st) 265 return db_ctf_type_by_index(*dsp); 266 267 objtoff += sizeof(*dsp); 268 } 269 270 return NULL; 271 } 272 273 const struct ctf_type * 274 db_ctf_type_by_name(const char *name, unsigned int kind) 275 { 276 struct ctf_header *cth; 277 const struct ctf_type *ctt; 278 const char *tname; 279 uint32_t off, toff; 280 281 if (!db_ctf.ctf_found) 282 return (NULL); 283 284 cth = db_ctf.cth; 285 286 for (off = cth->cth_typeoff; off < cth->cth_stroff; off += toff) { 287 ctt = (struct ctf_type *)(db_ctf.data + off); 288 toff = db_ctf_type_len(ctt); 289 if (toff == 0) { 290 db_printf("incorrect type at offset %u", off); 291 break; 292 } 293 294 if (CTF_INFO_KIND(ctt->ctt_info) != kind) 295 continue; 296 297 tname = db_ctf_off2name(ctt->ctt_name); 298 if (tname == NULL) 299 continue; 300 301 if (strcmp(name, tname) == 0) 302 return (ctt); 303 } 304 305 return (NULL); 306 } 307 308 /* 309 * Return the CTF type corresponding to a given index in the type section. 310 */ 311 const struct ctf_type * 312 db_ctf_type_by_index(uint16_t index) 313 { 314 uint32_t offset = db_ctf.cth->cth_typeoff; 315 uint16_t idx = 1; 316 317 if (!db_ctf.ctf_found) 318 return NULL; 319 320 while (offset < db_ctf.cth->cth_stroff) { 321 const struct ctf_type *ctt; 322 uint32_t toff; 323 324 ctt = (struct ctf_type *)(db_ctf.data + offset); 325 if (idx == index) 326 return ctt; 327 328 toff = db_ctf_type_len(ctt); 329 if (toff == 0) { 330 db_printf("incorrect type at offset %u", offset); 331 break; 332 } 333 offset += toff; 334 idx++; 335 } 336 337 return NULL; 338 } 339 340 /* 341 * Pretty print `addr'. 342 */ 343 void 344 db_ctf_pprint(const struct ctf_type *ctt, vaddr_t addr) 345 { 346 vaddr_t taddr = (vaddr_t)ctt; 347 const struct ctf_type *ref; 348 uint16_t kind; 349 uint32_t eob, toff; 350 351 kind = CTF_INFO_KIND(ctt->ctt_info); 352 if (ctt->ctt_size <= CTF_MAX_SIZE) 353 toff = sizeof(struct ctf_stype); 354 else 355 toff = sizeof(struct ctf_type); 356 357 switch (kind) { 358 case CTF_K_FLOAT: 359 case CTF_K_ENUM: 360 case CTF_K_ARRAY: 361 case CTF_K_FUNCTION: 362 db_printf("%lu", *((unsigned long *)addr)); 363 break; 364 case CTF_K_INTEGER: 365 eob = db_get_value((taddr + toff), sizeof(eob), 0); 366 switch (CTF_INT_BITS(eob)) { 367 case 64: 368 db_printf("0x%llx", *((long long *)addr)); 369 break; 370 default: 371 db_printf("0x%x", *((int *)addr)); 372 break; 373 } 374 break; 375 case CTF_K_STRUCT: 376 case CTF_K_UNION: 377 db_ctf_pprint_struct(ctt, addr); 378 break; 379 case CTF_K_POINTER: 380 db_ctf_pprint_ptr(ctt, addr); 381 break; 382 case CTF_K_TYPEDEF: 383 case CTF_K_VOLATILE: 384 case CTF_K_CONST: 385 case CTF_K_RESTRICT: 386 ref = db_ctf_type_by_index(ctt->ctt_type); 387 db_ctf_pprint(ref, addr); 388 break; 389 case CTF_K_UNKNOWN: 390 case CTF_K_FORWARD: 391 default: 392 break; 393 } 394 } 395 396 void 397 db_ctf_pprint_struct(const struct ctf_type *ctt, vaddr_t addr) 398 { 399 const char *name, *p = (const char *)ctt; 400 const struct ctf_type *ref; 401 uint32_t toff; 402 uint64_t size; 403 uint16_t i, vlen; 404 405 vlen = CTF_INFO_VLEN(ctt->ctt_info); 406 407 if (ctt->ctt_size <= CTF_MAX_SIZE) { 408 size = ctt->ctt_size; 409 toff = sizeof(struct ctf_stype); 410 } else { 411 size = CTF_TYPE_LSIZE(ctt); 412 toff = sizeof(struct ctf_type); 413 } 414 415 db_printf("{"); 416 if (size < CTF_LSTRUCT_THRESH) { 417 418 for (i = 0; i < vlen; i++) { 419 struct ctf_member *ctm; 420 421 ctm = (struct ctf_member *)(p + toff); 422 toff += sizeof(struct ctf_member); 423 424 name = db_ctf_off2name(ctm->ctm_name); 425 if (name != NULL) 426 db_printf("%s = ", name); 427 ref = db_ctf_type_by_index(ctm->ctm_type); 428 db_ctf_pprint(ref, addr + ctm->ctm_offset / 8); 429 if (i < vlen - 1) 430 db_printf(", "); 431 } 432 } else { 433 for (i = 0; i < vlen; i++) { 434 struct ctf_lmember *ctlm; 435 436 ctlm = (struct ctf_lmember *)(p + toff); 437 toff += sizeof(struct ctf_lmember); 438 439 name = db_ctf_off2name(ctlm->ctlm_name); 440 if (name != NULL) 441 db_printf("%s = ", name); 442 ref = db_ctf_type_by_index(ctlm->ctlm_type); 443 db_ctf_pprint(ref, addr + 444 CTF_LMEM_OFFSET(ctlm) / 8); 445 if (i < vlen - 1) 446 db_printf(", "); 447 } 448 } 449 db_printf("}"); 450 } 451 452 void 453 db_ctf_pprint_ptr(const struct ctf_type *ctt, vaddr_t addr) 454 { 455 const char *name, *modif = ""; 456 const struct ctf_type *ref; 457 uint16_t kind; 458 unsigned long ptr; 459 460 ref = db_ctf_type_by_index(ctt->ctt_type); 461 kind = CTF_INFO_KIND(ref->ctt_info); 462 463 switch (kind) { 464 case CTF_K_VOLATILE: 465 modif = "volatile "; 466 ref = db_ctf_type_by_index(ref->ctt_type); 467 break; 468 case CTF_K_CONST: 469 modif = "const "; 470 ref = db_ctf_type_by_index(ref->ctt_type); 471 break; 472 case CTF_K_STRUCT: 473 modif = "struct "; 474 break; 475 case CTF_K_UNION: 476 modif = "union "; 477 break; 478 default: 479 break; 480 } 481 482 name = db_ctf_off2name(ref->ctt_name); 483 if (name != NULL) 484 db_printf("(%s%s *)", modif, name); 485 486 ptr = (unsigned long)db_get_value(addr, sizeof(ptr), 0); 487 488 db_printf("0x%lx", ptr); 489 } 490 491 static const char * 492 db_ctf_off2name(uint32_t offset) 493 { 494 const char *name; 495 496 if (CTF_NAME_STID(offset) != CTF_STRTAB_0) 497 return "external"; 498 499 if (CTF_NAME_OFFSET(offset) >= db_ctf.cth->cth_strlen) 500 return "exceeds strlab"; 501 502 if (db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset) >= db_ctf.dlen) 503 return "invalid"; 504 505 name = db_ctf.data + db_ctf.cth->cth_stroff + CTF_NAME_OFFSET(offset); 506 if (*name == '\0') 507 return NULL; 508 509 return name; 510 } 511 512 static char * 513 db_ctf_decompress(const char *buf, size_t size, off_t len) 514 { 515 z_stream stream; 516 char *data; 517 int error; 518 519 data = malloc(len, M_TEMP, M_WAITOK|M_ZERO|M_CANFAIL); 520 if (data == NULL) 521 return NULL; 522 523 memset(&stream, 0, sizeof(stream)); 524 stream.next_in = (void *)buf; 525 stream.avail_in = size; 526 stream.next_out = data; 527 stream.avail_out = len; 528 529 if ((error = inflateInit(&stream)) != Z_OK) { 530 db_printf("zlib inflateInit failed: %s", zError(error)); 531 goto exit; 532 } 533 534 if ((error = inflate(&stream, Z_FINISH)) != Z_STREAM_END) { 535 db_printf("zlib inflate failed: %s", zError(error)); 536 inflateEnd(&stream); 537 goto exit; 538 } 539 540 if ((error = inflateEnd(&stream)) != Z_OK) { 541 db_printf("zlib inflateEnd failed: %s", zError(error)); 542 goto exit; 543 } 544 545 if (stream.total_out != len) { 546 db_printf("decompression failed: %llu != %llu", 547 stream.total_out, len); 548 goto exit; 549 } 550 551 return data; 552 553 exit: 554 free(data, M_DEVBUF, len); 555 return NULL; 556 } 557 558 /* 559 * pprint <symbol name> 560 */ 561 void 562 db_ctf_pprint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) 563 { 564 Elf_Sym *st; 565 const struct ctf_type *ctt; 566 int t; 567 568 if (!db_ctf.ctf_found) { 569 db_printf("No CTF data found\n"); 570 db_flush_lex(); 571 return; 572 } 573 574 /* 575 * Read the struct name from the debugger input. 576 */ 577 t = db_read_token(); 578 if (t != tIDENT) { 579 db_printf("Bad symbol name\n"); 580 db_flush_lex(); 581 return; 582 } 583 584 if ((st = db_symbol_by_name(db_tok_string, &addr)) == NULL) { 585 db_printf("Symbol not found %s\n", db_tok_string); 586 db_flush_lex(); 587 return; 588 } 589 590 if ((ctt = db_ctf_type_by_symbol(st)) == NULL) { 591 modif[0] = '\0'; 592 db_print_cmd(addr, 0, 0, modif); 593 db_flush_lex(); 594 return; 595 } 596 597 db_printf("%s:\t", db_tok_string); 598 db_ctf_pprint(ctt, addr); 599 db_printf("\n"); 600 } 601 602 /* 603 * show struct <struct name> [addr]: displays the data starting at addr 604 * (`dot' if unspecified) as a struct of the given type. 605 */ 606 void 607 db_ctf_show_struct(db_expr_t addr, int have_addr, db_expr_t count, 608 char *modifiers) 609 { 610 const struct ctf_type *ctt; 611 const char *name; 612 uint64_t sz; 613 int t; 614 615 /* 616 * Read the struct name from the debugger input. 617 */ 618 t = db_read_token(); 619 if (t != tIDENT) { 620 db_printf("Bad struct name\n"); 621 db_flush_lex(); 622 return; 623 } 624 name = db_tok_string; 625 626 ctt = db_ctf_type_by_name(name, CTF_K_STRUCT); 627 if (ctt == NULL) { 628 db_printf("unknown struct %s\n", name); 629 db_flush_lex(); 630 return; 631 } 632 633 /* 634 * Read the address, if any, from the debugger input. 635 * In that case, update `dot' value. 636 */ 637 if (db_expression(&addr)) { 638 db_dot = (vaddr_t)addr; 639 db_last_addr = db_dot; 640 } else 641 addr = (db_expr_t)db_dot; 642 643 db_skip_to_eol(); 644 645 /* 646 * Display the structure contents. 647 */ 648 sz = (ctt->ctt_size <= CTF_MAX_SIZE) ? 649 ctt->ctt_size : CTF_TYPE_LSIZE(ctt); 650 db_printf("struct %s at %p (%llu bytes) ", name, (void *)addr, sz); 651 db_ctf_pprint_struct(ctt, addr); 652 } 653