1 /* $OpenBSD: parse.c,v 1.7 2017/09/24 09:14:25 jsg 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 /* 21 * DWARF to IT (internal type) representation parser. 22 */ 23 24 #include <sys/param.h> /* nitems() */ 25 #include <sys/queue.h> 26 #include <sys/tree.h> 27 #include <sys/ctf.h> 28 29 #include <assert.h> 30 #include <limits.h> 31 #include <err.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 #include "itype.h" 36 #include "xmalloc.h" 37 #include "dwarf.h" 38 #include "dw.h" 39 #include "pool.h" 40 41 #ifdef DEBUG 42 #include <stdio.h> 43 #endif 44 45 #ifndef NOPOOL 46 struct pool it_pool, im_pool, ir_pool; 47 #endif /* NOPOOL */ 48 49 #define DPRINTF(x...) do { /*printf(x)*/ } while (0) 50 51 #define VOID_OFFSET 1 /* Fake offset for generating "void" type. */ 52 53 /* 54 * Tree used to resolve per-CU types based on their offset in 55 * the abbrev section. 56 */ 57 RB_HEAD(ioff_tree, itype); 58 59 /* 60 * Per-type trees used to merge exsiting types with the ones of 61 * a newly parsed CU. 62 */ 63 RB_HEAD(itype_tree, itype) itypet[CTF_K_MAX]; 64 65 /* 66 * Tree of symbols used to build a list matching the order of 67 * the ELF symbol table. 68 */ 69 struct isymb_tree isymbt; 70 71 struct itype *void_it; 72 uint16_t tidx, fidx, oidx; /* type, func & object IDs */ 73 uint16_t long_tidx; /* index of "long", for array */ 74 75 76 void cu_stat(void); 77 void cu_parse(struct dwcu *, struct itype_queue *, 78 struct ioff_tree *); 79 void cu_resolve(struct dwcu *, struct itype_queue *, 80 struct ioff_tree *); 81 void cu_reference(struct dwcu *, struct itype_queue *); 82 void cu_merge(struct dwcu *, struct itype_queue *); 83 84 struct itype *parse_base(struct dwdie *, size_t); 85 struct itype *parse_refers(struct dwdie *, size_t, int); 86 struct itype *parse_array(struct dwdie *, size_t); 87 struct itype *parse_enum(struct dwdie *, size_t); 88 struct itype *parse_struct(struct dwdie *, size_t, int, size_t); 89 struct itype *parse_function(struct dwdie *, size_t); 90 struct itype *parse_funcptr(struct dwdie *, size_t); 91 struct itype *parse_variable(struct dwdie *, size_t); 92 93 void subparse_subrange(struct dwdie *, size_t, struct itype *); 94 void subparse_enumerator(struct dwdie *, size_t, struct itype *); 95 void subparse_member(struct dwdie *, size_t, struct itype *, size_t); 96 void subparse_arguments(struct dwdie *, size_t, struct itype *); 97 98 size_t dav2val(struct dwaval *, size_t); 99 const char *dav2str(struct dwaval *); 100 const char *enc2name(unsigned short); 101 102 struct itype *it_new(uint64_t, size_t, const char *, uint32_t, uint16_t, 103 uint64_t, uint16_t, unsigned int); 104 void it_reference(struct itype *); 105 void it_free(struct itype *); 106 int it_cmp(struct itype *, struct itype *); 107 int it_name_cmp(struct itype *, struct itype *); 108 int it_off_cmp(struct itype *, struct itype *); 109 void ir_add(struct itype *, struct itype *); 110 void ir_purge(struct itype *); 111 struct imember *im_new(const char *, size_t, size_t); 112 113 RB_GENERATE(itype_tree, itype, it_node, it_cmp); 114 RB_GENERATE(isymb_tree, itype, it_node, it_name_cmp); 115 RB_GENERATE(ioff_tree, itype, it_node, it_off_cmp); 116 117 /* 118 * Construct a list of internal type and functions based on DWARF 119 * INFO and ABBREV sections. 120 * 121 * Multiple CUs are supported. 122 */ 123 void 124 dwarf_parse(const char *infobuf, size_t infolen, const char *abbuf, 125 size_t ablen) 126 { 127 struct dwbuf info = { .buf = infobuf, .len = infolen }; 128 struct dwbuf abbrev = { .buf = abbuf, .len = ablen }; 129 struct dwcu *dcu = NULL; 130 struct ioff_tree cu_iofft; 131 struct itype_queue cu_itypeq; 132 struct itype *it; 133 int i; 134 135 for (i = 0; i < CTF_K_MAX; i++) 136 RB_INIT(&itypet[i]); 137 RB_INIT(&isymbt); 138 139 void_it = it_new(++tidx, VOID_OFFSET, "void", 0, 140 CTF_INT_SIGNED, 0, CTF_K_INTEGER, 0); 141 TAILQ_INSERT_TAIL(&itypeq, void_it, it_next); 142 143 while (dw_cu_parse(&info, &abbrev, infolen, &dcu) == 0) { 144 TAILQ_INIT(&cu_itypeq); 145 RB_INIT(&cu_iofft); 146 147 /* Parse this CU */ 148 cu_parse(dcu, &cu_itypeq, &cu_iofft); 149 150 /* Resolve its types. */ 151 cu_resolve(dcu, &cu_itypeq, &cu_iofft); 152 assert(RB_EMPTY(&cu_iofft)); 153 154 /* Mark used type as such. */ 155 cu_reference(dcu, &cu_itypeq); 156 157 #ifdef DEBUG 158 /* Dump statistics for current CU. */ 159 cu_stat(); 160 #endif 161 162 /* Merge them with the common type list. */ 163 cu_merge(dcu, &cu_itypeq); 164 165 dw_dcu_free(dcu); 166 } 167 168 /* We force array's index type to be 'long', for that we need its ID. */ 169 RB_FOREACH(it, itype_tree, &itypet[CTF_K_INTEGER]) { 170 if (it_name(it) == NULL || it->it_size != (8 * sizeof(long))) 171 continue; 172 173 if (strcmp(it_name(it), "unsigned") == 0) { 174 long_tidx = it->it_idx; 175 break; 176 } 177 } 178 } 179 180 struct itype * 181 it_new(uint64_t index, size_t off, const char *name, uint32_t size, 182 uint16_t enc, uint64_t ref, uint16_t type, unsigned int flags) 183 { 184 struct itype *it; 185 #ifndef NOPOOL 186 static int it_pool_inited = 0; 187 188 if (!it_pool_inited) { 189 pool_init(&it_pool, "it", 512, sizeof(struct itype)); 190 pool_init(&im_pool, "im", 1024, sizeof(struct imember)); 191 pool_init(&ir_pool, "ir", 1024, sizeof(struct itref)); 192 it_pool_inited = 1; 193 } 194 #endif 195 196 assert((name != NULL) || !(flags & (ITF_FUNC|ITF_OBJ))); 197 198 it = pmalloc(&it_pool, sizeof(*it)); 199 SIMPLEQ_INIT(&it->it_refs); 200 TAILQ_INIT(&it->it_members); 201 it->it_off = off; 202 it->it_ref = ref; 203 it->it_refp = NULL; 204 it->it_size = size; 205 it->it_nelems = 0; 206 it->it_enc = enc; 207 it->it_idx = index; 208 it->it_type = type; 209 it->it_flags = flags; 210 211 if (name == NULL) { 212 it->it_flags |= ITF_ANON; 213 } else { 214 size_t n; 215 216 if ((n = strlcpy(it->it_name, name, ITNAME_MAX)) > ITNAME_MAX) 217 warnx("name %s too long %zd > %d", name, n, ITNAME_MAX); 218 } 219 220 return it; 221 } 222 223 struct itype * 224 it_dup(struct itype *it) 225 { 226 struct imember *copim, *im; 227 struct itype *copit; 228 229 copit = it_new(it->it_idx, it->it_off, it_name(it), it->it_size, 230 it->it_enc, it->it_ref, it->it_type, it->it_flags); 231 232 copit->it_refp = it->it_refp; 233 copit->it_nelems = it->it_nelems; 234 235 TAILQ_FOREACH(im, &it->it_members, im_next) { 236 copim = im_new(im_name(im), im->im_ref, im->im_off); 237 copim->im_refp = im->im_refp; 238 TAILQ_INSERT_TAIL(&copit->it_members, copim, im_next); 239 } 240 241 return copit; 242 } 243 244 const char * 245 it_name(struct itype *it) 246 { 247 if (!(it->it_flags & ITF_ANON)) 248 return it->it_name; 249 250 return NULL; 251 } 252 253 void 254 it_reference(struct itype *it) 255 { 256 struct imember *im; 257 258 if (it == NULL || it->it_flags & ITF_USED) 259 return; 260 261 it->it_flags |= ITF_USED; 262 263 it_reference(it->it_refp); 264 TAILQ_FOREACH(im, &it->it_members, im_next) 265 it_reference(im->im_refp); 266 } 267 268 void 269 it_free(struct itype *it) 270 { 271 struct imember *im; 272 273 if (it == NULL) 274 return; 275 276 while ((im = TAILQ_FIRST(&it->it_members)) != NULL) { 277 TAILQ_REMOVE(&it->it_members, im, im_next); 278 pfree(&im_pool, im); 279 } 280 281 ir_purge(it); 282 pfree(&it_pool, it); 283 } 284 285 /* 286 * Return 0 if ``a'' matches ``b''. 287 */ 288 int 289 it_cmp(struct itype *a, struct itype *b) 290 { 291 int diff; 292 293 if ((diff = (a->it_type - b->it_type)) != 0) 294 return diff; 295 296 if ((diff = (a->it_size - b->it_size)) != 0) 297 return diff; 298 299 if ((diff = (a->it_nelems - b->it_nelems)) != 0) 300 return diff; 301 302 /* Match by name */ 303 if (!(a->it_flags & ITF_ANON) && !(b->it_flags & ITF_ANON)) 304 return strcmp(it_name(a), it_name(b)); 305 306 /* Only one of them is anonym */ 307 if ((a->it_flags & ITF_ANON) != (b->it_flags & ITF_ANON)) 308 return (a->it_flags & ITF_ANON) ? -1 : 1; 309 310 /* Match by reference */ 311 if ((a->it_refp != NULL) && (b->it_refp != NULL)) 312 return it_cmp(a->it_refp, b->it_refp); 313 314 return 1; 315 } 316 317 int 318 it_name_cmp(struct itype *a, struct itype *b) 319 { 320 int diff; 321 322 if ((diff = strcmp(it_name(a), it_name(b))) != 0) 323 return diff; 324 325 return ((a->it_flags|ITF_MASK) - (b->it_flags|ITF_MASK)); 326 } 327 328 int 329 it_off_cmp(struct itype *a, struct itype *b) 330 { 331 return a->it_off - b->it_off; 332 } 333 334 void 335 ir_add(struct itype *it, struct itype *tmp) 336 { 337 struct itref *ir; 338 339 SIMPLEQ_FOREACH(ir, &tmp->it_refs, ir_next) { 340 if (ir->ir_itp == it) 341 return; 342 } 343 344 ir = pmalloc(&ir_pool, sizeof(*ir)); 345 ir->ir_itp = it; 346 SIMPLEQ_INSERT_TAIL(&tmp->it_refs, ir, ir_next); 347 } 348 349 void 350 ir_purge(struct itype *it) 351 { 352 struct itref *ir; 353 354 while ((ir = SIMPLEQ_FIRST(&it->it_refs)) != NULL) { 355 SIMPLEQ_REMOVE_HEAD(&it->it_refs, ir_next); 356 pfree(&ir_pool, ir); 357 } 358 } 359 360 struct imember * 361 im_new(const char *name, size_t ref, size_t off) 362 { 363 struct imember *im; 364 365 im = pmalloc(&im_pool, sizeof(*im)); 366 im->im_ref = ref; 367 im->im_off = off; 368 im->im_refp = NULL; 369 if (name == NULL) { 370 im->im_flags = IMF_ANON; 371 } else { 372 size_t n; 373 374 n = strlcpy(im->im_name, name, ITNAME_MAX); 375 if (n > ITNAME_MAX) 376 warnx("name %s too long %zd > %d", name, n, 377 ITNAME_MAX); 378 im->im_flags = 0; 379 } 380 381 return im; 382 } 383 384 const char * 385 im_name(struct imember *im) 386 { 387 if (!(im->im_flags & IMF_ANON)) 388 return im->im_name; 389 390 return NULL; 391 } 392 393 void 394 cu_stat(void) 395 { 396 #ifndef NOPOOL 397 pool_dump(); 398 #endif 399 } 400 /* 401 * Worst case it's a O(n*n) resolution lookup, with ``n'' being the number 402 * of elements in ``cutq''. 403 */ 404 void 405 cu_resolve(struct dwcu *dcu, struct itype_queue *cutq, struct ioff_tree *cuot) 406 { 407 struct itype *it, *ref, tmp; 408 struct imember *im; 409 unsigned int toresolve; 410 size_t off = dcu->dcu_offset; 411 412 TAILQ_FOREACH(it, cutq, it_next) { 413 if (!(it->it_flags & (ITF_UNRES|ITF_UNRES_MEMB))) 414 continue; 415 416 if (it->it_flags & ITF_UNRES) { 417 tmp.it_off = it->it_ref + off; 418 ref = RB_FIND(ioff_tree, cuot, &tmp); 419 if (ref != NULL) { 420 it->it_refp = ref; 421 ir_add(it, ref); 422 it->it_flags &= ~ITF_UNRES; 423 } 424 } 425 426 /* All members need to be resolved. */ 427 toresolve = it->it_nelems; 428 if ((it->it_flags & ITF_UNRES_MEMB) && toresolve > 0) { 429 TAILQ_FOREACH(im, &it->it_members, im_next) { 430 tmp.it_off = im->im_ref + off; 431 ref = RB_FIND(ioff_tree, cuot, &tmp); 432 if (ref != NULL) { 433 im->im_refp = ref; 434 ir_add(it, ref); 435 toresolve--; 436 } 437 } 438 if (toresolve == 0) 439 it->it_flags &= ~ITF_UNRES_MEMB; 440 } 441 #if defined(DEBUG) 442 if (it->it_flags & (ITF_UNRES|ITF_UNRES_MEMB)) { 443 printf("0x%zx: %s type=%d unresolved 0x%llx", 444 it->it_off, it_name(it), it->it_type, it->it_ref); 445 if (toresolve) 446 printf(": %d members", toresolve); 447 TAILQ_FOREACH(im, &it->it_members, im_next) { 448 if (im->im_refp != NULL) 449 continue; 450 printf("\n%zu: %s", im->im_ref, im_name(im)); 451 } 452 printf("\n"); 453 } 454 #endif /* defined(DEBUG) */ 455 } 456 457 RB_FOREACH_SAFE(it, ioff_tree, cuot, ref) 458 RB_REMOVE(ioff_tree, cuot, it); 459 } 460 461 void 462 cu_reference(struct dwcu *dcu, struct itype_queue *cutq) 463 { 464 struct itype *it; 465 466 TAILQ_FOREACH(it, cutq, it_next) { 467 if (it->it_flags & (ITF_OBJ|ITF_FUNC)) 468 it_reference(it); 469 } 470 } 471 472 /* 473 * Merge type representation from a CU with already known types. 474 */ 475 void 476 cu_merge(struct dwcu *dcu, struct itype_queue *cutq) 477 { 478 struct itype *it, *nit, *prev, *first; 479 int diff; 480 481 /* First ``it'' that needs a duplicate check. */ 482 first = TAILQ_FIRST(cutq); 483 if (first == NULL) 484 return; 485 486 TAILQ_CONCAT(&itypeq, cutq, it_next); 487 488 /* 489 * First pass: merge types 490 */ 491 for (it = first; it != NULL; it = nit) { 492 nit = TAILQ_NEXT(it, it_next); 493 494 /* Move functions & variable to their own list. */ 495 if (it->it_flags & (ITF_FUNC|ITF_OBJ)) { 496 /* 497 * FIXME: allow static variables with the same name 498 * to be of different type. 499 */ 500 if (RB_FIND(isymb_tree, &isymbt, it) == NULL) 501 RB_INSERT(isymb_tree, &isymbt, it); 502 continue; 503 } 504 505 /* Look if we already have this type. */ 506 if (it->it_flags & ITF_USED) 507 prev = RB_FIND(itype_tree, &itypet[it->it_type], it); 508 else 509 prev = NULL; 510 511 if (prev != NULL) { 512 struct itype *old = it; 513 struct itref *ir; 514 struct imember *im; 515 516 /* Substitute references */ 517 while ((ir = SIMPLEQ_FIRST(&old->it_refs)) != NULL) { 518 it = ir->ir_itp; 519 520 SIMPLEQ_REMOVE_HEAD(&old->it_refs, ir_next); 521 pfree(&ir_pool, ir); 522 523 if (it->it_refp == old) 524 it->it_refp = prev; 525 526 TAILQ_FOREACH(im, &it->it_members, im_next) { 527 if (im->im_refp == old) 528 im->im_refp = prev; 529 } 530 } 531 532 old->it_flags &= ~ITF_USED; 533 } else if (it->it_flags & ITF_USED) { 534 RB_INSERT(itype_tree, &itypet[it->it_type], it); 535 } 536 } 537 538 /* 539 * Second pass: update indexes 540 */ 541 diff = 0; 542 for (it = first; it != NULL; it = nit) { 543 nit = TAILQ_NEXT(it, it_next); 544 545 if (it->it_flags & (ITF_FUNC|ITF_OBJ)) 546 continue; 547 548 /* Adjust indexes */ 549 if (it->it_flags & ITF_USED) { 550 it->it_idx -= diff; 551 continue; 552 } 553 554 /* Remove unused */ 555 TAILQ_REMOVE(&itypeq, it, it_next); 556 it_free(it); 557 diff++; 558 } 559 560 /* Update global index to match removed entries. */ 561 it = TAILQ_LAST(&itypeq, itype_queue); 562 while (it->it_flags & (ITF_FUNC|ITF_OBJ)) 563 it = TAILQ_PREV(it, itype_queue, it_next); 564 565 tidx = it->it_idx; 566 } 567 568 /* 569 * Parse a CU. 570 */ 571 void 572 cu_parse(struct dwcu *dcu, struct itype_queue *cutq, struct ioff_tree *cuot) 573 { 574 struct itype *it = NULL; 575 struct dwdie *die; 576 size_t psz = dcu->dcu_psize; 577 size_t off = dcu->dcu_offset; 578 579 assert(RB_EMPTY(cuot)); 580 581 SIMPLEQ_FOREACH(die, &dcu->dcu_dies, die_next) { 582 uint64_t tag = die->die_dab->dab_tag; 583 584 switch (tag) { 585 case DW_TAG_array_type: 586 it = parse_array(die, dcu->dcu_psize); 587 break; 588 case DW_TAG_enumeration_type: 589 it = parse_enum(die, dcu->dcu_psize); 590 break; 591 case DW_TAG_pointer_type: 592 it = parse_refers(die, psz, CTF_K_POINTER); 593 break; 594 case DW_TAG_structure_type: 595 it = parse_struct(die, psz, CTF_K_STRUCT, off); 596 if (it == NULL) 597 continue; 598 break; 599 case DW_TAG_typedef: 600 it = parse_refers(die, psz, CTF_K_TYPEDEF); 601 break; 602 case DW_TAG_union_type: 603 it = parse_struct(die, psz, CTF_K_UNION, off); 604 if (it == NULL) 605 continue; 606 break; 607 case DW_TAG_base_type: 608 it = parse_base(die, psz); 609 if (it == NULL) 610 continue; 611 break; 612 case DW_TAG_const_type: 613 it = parse_refers(die, psz, CTF_K_CONST); 614 break; 615 case DW_TAG_volatile_type: 616 it = parse_refers(die, psz, CTF_K_VOLATILE); 617 break; 618 case DW_TAG_restrict_type: 619 it = parse_refers(die, psz, CTF_K_RESTRICT); 620 break; 621 case DW_TAG_subprogram: 622 it = parse_function(die, psz); 623 if (it == NULL) 624 continue; 625 break; 626 case DW_TAG_subroutine_type: 627 it = parse_funcptr(die, psz); 628 break; 629 /* 630 * Children are assumed to be right after their parent in 631 * the list. The parent parsing function takes care of 632 * parsing them. 633 */ 634 case DW_TAG_member: 635 assert(it->it_type == CTF_K_STRUCT || 636 it->it_type == CTF_K_UNION || 637 it->it_type == CTF_K_ENUM); 638 continue; 639 case DW_TAG_subrange_type: 640 assert(it->it_type == CTF_K_ARRAY); 641 continue; 642 case DW_TAG_formal_parameter: 643 /* 644 * If we skipped the second inline definition, 645 * skip its arguments. 646 */ 647 if (it == NULL) 648 continue; 649 650 /* See comment in subparse_arguments(). */ 651 if (it->it_type == CTF_K_STRUCT || 652 it->it_type == CTF_K_UNION || 653 it->it_type == CTF_K_ENUM || 654 it->it_type == CTF_K_TYPEDEF) 655 continue; 656 657 if (it->it_flags & ITF_OBJ) 658 continue; 659 660 assert(it->it_type == CTF_K_FUNCTION); 661 continue; 662 case DW_TAG_variable: 663 it = parse_variable(die, psz); 664 /* Unnamed variables are discarded. */ 665 if (it == NULL) 666 continue; 667 break; 668 #if 1 669 case DW_TAG_lexical_block: 670 case DW_TAG_inlined_subroutine: 671 continue; 672 #endif 673 case DW_TAG_compile_unit: 674 default: 675 DPRINTF("%s\n", dw_tag2name(tag)); 676 continue; 677 } 678 679 TAILQ_INSERT_TAIL(cutq, it, it_next); 680 RB_INSERT(ioff_tree, cuot, it); 681 } 682 } 683 684 struct itype * 685 parse_base(struct dwdie *die, size_t psz) 686 { 687 struct itype *it; 688 struct dwaval *dav; 689 uint16_t encoding, enc = 0, bits = 0; 690 int type; 691 692 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 693 switch (dav->dav_dat->dat_attr) { 694 case DW_AT_encoding: 695 enc = dav2val(dav, psz); 696 break; 697 case DW_AT_byte_size: 698 bits = 8 * dav2val(dav, psz); 699 break; 700 default: 701 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 702 break; 703 } 704 } 705 706 switch (enc) { 707 case DW_ATE_unsigned: 708 case DW_ATE_address: 709 encoding = 0; 710 type = CTF_K_INTEGER; 711 break; 712 case DW_ATE_unsigned_char: 713 encoding = CTF_INT_CHAR; 714 type = CTF_K_INTEGER; 715 break; 716 case DW_ATE_signed: 717 encoding = CTF_INT_SIGNED; 718 type = CTF_K_INTEGER; 719 break; 720 case DW_ATE_signed_char: 721 encoding = CTF_INT_SIGNED | CTF_INT_CHAR; 722 type = CTF_K_INTEGER; 723 break; 724 case DW_ATE_boolean: 725 encoding = CTF_INT_SIGNED | CTF_INT_BOOL; 726 type = CTF_K_INTEGER; 727 break; 728 case DW_ATE_float: 729 if (bits < psz) 730 encoding = CTF_FP_SINGLE; 731 else if (bits == psz) 732 encoding = CTF_FP_DOUBLE; 733 else 734 encoding = CTF_FP_LDOUBLE; 735 type = CTF_K_FLOAT; 736 break; 737 case DW_ATE_complex_float: 738 if (bits < psz) 739 encoding = CTF_FP_CPLX; 740 else if (bits == psz) 741 encoding = CTF_FP_DCPLX; 742 else 743 encoding = CTF_FP_LDCPLX; 744 type = CTF_K_FLOAT; 745 break; 746 case DW_ATE_imaginary_float: 747 if (bits < psz) 748 encoding = CTF_FP_IMAGRY; 749 else if (bits == psz) 750 encoding = CTF_FP_DIMAGRY; 751 else 752 encoding = CTF_FP_LDIMAGRY; 753 type = CTF_K_FLOAT; 754 break; 755 default: 756 DPRINTF("unknown encoding: %d\n", enc); 757 return (NULL); 758 } 759 760 it = it_new(++tidx, die->die_offset, enc2name(enc), bits, 761 encoding, 0, type, 0); 762 763 return it; 764 } 765 766 struct itype * 767 parse_refers(struct dwdie *die, size_t psz, int type) 768 { 769 struct itype *it; 770 struct dwaval *dav; 771 const char *name = NULL; 772 size_t ref = 0, size = 0; 773 774 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 775 switch (dav->dav_dat->dat_attr) { 776 case DW_AT_name: 777 name = dav2str(dav); 778 break; 779 case DW_AT_type: 780 ref = dav2val(dav, psz); 781 break; 782 case DW_AT_byte_size: 783 size = dav2val(dav, psz); 784 assert(size < UINT_MAX); 785 break; 786 default: 787 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 788 break; 789 } 790 } 791 792 it = it_new(++tidx, die->die_offset, name, size, 0, ref, type, 793 ITF_UNRES); 794 795 if (it->it_ref == 0 && (it->it_size == sizeof(void *) || 796 type == CTF_K_CONST || type == CTF_K_VOLATILE || 797 type == CTF_K_POINTER)) { 798 /* Work around GCC/clang not emiting a type for void */ 799 it->it_flags &= ~ITF_UNRES; 800 it->it_ref = VOID_OFFSET; 801 it->it_refp = void_it; 802 } 803 804 return it; 805 } 806 807 struct itype * 808 parse_array(struct dwdie *die, size_t psz) 809 { 810 struct itype *it; 811 struct dwaval *dav; 812 const char *name = NULL; 813 size_t ref = 0; 814 815 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 816 switch (dav->dav_dat->dat_attr) { 817 case DW_AT_name: 818 name = dav2str(dav); 819 break; 820 case DW_AT_type: 821 ref = dav2val(dav, psz); 822 break; 823 default: 824 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 825 break; 826 } 827 } 828 829 it = it_new(++tidx, die->die_offset, name, 0, 0, ref, CTF_K_ARRAY, 830 ITF_UNRES); 831 832 subparse_subrange(die, psz, it); 833 834 return it; 835 } 836 837 struct itype * 838 parse_enum(struct dwdie *die, size_t psz) 839 { 840 struct itype *it; 841 struct dwaval *dav; 842 const char *name = NULL; 843 size_t size = 0; 844 845 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 846 switch (dav->dav_dat->dat_attr) { 847 case DW_AT_byte_size: 848 size = dav2val(dav, psz); 849 assert(size < UINT_MAX); 850 break; 851 case DW_AT_name: 852 name = dav2str(dav); 853 break; 854 default: 855 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 856 break; 857 } 858 } 859 860 it = it_new(++tidx, die->die_offset, name, size, 0, 0, CTF_K_ENUM, 0); 861 862 subparse_enumerator(die, psz, it); 863 864 return it; 865 } 866 867 void 868 subparse_subrange(struct dwdie *die, size_t psz, struct itype *it) 869 { 870 struct dwaval *dav; 871 872 assert(it->it_type == CTF_K_ARRAY); 873 874 if (die->die_dab->dab_children == DW_CHILDREN_no) 875 return; 876 877 /* 878 * This loop assumes that the children of a DIE are just 879 * after it on the list. 880 */ 881 while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) { 882 uint64_t tag = die->die_dab->dab_tag; 883 size_t nelems = 0; 884 885 if (tag != DW_TAG_subrange_type) 886 break; 887 888 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 889 switch (dav->dav_dat->dat_attr) { 890 case DW_AT_count: 891 nelems = dav2val(dav, psz); 892 break; 893 case DW_AT_upper_bound: 894 nelems = dav2val(dav, psz) + 1; 895 break; 896 default: 897 DPRINTF("%s\n", 898 dw_at2name(dav->dav_dat->dat_attr)); 899 break; 900 } 901 } 902 903 assert(nelems < UINT_MAX); 904 it->it_nelems = nelems; 905 } 906 } 907 908 void 909 subparse_enumerator(struct dwdie *die, size_t psz, struct itype *it) 910 { 911 struct imember *im; 912 struct dwaval *dav; 913 914 assert(it->it_type == CTF_K_ENUM); 915 916 if (die->die_dab->dab_children == DW_CHILDREN_no) 917 return; 918 919 /* 920 * This loop assumes that the children of a DIE are just 921 * after it on the list. 922 */ 923 while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) { 924 uint64_t tag = die->die_dab->dab_tag; 925 size_t val = 0; 926 const char *name = NULL; 927 928 if (tag != DW_TAG_enumerator) 929 break; 930 931 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 932 switch (dav->dav_dat->dat_attr) { 933 case DW_AT_name: 934 name = dav2str(dav); 935 break; 936 case DW_AT_const_value: 937 val = dav2val(dav, psz); 938 break; 939 default: 940 DPRINTF("%s\n", 941 dw_at2name(dav->dav_dat->dat_attr)); 942 break; 943 } 944 } 945 946 if (name == NULL) { 947 warnx("%s with anon member", it_name(it)); 948 continue; 949 } 950 951 im = im_new(name, val, 0); 952 assert(it->it_nelems < UINT_MAX); 953 it->it_nelems++; 954 TAILQ_INSERT_TAIL(&it->it_members, im, im_next); 955 } 956 } 957 958 struct itype * 959 parse_struct(struct dwdie *die, size_t psz, int type, size_t off) 960 { 961 struct itype *it = NULL; 962 struct dwaval *dav; 963 const char *name = NULL; 964 size_t size = 0; 965 966 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 967 switch (dav->dav_dat->dat_attr) { 968 case DW_AT_byte_size: 969 size = dav2val(dav, psz); 970 assert(size < UINT_MAX); 971 break; 972 case DW_AT_name: 973 name = dav2str(dav); 974 break; 975 default: 976 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 977 break; 978 } 979 } 980 981 it = it_new(++tidx, die->die_offset, name, size, 0, 0, type, 0); 982 983 subparse_member(die, psz, it, off); 984 985 return it; 986 } 987 988 void 989 subparse_member(struct dwdie *die, size_t psz, struct itype *it, size_t offset) 990 { 991 struct imember *im; 992 struct dwaval *dav; 993 const char *name; 994 size_t off = 0, ref = 0, bits = 0; 995 uint8_t lvl = die->die_lvl; 996 997 assert(it->it_type == CTF_K_STRUCT || it->it_type == CTF_K_UNION); 998 999 if (die->die_dab->dab_children == DW_CHILDREN_no) 1000 return; 1001 1002 /* 1003 * This loop assumes that the children of a DIE are just 1004 * after it on the list. 1005 */ 1006 while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) { 1007 int64_t tag = die->die_dab->dab_tag; 1008 1009 name = NULL; 1010 if (die->die_lvl <= lvl) 1011 break; 1012 1013 /* Skip members of members */ 1014 if (die->die_lvl > lvl + 1) 1015 continue; 1016 /* 1017 * Nested declaration. 1018 * 1019 * This matches the case where a ``struct'', ``union'', 1020 * ``enum'' or ``typedef'' is first declared "inside" a 1021 * union or struct declaration. 1022 */ 1023 if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type || 1024 tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef) 1025 continue; 1026 1027 it->it_flags |= ITF_UNRES_MEMB; 1028 1029 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1030 switch (dav->dav_dat->dat_attr) { 1031 case DW_AT_name: 1032 name = dav2str(dav); 1033 break; 1034 case DW_AT_type: 1035 ref = dav2val(dav, psz); 1036 break; 1037 case DW_AT_data_member_location: 1038 off = 8 * dav2val(dav, psz); 1039 break; 1040 case DW_AT_bit_size: 1041 bits = dav2val(dav, psz); 1042 assert(bits < USHRT_MAX); 1043 break; 1044 default: 1045 DPRINTF("%s\n", 1046 dw_at2name(dav->dav_dat->dat_attr)); 1047 break; 1048 } 1049 } 1050 1051 /* 1052 * When a structure is declared inside an union, we 1053 * have to generate a reference to make the resolver 1054 * happy. 1055 */ 1056 if ((ref == 0) && (tag == DW_TAG_structure_type)) 1057 ref = die->die_offset - offset; 1058 1059 im = im_new(name, ref, off); 1060 assert(it->it_nelems < UINT_MAX); 1061 it->it_nelems++; 1062 TAILQ_INSERT_TAIL(&it->it_members, im, im_next); 1063 } 1064 } 1065 1066 1067 void 1068 subparse_arguments(struct dwdie *die, size_t psz, struct itype *it) 1069 { 1070 struct imember *im; 1071 struct dwaval *dav; 1072 size_t ref = 0; 1073 1074 assert(it->it_type == CTF_K_FUNCTION); 1075 1076 if (die->die_dab->dab_children == DW_CHILDREN_no) 1077 return; 1078 1079 /* 1080 * This loop assumes that the children of a DIE are after it 1081 * on the list. 1082 */ 1083 while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) { 1084 uint64_t tag = die->die_dab->dab_tag; 1085 1086 if (tag == DW_TAG_unspecified_parameters) { 1087 it->it_flags |= ITF_VARARGS; 1088 continue; 1089 } 1090 1091 /* 1092 * Nested declaration. 1093 * 1094 * This matches the case where a ``struct'', ``union'', 1095 * ``enum'' or ``typedef'' is first declared "inside" a 1096 * function declaration. 1097 */ 1098 if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type || 1099 tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef) 1100 continue; 1101 1102 if (tag != DW_TAG_formal_parameter) 1103 break; 1104 1105 it->it_flags |= ITF_UNRES_MEMB; 1106 1107 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1108 switch (dav->dav_dat->dat_attr) { 1109 case DW_AT_type: 1110 ref = dav2val(dav, psz); 1111 break; 1112 default: 1113 DPRINTF("%s\n", 1114 dw_at2name(dav->dav_dat->dat_attr)); 1115 break; 1116 } 1117 } 1118 1119 im = im_new(NULL, ref, 0); 1120 assert(it->it_nelems < UINT_MAX); 1121 it->it_nelems++; 1122 TAILQ_INSERT_TAIL(&it->it_members, im, im_next); 1123 } 1124 } 1125 1126 struct itype * 1127 parse_function(struct dwdie *die, size_t psz) 1128 { 1129 struct itype *it; 1130 struct dwaval *dav; 1131 const char *name = NULL; 1132 size_t ref = 0; 1133 1134 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1135 switch (dav->dav_dat->dat_attr) { 1136 case DW_AT_name: 1137 name = dav2str(dav); 1138 break; 1139 case DW_AT_type: 1140 ref = dav2val(dav, psz); 1141 break; 1142 case DW_AT_abstract_origin: 1143 /* 1144 * Skip second empty definition for inline 1145 * functions. 1146 */ 1147 return NULL; 1148 default: 1149 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 1150 break; 1151 } 1152 } 1153 1154 /* 1155 * Work around for clang 4.0 generating DW_TAG_subprogram without 1156 * any attribute. 1157 */ 1158 if (name == NULL) 1159 return NULL; 1160 1161 it = it_new(++fidx, die->die_offset, name, 0, 0, ref, CTF_K_FUNCTION, 1162 ITF_UNRES|ITF_FUNC); 1163 1164 subparse_arguments(die, psz, it); 1165 1166 if (it->it_ref == 0) { 1167 /* Work around GCC not emiting a type for void */ 1168 it->it_flags &= ~ITF_UNRES; 1169 it->it_ref = VOID_OFFSET; 1170 it->it_refp = void_it; 1171 } 1172 1173 return it; 1174 } 1175 1176 struct itype * 1177 parse_funcptr(struct dwdie *die, size_t psz) 1178 { 1179 struct itype *it; 1180 struct dwaval *dav; 1181 const char *name = NULL; 1182 size_t ref = 0; 1183 1184 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1185 switch (dav->dav_dat->dat_attr) { 1186 case DW_AT_name: 1187 name = dav2str(dav); 1188 break; 1189 case DW_AT_type: 1190 ref = dav2val(dav, psz); 1191 break; 1192 default: 1193 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 1194 break; 1195 } 1196 } 1197 1198 it = it_new(++tidx, die->die_offset, name, 0, 0, ref, CTF_K_FUNCTION, 1199 ITF_UNRES); 1200 1201 subparse_arguments(die, psz, it); 1202 1203 if (it->it_ref == 0) { 1204 /* Work around GCC not emiting a type for void */ 1205 it->it_flags &= ~ITF_UNRES; 1206 it->it_ref = VOID_OFFSET; 1207 it->it_refp = void_it; 1208 } 1209 1210 return it; 1211 } 1212 1213 struct itype * 1214 parse_variable(struct dwdie *die, size_t psz) 1215 { 1216 struct itype *it = NULL; 1217 struct dwaval *dav; 1218 const char *name = NULL; 1219 size_t ref = 0; 1220 int declaration = 0; 1221 1222 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1223 switch (dav->dav_dat->dat_attr) { 1224 case DW_AT_declaration: 1225 declaration = dav2val(dav, psz); 1226 break; 1227 case DW_AT_name: 1228 name = dav2str(dav); 1229 break; 1230 case DW_AT_type: 1231 ref = dav2val(dav, psz); 1232 break; 1233 default: 1234 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 1235 break; 1236 } 1237 } 1238 1239 1240 if (!declaration && name != NULL) { 1241 it = it_new(++oidx, die->die_offset, name, 0, 0, ref, 0, 1242 ITF_UNRES|ITF_OBJ); 1243 } 1244 1245 return it; 1246 } 1247 1248 size_t 1249 dav2val(struct dwaval *dav, size_t psz) 1250 { 1251 uint64_t val = (uint64_t)-1; 1252 1253 switch (dav->dav_dat->dat_form) { 1254 case DW_FORM_addr: 1255 case DW_FORM_ref_addr: 1256 if (psz == sizeof(uint32_t)) 1257 val = dav->dav_u32; 1258 else 1259 val = dav->dav_u64; 1260 break; 1261 case DW_FORM_block1: 1262 case DW_FORM_block2: 1263 case DW_FORM_block4: 1264 case DW_FORM_block: 1265 dw_loc_parse(&dav->dav_buf, NULL, &val, NULL); 1266 break; 1267 case DW_FORM_flag: 1268 case DW_FORM_data1: 1269 case DW_FORM_ref1: 1270 val = dav->dav_u8; 1271 break; 1272 case DW_FORM_data2: 1273 case DW_FORM_ref2: 1274 val = dav->dav_u16; 1275 break; 1276 case DW_FORM_data4: 1277 case DW_FORM_ref4: 1278 val = dav->dav_u32; 1279 break; 1280 case DW_FORM_sdata: 1281 case DW_FORM_data8: 1282 case DW_FORM_ref8: 1283 val = dav->dav_u64; 1284 break; 1285 case DW_FORM_strp: 1286 val = dav->dav_u32; 1287 break; 1288 case DW_FORM_flag_present: 1289 val = 1; 1290 break; 1291 default: 1292 break; 1293 } 1294 1295 return val; 1296 } 1297 1298 const char * 1299 dav2str(struct dwaval *dav) 1300 { 1301 const char *str = NULL; 1302 extern const char *dstrbuf; 1303 extern size_t dstrlen; 1304 1305 switch (dav->dav_dat->dat_form) { 1306 case DW_FORM_string: 1307 str = dav->dav_str; 1308 break; 1309 case DW_FORM_strp: 1310 if (dav->dav_u32 >= dstrlen) 1311 str = NULL; 1312 else 1313 str = dstrbuf + dav->dav_u32; 1314 break; 1315 default: 1316 break; 1317 } 1318 1319 return str; 1320 } 1321 1322 const char * 1323 enc2name(unsigned short enc) 1324 { 1325 static const char *enc_name[] = { "address", "boolean", "complex float", 1326 "float", "signed", "char", "unsigned", "unsigned char", 1327 "imaginary float", "packed decimal", "numeric string", "edited", 1328 "signed fixed", "unsigned fixed", "decimal float" }; 1329 1330 if (enc > 0 && enc <= nitems(enc_name)) 1331 return enc_name[enc - 1]; 1332 1333 return "invalid"; 1334 } 1335