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