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