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