1 /* $OpenBSD: parse.c,v 1.4 2017/08/11 16:55:46 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/param.h> 25 #include <sys/types.h> 26 #include <sys/queue.h> 27 #include <sys/tree.h> 28 #include <sys/ctf.h> 29 30 #include <assert.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 break; 610 case DW_TAG_const_type: 611 it = parse_refers(die, psz, CTF_K_CONST); 612 break; 613 case DW_TAG_volatile_type: 614 it = parse_refers(die, psz, CTF_K_VOLATILE); 615 break; 616 case DW_TAG_restrict_type: 617 it = parse_refers(die, psz, CTF_K_RESTRICT); 618 break; 619 case DW_TAG_subprogram: 620 it = parse_function(die, psz); 621 if (it == NULL) 622 continue; 623 break; 624 case DW_TAG_subroutine_type: 625 it = parse_funcptr(die, psz); 626 break; 627 /* 628 * Children are assumed to be right after their parent in 629 * the list. The parent parsing function takes care of 630 * parsing them. 631 */ 632 case DW_TAG_member: 633 assert(it->it_type == CTF_K_STRUCT || 634 it->it_type == CTF_K_UNION || 635 it->it_type == CTF_K_ENUM); 636 continue; 637 case DW_TAG_subrange_type: 638 assert(it->it_type == CTF_K_ARRAY); 639 continue; 640 case DW_TAG_formal_parameter: 641 /* 642 * If we skipped the second inline definition, 643 * skip its arguments. 644 */ 645 if (it == NULL) 646 continue; 647 648 /* See comment in subparse_arguments(). */ 649 if (it->it_type == CTF_K_STRUCT || 650 it->it_type == CTF_K_UNION || 651 it->it_type == CTF_K_ENUM || 652 it->it_type == CTF_K_TYPEDEF) 653 continue; 654 655 if (it->it_flags & ITF_OBJ) 656 continue; 657 658 assert(it->it_type == CTF_K_FUNCTION); 659 continue; 660 case DW_TAG_variable: 661 it = parse_variable(die, psz); 662 /* Unnamed variables are discarded. */ 663 if (it == NULL) 664 continue; 665 break; 666 #if 1 667 case DW_TAG_lexical_block: 668 case DW_TAG_inlined_subroutine: 669 continue; 670 #endif 671 case DW_TAG_compile_unit: 672 default: 673 DPRINTF("%s\n", dw_tag2name(tag)); 674 continue; 675 } 676 677 TAILQ_INSERT_TAIL(cutq, it, it_next); 678 RB_INSERT(ioff_tree, cuot, it); 679 } 680 } 681 682 struct itype * 683 parse_base(struct dwdie *die, size_t psz) 684 { 685 struct itype *it; 686 struct dwaval *dav; 687 uint16_t encoding, enc = 0, bits = 0; 688 int type; 689 690 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 691 switch (dav->dav_dat->dat_attr) { 692 case DW_AT_encoding: 693 enc = dav2val(dav, psz); 694 break; 695 case DW_AT_byte_size: 696 bits = 8 * dav2val(dav, psz); 697 break; 698 default: 699 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 700 break; 701 } 702 } 703 704 switch (enc) { 705 case DW_ATE_unsigned: 706 case DW_ATE_address: 707 encoding = 0; 708 type = CTF_K_INTEGER; 709 break; 710 case DW_ATE_unsigned_char: 711 encoding = CTF_INT_CHAR; 712 type = CTF_K_INTEGER; 713 break; 714 case DW_ATE_signed: 715 encoding = CTF_INT_SIGNED; 716 type = CTF_K_INTEGER; 717 break; 718 case DW_ATE_signed_char: 719 encoding = CTF_INT_SIGNED | CTF_INT_CHAR; 720 type = CTF_K_INTEGER; 721 break; 722 case DW_ATE_boolean: 723 encoding = CTF_INT_SIGNED | CTF_INT_BOOL; 724 type = CTF_K_INTEGER; 725 break; 726 case DW_ATE_float: 727 if (bits < psz) 728 encoding = CTF_FP_SINGLE; 729 else if (bits == psz) 730 encoding = CTF_FP_DOUBLE; 731 else 732 encoding = CTF_FP_LDOUBLE; 733 type = CTF_K_FLOAT; 734 break; 735 case DW_ATE_complex_float: 736 if (bits < psz) 737 encoding = CTF_FP_CPLX; 738 else if (bits == psz) 739 encoding = CTF_FP_DCPLX; 740 else 741 encoding = CTF_FP_LDCPLX; 742 type = CTF_K_FLOAT; 743 break; 744 case DW_ATE_imaginary_float: 745 if (bits < psz) 746 encoding = CTF_FP_IMAGRY; 747 else if (bits == psz) 748 encoding = CTF_FP_DIMAGRY; 749 else 750 encoding = CTF_FP_LDIMAGRY; 751 type = CTF_K_FLOAT; 752 break; 753 default: 754 DPRINTF("unknown encoding: %d\n", enc); 755 return (NULL); 756 } 757 758 it = it_new(++tidx, die->die_offset, enc2name(enc), bits, 759 encoding, 0, type, 0); 760 761 return it; 762 } 763 764 struct itype * 765 parse_refers(struct dwdie *die, size_t psz, int type) 766 { 767 struct itype *it; 768 struct dwaval *dav; 769 const char *name = NULL; 770 size_t ref = 0, size = 0; 771 772 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 773 switch (dav->dav_dat->dat_attr) { 774 case DW_AT_name: 775 name = dav2str(dav); 776 break; 777 case DW_AT_type: 778 ref = dav2val(dav, psz); 779 break; 780 case DW_AT_byte_size: 781 size = dav2val(dav, psz); 782 assert(size < UINT_MAX); 783 break; 784 default: 785 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 786 break; 787 } 788 } 789 790 it = it_new(++tidx, die->die_offset, name, size, 0, ref, type, 791 ITF_UNRES); 792 793 if (it->it_ref == 0 && (it->it_size == sizeof(void *) || 794 type == CTF_K_CONST || type == CTF_K_VOLATILE || 795 type == CTF_K_POINTER)) { 796 /* Work around GCC/clang not emiting a type for void */ 797 it->it_flags &= ~ITF_UNRES; 798 it->it_ref = VOID_OFFSET; 799 it->it_refp = void_it; 800 } 801 802 return it; 803 } 804 805 struct itype * 806 parse_array(struct dwdie *die, size_t psz) 807 { 808 struct itype *it; 809 struct dwaval *dav; 810 const char *name = NULL; 811 size_t ref = 0; 812 813 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 814 switch (dav->dav_dat->dat_attr) { 815 case DW_AT_name: 816 name = dav2str(dav); 817 break; 818 case DW_AT_type: 819 ref = dav2val(dav, psz); 820 break; 821 default: 822 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 823 break; 824 } 825 } 826 827 it = it_new(++tidx, die->die_offset, name, 0, 0, ref, CTF_K_ARRAY, 828 ITF_UNRES); 829 830 subparse_subrange(die, psz, it); 831 832 return it; 833 } 834 835 struct itype * 836 parse_enum(struct dwdie *die, size_t psz) 837 { 838 struct itype *it; 839 struct dwaval *dav; 840 const char *name = NULL; 841 size_t size = 0; 842 843 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 844 switch (dav->dav_dat->dat_attr) { 845 case DW_AT_byte_size: 846 size = dav2val(dav, psz); 847 assert(size < UINT_MAX); 848 break; 849 case DW_AT_name: 850 name = dav2str(dav); 851 break; 852 default: 853 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 854 break; 855 } 856 } 857 858 it = it_new(++tidx, die->die_offset, name, size, 0, 0, CTF_K_ENUM, 0); 859 860 subparse_enumerator(die, psz, it); 861 862 return it; 863 } 864 865 void 866 subparse_subrange(struct dwdie *die, size_t psz, struct itype *it) 867 { 868 struct dwaval *dav; 869 870 assert(it->it_type == CTF_K_ARRAY); 871 872 if (die->die_dab->dab_children == DW_CHILDREN_no) 873 return; 874 875 /* 876 * This loop assumes that the children of a DIE are just 877 * after it on the list. 878 */ 879 while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) { 880 uint64_t tag = die->die_dab->dab_tag; 881 size_t nelems = 0; 882 883 if (tag != DW_TAG_subrange_type) 884 break; 885 886 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 887 switch (dav->dav_dat->dat_attr) { 888 case DW_AT_count: 889 nelems = dav2val(dav, psz); 890 break; 891 case DW_AT_upper_bound: 892 nelems = dav2val(dav, psz) + 1; 893 break; 894 default: 895 DPRINTF("%s\n", 896 dw_at2name(dav->dav_dat->dat_attr)); 897 break; 898 } 899 } 900 901 assert(nelems < UINT_MAX); 902 it->it_nelems = nelems; 903 } 904 } 905 906 void 907 subparse_enumerator(struct dwdie *die, size_t psz, struct itype *it) 908 { 909 struct imember *im; 910 struct dwaval *dav; 911 912 assert(it->it_type == CTF_K_ENUM); 913 914 if (die->die_dab->dab_children == DW_CHILDREN_no) 915 return; 916 917 /* 918 * This loop assumes that the children of a DIE are just 919 * after it on the list. 920 */ 921 while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) { 922 uint64_t tag = die->die_dab->dab_tag; 923 size_t val = 0; 924 const char *name = NULL; 925 926 if (tag != DW_TAG_enumerator) 927 break; 928 929 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 930 switch (dav->dav_dat->dat_attr) { 931 case DW_AT_name: 932 name = dav2str(dav); 933 break; 934 case DW_AT_const_value: 935 val = dav2val(dav, psz); 936 break; 937 default: 938 DPRINTF("%s\n", 939 dw_at2name(dav->dav_dat->dat_attr)); 940 break; 941 } 942 } 943 944 if (name == NULL) { 945 warnx("%s with anon member", it_name(it)); 946 continue; 947 } 948 949 im = im_new(name, val, 0); 950 assert(it->it_nelems < UINT_MAX); 951 it->it_nelems++; 952 TAILQ_INSERT_TAIL(&it->it_members, im, im_next); 953 } 954 } 955 956 struct itype * 957 parse_struct(struct dwdie *die, size_t psz, int type, size_t off) 958 { 959 struct itype *it = NULL; 960 struct dwaval *dav; 961 const char *name = NULL; 962 size_t size = 0; 963 964 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 965 switch (dav->dav_dat->dat_attr) { 966 case DW_AT_byte_size: 967 size = dav2val(dav, psz); 968 assert(size < UINT_MAX); 969 break; 970 case DW_AT_name: 971 name = dav2str(dav); 972 break; 973 default: 974 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 975 break; 976 } 977 } 978 979 it = it_new(++tidx, die->die_offset, name, size, 0, 0, type, 0); 980 981 subparse_member(die, psz, it, off); 982 983 return it; 984 } 985 986 void 987 subparse_member(struct dwdie *die, size_t psz, struct itype *it, size_t offset) 988 { 989 struct imember *im; 990 struct dwaval *dav; 991 const char *name; 992 size_t off = 0, ref = 0, bits = 0; 993 uint8_t lvl = die->die_lvl; 994 995 assert(it->it_type == CTF_K_STRUCT || it->it_type == CTF_K_UNION); 996 997 if (die->die_dab->dab_children == DW_CHILDREN_no) 998 return; 999 1000 /* 1001 * This loop assumes that the children of a DIE are just 1002 * after it on the list. 1003 */ 1004 while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) { 1005 int64_t tag = die->die_dab->dab_tag; 1006 1007 name = NULL; 1008 if (die->die_lvl <= lvl) 1009 break; 1010 1011 /* Skip members of members */ 1012 if (die->die_lvl > lvl + 1) 1013 continue; 1014 /* 1015 * Nested declaration. 1016 * 1017 * This matches the case where a ``struct'', ``union'', 1018 * ``enum'' or ``typedef'' is first declared "inside" a 1019 * union or struct declaration. 1020 */ 1021 if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type || 1022 tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef) 1023 continue; 1024 1025 it->it_flags |= ITF_UNRES_MEMB; 1026 1027 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1028 switch (dav->dav_dat->dat_attr) { 1029 case DW_AT_name: 1030 name = dav2str(dav); 1031 break; 1032 case DW_AT_type: 1033 ref = dav2val(dav, psz); 1034 break; 1035 case DW_AT_data_member_location: 1036 off = 8 * dav2val(dav, psz); 1037 break; 1038 case DW_AT_bit_size: 1039 bits = dav2val(dav, psz); 1040 assert(bits < USHRT_MAX); 1041 break; 1042 default: 1043 DPRINTF("%s\n", 1044 dw_at2name(dav->dav_dat->dat_attr)); 1045 break; 1046 } 1047 } 1048 1049 /* 1050 * When a structure is declared inside an union, we 1051 * have to generate a reference to make the resolver 1052 * happy. 1053 */ 1054 if ((ref == 0) && (tag == DW_TAG_structure_type)) 1055 ref = die->die_offset - offset; 1056 1057 im = im_new(name, ref, off); 1058 assert(it->it_nelems < UINT_MAX); 1059 it->it_nelems++; 1060 TAILQ_INSERT_TAIL(&it->it_members, im, im_next); 1061 } 1062 } 1063 1064 1065 void 1066 subparse_arguments(struct dwdie *die, size_t psz, struct itype *it) 1067 { 1068 struct imember *im; 1069 struct dwaval *dav; 1070 size_t ref = 0; 1071 1072 assert(it->it_type == CTF_K_FUNCTION); 1073 1074 if (die->die_dab->dab_children == DW_CHILDREN_no) 1075 return; 1076 1077 /* 1078 * This loop assumes that the children of a DIE are after it 1079 * on the list. 1080 */ 1081 while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) { 1082 uint64_t tag = die->die_dab->dab_tag; 1083 1084 if (tag == DW_TAG_unspecified_parameters) { 1085 it->it_flags |= ITF_VARARGS; 1086 continue; 1087 } 1088 1089 /* 1090 * Nested declaration. 1091 * 1092 * This matches the case where a ``struct'', ``union'', 1093 * ``enum'' or ``typedef'' is first declared "inside" a 1094 * function declaration. 1095 */ 1096 if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type || 1097 tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef) 1098 continue; 1099 1100 if (tag != DW_TAG_formal_parameter) 1101 break; 1102 1103 it->it_flags |= ITF_UNRES_MEMB; 1104 1105 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1106 switch (dav->dav_dat->dat_attr) { 1107 case DW_AT_type: 1108 ref = dav2val(dav, psz); 1109 break; 1110 default: 1111 DPRINTF("%s\n", 1112 dw_at2name(dav->dav_dat->dat_attr)); 1113 break; 1114 } 1115 } 1116 1117 im = im_new(NULL, ref, 0); 1118 assert(it->it_nelems < UINT_MAX); 1119 it->it_nelems++; 1120 TAILQ_INSERT_TAIL(&it->it_members, im, im_next); 1121 } 1122 } 1123 1124 struct itype * 1125 parse_function(struct dwdie *die, size_t psz) 1126 { 1127 struct itype *it; 1128 struct dwaval *dav; 1129 const char *name = NULL; 1130 size_t ref = 0; 1131 1132 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1133 switch (dav->dav_dat->dat_attr) { 1134 case DW_AT_name: 1135 name = dav2str(dav); 1136 break; 1137 case DW_AT_type: 1138 ref = dav2val(dav, psz); 1139 break; 1140 case DW_AT_abstract_origin: 1141 /* 1142 * Skip second empty definition for inline 1143 * functions. 1144 */ 1145 return NULL; 1146 default: 1147 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 1148 break; 1149 } 1150 } 1151 1152 /* 1153 * Work around for clang 4.0 generating DW_TAG_subprogram without 1154 * any attribute. 1155 */ 1156 if (name == NULL) 1157 return NULL; 1158 1159 it = it_new(++fidx, die->die_offset, name, 0, 0, ref, CTF_K_FUNCTION, 1160 ITF_UNRES|ITF_FUNC); 1161 1162 subparse_arguments(die, psz, it); 1163 1164 if (it->it_ref == 0) { 1165 /* Work around GCC not emiting a type for void */ 1166 it->it_flags &= ~ITF_UNRES; 1167 it->it_ref = VOID_OFFSET; 1168 it->it_refp = void_it; 1169 } 1170 1171 return it; 1172 } 1173 1174 struct itype * 1175 parse_funcptr(struct dwdie *die, size_t psz) 1176 { 1177 struct itype *it; 1178 struct dwaval *dav; 1179 const char *name = NULL; 1180 size_t ref = 0; 1181 1182 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1183 switch (dav->dav_dat->dat_attr) { 1184 case DW_AT_name: 1185 name = dav2str(dav); 1186 break; 1187 case DW_AT_type: 1188 ref = dav2val(dav, psz); 1189 break; 1190 default: 1191 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 1192 break; 1193 } 1194 } 1195 1196 it = it_new(++tidx, die->die_offset, name, 0, 0, ref, CTF_K_FUNCTION, 1197 ITF_UNRES); 1198 1199 subparse_arguments(die, psz, it); 1200 1201 if (it->it_ref == 0) { 1202 /* Work around GCC not emiting a type for void */ 1203 it->it_flags &= ~ITF_UNRES; 1204 it->it_ref = VOID_OFFSET; 1205 it->it_refp = void_it; 1206 } 1207 1208 return it; 1209 } 1210 1211 struct itype * 1212 parse_variable(struct dwdie *die, size_t psz) 1213 { 1214 struct itype *it = NULL; 1215 struct dwaval *dav; 1216 const char *name = NULL; 1217 size_t ref = 0; 1218 int declaration = 0; 1219 1220 SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) { 1221 switch (dav->dav_dat->dat_attr) { 1222 case DW_AT_declaration: 1223 declaration = dav2val(dav, psz); 1224 break; 1225 case DW_AT_name: 1226 name = dav2str(dav); 1227 break; 1228 case DW_AT_type: 1229 ref = dav2val(dav, psz); 1230 break; 1231 default: 1232 DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr)); 1233 break; 1234 } 1235 } 1236 1237 1238 if (!declaration && name != NULL) { 1239 it = it_new(++oidx, die->die_offset, name, 0, 0, ref, 0, 1240 ITF_UNRES|ITF_OBJ); 1241 } 1242 1243 return it; 1244 } 1245 1246 size_t 1247 dav2val(struct dwaval *dav, size_t psz) 1248 { 1249 uint64_t val = (uint64_t)-1; 1250 1251 switch (dav->dav_dat->dat_form) { 1252 case DW_FORM_addr: 1253 case DW_FORM_ref_addr: 1254 if (psz == sizeof(uint32_t)) 1255 val = dav->dav_u32; 1256 else 1257 val = dav->dav_u64; 1258 break; 1259 case DW_FORM_block1: 1260 case DW_FORM_block2: 1261 case DW_FORM_block4: 1262 case DW_FORM_block: 1263 dw_loc_parse(&dav->dav_buf, NULL, &val, NULL); 1264 break; 1265 case DW_FORM_flag: 1266 case DW_FORM_data1: 1267 case DW_FORM_ref1: 1268 val = dav->dav_u8; 1269 break; 1270 case DW_FORM_data2: 1271 case DW_FORM_ref2: 1272 val = dav->dav_u16; 1273 break; 1274 case DW_FORM_data4: 1275 case DW_FORM_ref4: 1276 val = dav->dav_u32; 1277 break; 1278 case DW_FORM_sdata: 1279 case DW_FORM_data8: 1280 case DW_FORM_ref8: 1281 val = dav->dav_u64; 1282 break; 1283 case DW_FORM_strp: 1284 val = dav->dav_u32; 1285 break; 1286 case DW_FORM_flag_present: 1287 val = 1; 1288 break; 1289 default: 1290 break; 1291 } 1292 1293 return val; 1294 } 1295 1296 const char * 1297 dav2str(struct dwaval *dav) 1298 { 1299 const char *str = NULL; 1300 extern const char *dstrbuf; 1301 1302 switch (dav->dav_dat->dat_form) { 1303 case DW_FORM_string: 1304 str = dav->dav_str; 1305 break; 1306 case DW_FORM_strp: 1307 str = dstrbuf + dav->dav_u32; 1308 break; 1309 default: 1310 break; 1311 } 1312 1313 return str; 1314 } 1315 1316 const char * 1317 enc2name(unsigned short enc) 1318 { 1319 static const char *enc_name[] = { "address", "boolean", "complex float", 1320 "float", "signed", "char", "unsigned", "unsigned char", 1321 "imaginary float", "packed decimal", "numeric string", "edited", 1322 "signed fixed", "unsigned fixed", "decimal float" }; 1323 1324 if (enc > 0 && enc <= nitems(enc_name)) 1325 return enc_name[enc - 1]; 1326 1327 return "invalid"; 1328 } 1329