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