Changeset 38617 in vbox
- Timestamp:
- Sep 2, 2011 8:22:26 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 73824
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp
r38606 r38617 36 36 #include <iprt/ctype.h> 37 37 #include <iprt/err.h> 38 #include <iprt/list.h> 38 39 #include <iprt/log.h> 39 40 #include <iprt/mem.h> … … 268 269 /** @} */ 269 270 271 /** @name Address classes. 272 * @{ */ 273 #define DW_ADDR_none UINT8_C(0) 274 #define DW_ADDR_i386_near16 UINT8_C(1) 275 #define DW_ADDR_i386_far16 UINT8_C(2) 276 #define DW_ADDR_i386_huge16 UINT8_C(3) 277 #define DW_ADDR_i386_near32 UINT8_C(4) 278 #define DW_ADDR_i386_far32 UINT8_C(5) 279 /** @} */ 280 270 281 271 282 /******************************************************************************* 272 283 * Structures and Typedefs * 273 284 *******************************************************************************/ 285 /** Pointer to a DWARF section reader. */ 286 typedef struct RTDWARFCURSOR *PRTDWARFCURSOR; 287 /** Pointer to an attribute descriptor. */ 288 typedef struct RTDWARFATTRDESC const *PCRTDWARFATTRDESC; 289 /** Pointer to a DIE. */ 290 typedef struct RTDWARFDIE *PRTDWARFDIE; 291 /** Pointer to a const DIE. */ 292 typedef struct RTDWARFDIE const *PCRTDWARFDIE; 293 274 294 /** 275 295 * DWARF sections. … … 344 364 uint32_t cCachedAbbrevs; 345 365 /** Array of cached abbreviations, indexed by code. */ 346 PRTDWARFABBREV 366 PRTDWARFABBREV paCachedAbbrevs; 347 367 /** Used by rtDwarfAbbrev_Lookup when the result is uncachable. */ 348 RTDWARFABBREV LookupAbbrev; 368 RTDWARFABBREV LookupAbbrev; 369 370 /** The list of compilation units (RTDWARFDIE). */ 371 RTLISTNODE CompileUnitList; 349 372 } RTDBGMODDWARF; 350 373 /** Pointer to instance data of the DWARF reader. */ … … 354 377 * DWARF cursor for reading byte data. 355 378 */ 356 typedef struct RTDWARF SECTRDR379 typedef struct RTDWARFCURSOR 357 380 { 358 381 /** The current position. */ … … 380 403 krtDbgModDwarfSect enmSect; 381 404 } RTDWARFCURSOR; 382 /** Pointer to a DWARF section reader. */383 typedef RTDWARFCURSOR *PRTDWARFCURSOR;384 405 385 406 … … 438 459 /** Pointer to a DWARF line number program state. */ 439 460 typedef RTDWARFLINESTATE *PRTDWARFLINESTATE; 461 462 463 /** 464 * Decodes an attribute and stores it in the specified DIE member field. 465 * 466 * @returns IPRT status code. 467 * @param pDie Pointer to the DIE structure. 468 * @param pbMember Pointer to the first byte in the member. 469 * @param pDesc The attribute descriptor. 470 * @param uForm The data form. 471 * @param pDataCursor The cursor to read data from. 472 */ 473 typedef DECLCALLBACK(int) FNRTDWARFATTRDECODER(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 474 uint32_t uForm, PRTDWARFCURSOR pCursor); 475 /** Pointer to an attribute decoder callback. */ 476 typedef FNRTDWARFATTRDECODER *PFNRTDWARFATTRDECODER; 477 478 /** 479 * Attribute descriptor. 480 */ 481 typedef struct RTDWARFATTRDESC 482 { 483 /** The attribute. */ 484 uint8_t uAttr; 485 /** The data member size and initialization method. */ 486 uint8_t cbInit; 487 /** The data member offset. */ 488 uint16_t off; 489 /** The decoder function. */ 490 PFNRTDWARFATTRDECODER pfnDecoder; 491 } RTDWARFATTRDESC; 492 493 /** Define a attribute entry. */ 494 #define ATTR_ENTRY(a_uAttr, a_Struct, a_Member, a_Init, a_pfnDecoder) \ 495 { \ 496 a_uAttr, \ 497 a_Init | ((uint8_t)RT_SIZEOFMEMB(a_Struct, a_Member) & ATTR_SIZE_MASK), \ 498 (uint16_t)RT_OFFSETOF(a_Struct, a_Member), \ 499 a_pfnDecoder\ 500 } 501 502 /** @name Attribute size and init methods. 503 * @{ */ 504 #define ATTR_INIT_ZERO UINT8_C(0x00) 505 #define ATTR_INIT_FFFS UINT8_C(0x40) 506 #define ATTR_INIT_ADDRINFO UINT8_C(0x80) 507 #define ATTR_INIT_RESERVED UINT8_C(0xc0) 508 #define ATTR_INIT_MASK UINT8_C(0xc0) 509 #define ATTR_SIZE_MASK UINT8_C(0x3f) 510 #define ATTR_GET_SIZE(a_pAttrDesc) ((a_pAttrDesc)->cbInit & ATTR_SIZE_MASK) 511 /** @} */ 512 513 514 /** 515 * DIE descriptor. 516 */ 517 typedef struct RTDWARFDIEDESC 518 { 519 /** The number of attributes. */ 520 size_t cAttributes; 521 /** The */ 522 PCRTDWARFATTRDESC paAttributes; 523 } RTDWARFDIEDESC; 524 typedef struct RTDWARFDIEDESC const *PCRTDWARFDIEDESC; 525 526 527 /** 528 * DIE core structure, all inherits (starts with) this. 529 */ 530 typedef struct RTDWARFDIE 531 { 532 /** Pointer to the parent node. NULL if root unit. */ 533 struct RTDWARFDIE *pParent; 534 /** Our node in the sibling list. */ 535 RTLISTNODE SiblingNode; 536 /** List of children. */ 537 RTLISTNODE ChildList; 538 /** The number of attributes successfully decoded. */ 539 uint8_t cDecodedAttrs; 540 /** The number of unknown or otherwise unhandled attributes. */ 541 uint8_t cUnhandledAttrs; 542 /** The date tag, indicating which union structure to use. */ 543 uint16_t uTag; 544 /** Offset of the abbreviation specification (within debug_abbrev). */ 545 uint32_t offSpec; 546 } RTDWARFDIE; 547 548 549 /** 550 * DWARF address structure. 551 */ 552 typedef struct RTDWARFADDR 553 { 554 /** The address. */ 555 uint64_t uAddress; 556 } RTDWARFADDR; 557 558 559 /** 560 * DWARF address range. 561 */ 562 typedef struct RTDWARFADDRRANGE 563 { 564 uint64_t uLowAddress; 565 uint64_t uHighAddress; 566 uint8_t const *pbRanges; /* ?? */ 567 bool fHaveLowAddress : 1; 568 bool fHaveHighAddress : 1; 569 bool fHaveRanges : 1; 570 } RTDWARFADDRRANGE; 571 typedef RTDWARFADDRRANGE *PRTDWARFADDRRANGE; 572 typedef RTDWARFADDRRANGE const *PCRTDWARFADDRRANGE; 573 574 /** What a RTDWARFREF is relative to. */ 575 typedef enum krtDwarfRef 576 { 577 krtDwarfRef_NotSet, 578 krtDwarfRef_LineSection, 579 krtDwarfRef_LocSection, 580 krtDwarfRef_RangesSection, 581 krtDwarfRef_InfoSection, 582 krtDwarfRef_SameUnit, 583 krtDwarfRef_TypeId64 584 } krtDwarfRef; 585 586 /** 587 * DWARF reference. 588 */ 589 typedef struct RTDWARFREF 590 { 591 /** The offset. */ 592 uint64_t off; 593 /** What the offset is relative to. */ 594 krtDwarfRef enmWrt; 595 } RTDWARFREF; 596 typedef RTDWARFREF *PRTDWARFREF; 597 typedef RTDWARFREF const *PCRTDWARFREF; 598 599 600 601 /******************************************************************************* 602 * Internal Functions * 603 *******************************************************************************/ 604 static FNRTDWARFATTRDECODER rtDwarfDecode_Bool; 605 static FNRTDWARFATTRDECODER rtDwarfDecode_LowHighPc; 606 static FNRTDWARFATTRDECODER rtDwarfDecode_Ranges; 607 static FNRTDWARFATTRDECODER rtDwarfDecode_Reference; 608 static FNRTDWARFATTRDECODER rtDwarfDecode_SectOff; 609 static FNRTDWARFATTRDECODER rtDwarfDecode_String; 610 static FNRTDWARFATTRDECODER rtDwarfDecode_UnsignedInt; 611 612 613 /******************************************************************************* 614 * Global Variables * 615 *******************************************************************************/ 616 /** 617 * DW_TAG_compile_unit & DW_TAG_partial_unit. 618 */ 619 typedef struct RTDWARFDIECOMPILEUNIT 620 { 621 /** The DIE core structure. */ 622 RTDWARFDIE Core; 623 /** The unit name. */ 624 const char *pszName; 625 /** The address range of the code belonging to this unit. */ 626 RTDWARFADDRRANGE PcRange; 627 /** The language name. */ 628 uint8_t uLanguage; 629 /** The identifier case. */ 630 uint8_t uIdentifierCase; 631 /** String are UTF-8 encoded. If not set, the encoding is 632 * unknown. */ 633 bool fUseUtf8; 634 /** The unit contains main() or equivalent. */ 635 bool fMainFunction; 636 /** The line numbers for this unit. */ 637 RTDWARFREF StmtListRef; 638 /** The macro information for this unit. */ 639 RTDWARFREF MacroInfoRef; 640 /** Reference to the base types. */ 641 RTDWARFREF BaseTypesRef; 642 /** Working directory for the unit. */ 643 const char *pszCurDir; 644 /** The name of the compiler or whatever that produced this unit. */ 645 const char *pszProducer; 646 647 /** @name From the unit header. 648 * @{ */ 649 /** The offset into debug_info of this unit (for references). */ 650 uint64_t offUnit; 651 /** The length of this unit. */ 652 uint64_t cbUnit; 653 /** The offset into debug_abbrev of the abbreviation for this unit. */ 654 uint64_t offAbbrev; 655 /** The native address size. */ 656 uint8_t cbNativeAddr; 657 /** The DWARF version. */ 658 uint8_t uDwarfVer; 659 /** @} */ 660 } RTDWARFDIECOMPILEUNIT; 661 typedef RTDWARFDIECOMPILEUNIT *PRTDWARFDIECOMPILEUNIT; 662 663 664 /** RTDWARFDIECOMPILEUNIT attributes. */ 665 static const RTDWARFATTRDESC g_aCompileUnitAttrs[] = 666 { 667 ATTR_ENTRY(DW_AT_name, RTDWARFDIECOMPILEUNIT, pszName, ATTR_INIT_ZERO, rtDwarfDecode_String), 668 ATTR_ENTRY(DW_AT_high_pc, RTDWARFDIECOMPILEUNIT, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc), 669 ATTR_ENTRY(DW_AT_ranges, RTDWARFDIECOMPILEUNIT, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_Ranges), 670 ATTR_ENTRY(DW_AT_language, RTDWARFDIECOMPILEUNIT, uLanguage, ATTR_INIT_ZERO, rtDwarfDecode_UnsignedInt), 671 ATTR_ENTRY(DW_AT_macro_info, RTDWARFDIECOMPILEUNIT, MacroInfoRef, ATTR_INIT_FFFS, rtDwarfDecode_SectOff), 672 ATTR_ENTRY(DW_AT_stmt_list, RTDWARFDIECOMPILEUNIT, StmtListRef, ATTR_INIT_FFFS, rtDwarfDecode_SectOff), 673 ATTR_ENTRY(DW_AT_comp_dir, RTDWARFDIECOMPILEUNIT, pszCurDir, ATTR_INIT_ZERO, rtDwarfDecode_String), 674 ATTR_ENTRY(DW_AT_producer, RTDWARFDIECOMPILEUNIT, pszProducer, ATTR_INIT_ZERO, rtDwarfDecode_String), 675 ATTR_ENTRY(DW_AT_identifier_case, RTDWARFDIECOMPILEUNIT, uIdentifierCase,ATTR_INIT_ZERO, rtDwarfDecode_UnsignedInt), 676 ATTR_ENTRY(DW_AT_base_types, RTDWARFDIECOMPILEUNIT, BaseTypesRef, ATTR_INIT_ZERO, rtDwarfDecode_Reference), 677 ATTR_ENTRY(DW_AT_use_UTF8, RTDWARFDIECOMPILEUNIT, fUseUtf8, ATTR_INIT_ZERO, rtDwarfDecode_Bool), 678 ATTR_ENTRY(DW_AT_main_subprogram, RTDWARFDIECOMPILEUNIT, fMainFunction, ATTR_INIT_ZERO, rtDwarfDecode_Bool) 679 }; 680 681 /** RTDWARFDIECOMPILEUNIT description. */ 682 static const RTDWARFDIEDESC g_aCompileUnitDesc = { RT_ELEMENTS(g_aCompileUnitAttrs), &g_aCompileUnitAttrs[0] }; 683 684 685 #ifndef DEFINE_THESE_TAGS_TOO 686 #define DW_TAG_array_type UINT16_C(0x0001) 687 #define DW_TAG_class_type UINT16_C(0x0002) 688 #define DW_TAG_entry_point UINT16_C(0x0003) 689 #define DW_TAG_enumeration_type UINT16_C(0x0004) 690 #define DW_TAG_formal_parameter UINT16_C(0x0005) 691 #define DW_TAG_imported_declaration UINT16_C(0x0008) 692 #define DW_TAG_label UINT16_C(0x000a) 693 #define DW_TAG_lexical_block UINT16_C(0x000b) 694 #define DW_TAG_member UINT16_C(0x000d) 695 #define DW_TAG_pointer_type UINT16_C(0x000f) 696 #define DW_TAG_reference_type UINT16_C(0x0010) 697 #define DW_TAG_compile_unit UINT16_C(0x0011) 698 #define DW_TAG_string_type UINT16_C(0x0012) 699 #define DW_TAG_structure_type UINT16_C(0x0013) 700 #define DW_TAG_subroutine_type UINT16_C(0x0015) 701 #define DW_TAG_typedef UINT16_C(0x0016) 702 #define DW_TAG_union_type UINT16_C(0x0017) 703 #define DW_TAG_unspecified_parameters UINT16_C(0x0018) 704 #define DW_TAG_variant UINT16_C(0x0019) 705 #define DW_TAG_common_block UINT16_C(0x001a) 706 #define DW_TAG_common_inclusion UINT16_C(0x001b) 707 #define DW_TAG_inheritance UINT16_C(0x001c) 708 #define DW_TAG_inlined_subroutine UINT16_C(0x001d) 709 #define DW_TAG_module UINT16_C(0x001e) 710 #define DW_TAG_ptr_to_member_type UINT16_C(0x001f) 711 #define DW_TAG_set_type UINT16_C(0x0020) 712 #define DW_TAG_subrange_type UINT16_C(0x0021) 713 #define DW_TAG_with_stmt UINT16_C(0x0022) 714 #define DW_TAG_access_declaration UINT16_C(0x0023) 715 #define DW_TAG_base_type UINT16_C(0x0024) 716 #define DW_TAG_catch_block UINT16_C(0x0025) 717 #define DW_TAG_const_type UINT16_C(0x0026) 718 #define DW_TAG_constant UINT16_C(0x0027) 719 #define DW_TAG_enumerator UINT16_C(0x0028) 720 #define DW_TAG_file_type UINT16_C(0x0029) 721 #define DW_TAG_friend UINT16_C(0x002a) 722 #define DW_TAG_namelist UINT16_C(0x002b) 723 #define DW_TAG_namelist_item UINT16_C(0x002c) 724 #define DW_TAG_packed_type UINT16_C(0x002d) 725 #define DW_TAG_subprogram UINT16_C(0x002e) 726 #define DW_TAG_template_type_parameter UINT16_C(0x002f) 727 #define DW_TAG_template_value_parameter UINT16_C(0x0030) 728 #define DW_TAG_thrown_type UINT16_C(0x0031) 729 #define DW_TAG_try_block UINT16_C(0x0032) 730 #define DW_TAG_variant_part UINT16_C(0x0033) 731 #define DW_TAG_variable UINT16_C(0x0034) 732 #define DW_TAG_volatile_type UINT16_C(0x0035) 733 #define DW_TAG_dwarf_procedure UINT16_C(0x0036) 734 #define DW_TAG_restrict_type UINT16_C(0x0037) 735 #define DW_TAG_interface_type UINT16_C(0x0038) 736 #define DW_TAG_namespace UINT16_C(0x0039) 737 #define DW_TAG_imported_module UINT16_C(0x003a) 738 #define DW_TAG_unspecified_type UINT16_C(0x003b) 739 #define DW_TAG_partial_unit UINT16_C(0x003c) 740 #define DW_TAG_imported_unit UINT16_C(0x003d) 741 #define DW_TAG_condition UINT16_C(0x003f) 742 #define DW_TAG_shared_type UINT16_C(0x0040) 743 #define DW_TAG_type_unit UINT16_C(0x0041) 744 #define DW_TAG_rvalue_reference_type UINT16_C(0x0042) 745 #define DW_TAG_template_alias UINT16_C(0x0043) 746 #define DW_TAG_lo_user UINT16_C(0x4080) 747 #define DW_TAG_hi_user UINT16_C(0xffff) 748 #endif 749 750 440 751 441 752 … … 1985 2296 1986 2297 2298 1987 2299 /* 1988 2300 * 1989 * DWARF DIE stack (used by the debug_info parser). 1990 * DWARF DIE stack (used by the debug_info parser). 1991 * DWARF DIE stack (used by the debug_info parser). 1992 * 1993 */ 1994 1995 /** 1996 * DWARF DIE stack entry. 1997 */ 1998 typedef struct RTDWARFDIESTACKENTRY 1999 { 2000 /** The abbreviation code. */ 2001 uint32_t uAbbrCode; 2002 /** The tag. */ 2003 uint16_t uTag; 2004 /** The offset into the debug_info section of the data. */ 2005 uint32_t offData; 2006 /** The associated name. (Points into some dwarf section.) */ 2007 const char *pszName; 2008 } RTDWARFDIESTACKENTRY; 2009 /** Pointer to a DIE stack entry. */ 2010 typedef RTDWARFDIESTACKENTRY *PRTDWARFDIESTACKENTRY; 2011 2012 /** 2013 * DWARF DIE stack. 2014 */ 2015 typedef struct RTDWARFDIESTACK 2016 { 2017 /** The number of items on the stack. */ 2018 uint32_t cOnStack; 2019 /** The number of stack entries we've allocated. */ 2020 uint32_t cAlloced; 2021 /** Pointer to the stack entries. */ 2022 PRTDWARFDIESTACKENTRY paEntries; 2023 } RTDWARFDIESTACK; 2024 /** Pointer to a DIE stack. */ 2025 typedef RTDWARFDIESTACK *PRTDWARFDIESTACK; 2026 /** Pointer to a const DIE stack. */ 2027 typedef RTDWARFDIESTACK const *PCRTDWARFDIESTACK; 2028 2029 2030 static int rtDwarfDieStack_SetName(PRTDWARFDIESTACK pStack, const char *pszName) 2031 { 2032 uint32_t i = pStack->cOnStack; 2033 if (i == 0) 2034 return VERR_DWARF_BAD_INFO; 2035 i--; 2036 pStack->paEntries[i].pszName = pszName; 2037 return VINF_SUCCESS; 2038 } 2039 2040 2041 static int rtDwarfDieStack_Push(PRTDWARFDIESTACK pStack, uint32_t uAbbrCode, uint16_t uTag, uint32_t offData) 2042 { 2043 uint32_t i = pStack->cOnStack; 2044 if (i == pStack->cAlloced) 2045 { 2046 uint32_t cNewSize = pStack->cAlloced ? pStack->cAlloced * 2 : 1 /*16*/; 2047 void *pv = RTMemRealloc(pStack->paEntries, sizeof(pStack->paEntries[0]) * cNewSize); 2048 if (!pv) 2049 return VERR_NO_MEMORY; 2050 pStack->paEntries = (PRTDWARFDIESTACKENTRY)pv; 2051 pStack->cAlloced = cNewSize; 2052 } 2053 Assert(i < pStack->cAlloced); 2054 2055 pStack->paEntries[i].uAbbrCode = uAbbrCode; 2056 pStack->paEntries[i].uTag = uTag; 2057 pStack->paEntries[i].offData = offData; 2058 pStack->paEntries[i].pszName = NULL; 2059 pStack->cOnStack = i + 1; 2060 2061 return VINF_SUCCESS; 2062 } 2063 2064 2065 static int rtDwarfDieStack_Pop(PRTDWARFDIESTACK pStack) 2066 { 2067 if (pStack->cOnStack == 0) 2068 return VERR_DWARF_BAD_INFO; 2069 pStack->cOnStack--; 2070 return VINF_SUCCESS; 2071 } 2072 2073 2074 static void rtDwarfDieStack_Init(PRTDWARFDIESTACK pStack) 2075 { 2076 pStack->cOnStack = 0; 2077 pStack->cAlloced = 0; 2078 pStack->paEntries = NULL; 2079 } 2080 2081 2082 static void rtDwarfDieStack_Delete(PRTDWARFDIESTACK pStack) 2083 { 2084 RTMemFree(pStack->paEntries); 2085 pStack->paEntries = NULL; 2086 } 2087 2088 2089 2090 /* 2091 * 2092 * DWARF debug_info parser 2093 * DWARF debug_info parser 2094 * DWARF debug_info parser 2095 * 2096 */ 2301 * DIE Attribute Parsers. 2302 * DIE Attribute Parsers. 2303 * DIE Attribute Parsers. 2304 * 2305 */ 2306 2307 /** 2308 * Gets the compilation unit a DIE belongs to. 2309 * 2310 * @returns The compilation unit DIE. 2311 * @param pDie Some DIE in the unit. 2312 */ 2313 static PRTDWARFDIECOMPILEUNIT rtDwarfDie_GetCompileUnit(PRTDWARFDIE pDie) 2314 { 2315 while (pDie->pParent) 2316 pDie = pDie->pParent; 2317 AssertReturn( pDie->uTag == DW_TAG_compile_unit 2318 || pDie->uTag == DW_TAG_partial_unit, 2319 NULL); 2320 return (PRTDWARFDIECOMPILEUNIT)pDie; 2321 } 2097 2322 2098 2323 … … 2106 2331 * pCursor->rc is set). 2107 2332 */ 2108 static const char *rtDwarf Form_GetStrp(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, const char *pszErrValue)2333 static const char *rtDwarfDecode_GetStrp(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, const char *pszErrValue) 2109 2334 { 2110 2335 uint64_t offDebugStr = rtDwarfCursor_GetUOff(pCursor, UINT64_MAX); … … 2133 2358 } 2134 2359 2360 2361 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2362 static DECLCALLBACK(int) rtDwarfDecode_Bool(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2363 uint32_t uForm, PRTDWARFCURSOR pCursor) 2364 { 2365 AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(bool), VERR_INTERNAL_ERROR_3); 2366 2367 bool *pfMember = (bool *)pbMember; 2368 switch (uForm) 2369 { 2370 case DW_FORM_flag: 2371 { 2372 uint8_t b = rtDwarfCursor_GetU8(pCursor, UINT8_MAX); 2373 if (b > 1) 2374 return RT_FAILURE(pCursor->rc) ? pCursor->rc : pCursor->rc = VERR_DWARF_BAD_INFO; 2375 *pfMember = RT_BOOL(b); 2376 break; 2377 } 2378 2379 case DW_FORM_flag_present: 2380 *pfMember = true; 2381 break; 2382 2383 default: 2384 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); 2385 } 2386 2387 return VINF_SUCCESS; 2388 } 2389 2390 2391 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2392 static DECLCALLBACK(int) rtDwarfDecode_LowHighPc(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2393 uint32_t uForm, PRTDWARFCURSOR pCursor) 2394 { 2395 AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDRRANGE), VERR_INTERNAL_ERROR_3); 2396 AssertReturn(pDesc->uAttr == DW_AT_low_pc || pDesc->uAttr == DW_AT_high_pc, VERR_INTERNAL_ERROR_3); 2397 2398 uint64_t uAddr; 2399 switch (uForm) 2400 { 2401 case DW_FORM_addr: uAddr = rtDwarfCursor_GetNativeUOff(pCursor, 0); break; 2402 case DW_FORM_data1: uAddr = rtDwarfCursor_GetU8(pCursor, 0); break; 2403 case DW_FORM_data2: uAddr = rtDwarfCursor_GetU16(pCursor, 0); break; 2404 case DW_FORM_data4: uAddr = rtDwarfCursor_GetU32(pCursor, 0); break; 2405 case DW_FORM_data8: uAddr = rtDwarfCursor_GetU64(pCursor, 0); break; 2406 case DW_FORM_udata: uAddr = rtDwarfCursor_GetULeb128(pCursor, 0); break; 2407 default: 2408 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); 2409 } 2410 if (RT_FAILURE(pCursor->rc)) 2411 return pCursor->rc; 2412 2413 PRTDWARFADDRRANGE pRange = (PRTDWARFADDRRANGE)pbMember; 2414 if (pDesc->uAttr == DW_AT_low_pc) 2415 { 2416 pRange->uLowAddress = uAddr; 2417 pRange->fHaveLowAddress = true; 2418 } 2419 else 2420 { 2421 pRange->uHighAddress = uAddr; 2422 pRange->fHaveHighAddress = true; 2423 } 2424 2425 return VINF_SUCCESS; 2426 } 2427 2428 2429 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2430 static DECLCALLBACK(int) rtDwarfDecode_Ranges(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2431 uint32_t uForm, PRTDWARFCURSOR pCursor) 2432 { 2433 AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDRRANGE), VERR_INTERNAL_ERROR_3); 2434 AssertReturn(pDesc->uAttr == DW_AT_low_pc || pDesc->uAttr == DW_AT_high_pc, VERR_INTERNAL_ERROR_3); 2435 2436 /* Decode it. */ 2437 uint64_t off; 2438 switch (uForm) 2439 { 2440 case DW_FORM_addr: off = rtDwarfCursor_GetNativeUOff(pCursor, 0); break; 2441 case DW_FORM_data4: off = rtDwarfCursor_GetU32(pCursor, 0); break; 2442 case DW_FORM_data8: off = rtDwarfCursor_GetU64(pCursor, 0); break; 2443 default: 2444 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); 2445 } 2446 if (RT_FAILURE(pCursor->rc)) 2447 return pCursor->rc; 2448 2449 /* Validate the offset and load the ranges. */ 2450 PRTDBGMODDWARF pThis = pCursor->pDwarfMod; 2451 if (off >= pThis->aSections[krtDbgModDwarfSect_ranges].cb) 2452 return pCursor->rc = VERR_DWARF_BAD_POS; 2453 2454 if (!pThis->aSections[krtDbgModDwarfSect_ranges].pv) 2455 { 2456 int rc = rtDbgModDwarfLoadSection(pThis, krtDbgModDwarfSect_ranges); 2457 if (RT_FAILURE(rc)) 2458 return pCursor->rc = rc; 2459 } 2460 2461 /* Store the result. */ 2462 PRTDWARFADDRRANGE pRange = (PRTDWARFADDRRANGE)pbMember; 2463 pRange->pbRanges = (uint8_t const *)pThis->aSections[krtDbgModDwarfSect_ranges].pv + (size_t)off; 2464 pRange->fHaveRanges = true; 2465 2466 return VINF_SUCCESS; 2467 } 2468 2469 2470 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2471 static DECLCALLBACK(int) rtDwarfDecode_Reference(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2472 uint32_t uForm, PRTDWARFCURSOR pCursor) 2473 { 2474 AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFREF), VERR_INTERNAL_ERROR_3); 2475 2476 /* Decode it. */ 2477 uint64_t off; 2478 krtDwarfRef enmWrt = krtDwarfRef_InfoSection; 2479 switch (uForm) 2480 { 2481 case DW_FORM_ref1: off = rtDwarfCursor_GetU8(pCursor, 0); break; 2482 case DW_FORM_ref2: off = rtDwarfCursor_GetU16(pCursor, 0); break; 2483 case DW_FORM_ref4: off = rtDwarfCursor_GetU32(pCursor, 0); break; 2484 case DW_FORM_ref8: off = rtDwarfCursor_GetU64(pCursor, 0); break; 2485 case DW_FORM_ref_udata: off = rtDwarfCursor_GetULeb128(pCursor, 0); break; 2486 2487 case DW_FORM_ref_addr: 2488 enmWrt = krtDwarfRef_InfoSection; 2489 off = rtDwarfCursor_GetUOff(pCursor, 0); 2490 break; 2491 2492 case DW_FORM_ref_sig8: 2493 enmWrt = krtDwarfRef_TypeId64; 2494 off = rtDwarfCursor_GetU64(pCursor, 0); 2495 break; 2496 2497 default: 2498 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); 2499 } 2500 if (RT_FAILURE(pCursor->rc)) 2501 return pCursor->rc; 2502 2503 /* Validate the offset and convert to debug_info relative offsets. */ 2504 if (enmWrt == krtDwarfRef_InfoSection) 2505 { 2506 if (off >= pCursor->pDwarfMod->aSections[krtDbgModDwarfSect_info].cb) 2507 return pCursor->rc = VERR_DWARF_BAD_POS; 2508 } 2509 else if (enmWrt == krtDwarfRef_SameUnit) 2510 { 2511 PRTDWARFDIECOMPILEUNIT pUnit = rtDwarfDie_GetCompileUnit(pDie); 2512 if (off >= pUnit->cbUnit) 2513 return pCursor->rc = VERR_DWARF_BAD_POS; 2514 off += pUnit->offUnit; 2515 enmWrt = krtDwarfRef_InfoSection; 2516 } 2517 /* else: not bother verifying/resolving the indirect type reference yet. */ 2518 2519 /* Store it */ 2520 PRTDWARFREF pRef = (PRTDWARFREF)pbMember; 2521 pRef->enmWrt = enmWrt; 2522 pRef->off = off; 2523 2524 return VINF_SUCCESS; 2525 } 2526 2527 2528 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2529 static DECLCALLBACK(int) rtDwarfDecode_SectOff(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2530 uint32_t uForm, PRTDWARFCURSOR pCursor) 2531 { 2532 AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFREF), VERR_INTERNAL_ERROR_3); 2533 2534 uint64_t off; 2535 switch (uForm) 2536 { 2537 case DW_FORM_data4: off = rtDwarfCursor_GetU32(pCursor, 0); break; 2538 case DW_FORM_data8: off = rtDwarfCursor_GetU64(pCursor, 0); break; 2539 case DW_FORM_sec_offset: off = rtDwarfCursor_GetUOff(pCursor, 0); break; 2540 default: 2541 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); 2542 } 2543 if (RT_FAILURE(pCursor->rc)) 2544 return pCursor->rc; 2545 2546 krtDbgModDwarfSect enmSect; 2547 krtDwarfRef enmWrt; 2548 switch (pDesc->uAttr) 2549 { 2550 case DW_AT_stmt_list: enmSect = krtDbgModDwarfSect_line; enmWrt = krtDwarfRef_LineSection; break; 2551 case DW_AT_macro_info: enmSect = krtDbgModDwarfSect_loc; enmWrt = krtDwarfRef_LocSection; break; 2552 case DW_AT_ranges: enmSect = krtDbgModDwarfSect_ranges; enmWrt = krtDwarfRef_RangesSection; break; 2553 default: AssertMsgFailedReturn(("%u\n", pDesc->uAttr), VERR_INTERNAL_ERROR_4); 2554 } 2555 if (off > pCursor->pDwarfMod->aSections[enmSect].cb) 2556 return pCursor->rc = VERR_DWARF_BAD_POS; 2557 2558 PRTDWARFREF pRef = (PRTDWARFREF)pbMember; 2559 pRef->enmWrt = enmWrt; 2560 pRef->off = off; 2561 2562 return VINF_SUCCESS; 2563 } 2564 2565 2566 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2567 static DECLCALLBACK(int) rtDwarfDecode_String(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2568 uint32_t uForm, PRTDWARFCURSOR pCursor) 2569 { 2570 AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(const char *), VERR_INTERNAL_ERROR_3); 2571 2572 switch (uForm) 2573 { 2574 case DW_FORM_string: 2575 *(const char **)pbMember = rtDwarfCursor_GetSZ(pCursor, NULL); 2576 break; 2577 2578 case DW_FORM_strp: 2579 *(const char **)pbMember = rtDwarfDecode_GetStrp(pCursor->pDwarfMod, pCursor, NULL); 2580 break; 2581 2582 default: 2583 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); 2584 } 2585 2586 return pCursor->rc; 2587 } 2588 2589 2590 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2591 static DECLCALLBACK(int) rtDwarfDecode_UnsignedInt(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2592 uint32_t uForm, PRTDWARFCURSOR pCursor) 2593 { 2594 uint64_t u64Val; 2595 switch (uForm) 2596 { 2597 case DW_FORM_udata: u64Val = rtDwarfCursor_GetULeb128(pCursor, 0); break; 2598 case DW_FORM_data1: u64Val = rtDwarfCursor_GetU8(pCursor, 0); break; 2599 case DW_FORM_data2: u64Val = rtDwarfCursor_GetU16(pCursor, 0); break; 2600 case DW_FORM_data4: u64Val = rtDwarfCursor_GetU32(pCursor, 0); break; 2601 case DW_FORM_data8: u64Val = rtDwarfCursor_GetU64(pCursor, 0); break; 2602 default: 2603 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); 2604 } 2605 if (RT_FAILURE(pCursor->rc)) 2606 return pCursor->rc; 2607 2608 switch (ATTR_GET_SIZE(pDesc)) 2609 { 2610 case 1: 2611 *pbMember = (uint8_t)u64Val; 2612 if (*pbMember != u64Val) 2613 return VERR_OUT_OF_RANGE; 2614 break; 2615 2616 case 2: 2617 *(uint16_t *)pbMember = (uint16_t)u64Val; 2618 if (*(uint16_t *)pbMember != u64Val) 2619 return VERR_OUT_OF_RANGE; 2620 break; 2621 2622 case 4: 2623 *(uint32_t *)pbMember = (uint32_t)u64Val; 2624 if (*(uint32_t *)pbMember != u64Val) 2625 return VERR_OUT_OF_RANGE; 2626 break; 2627 2628 case 8: 2629 *(uint64_t *)pbMember = (uint64_t)u64Val; 2630 if (*(uint64_t *)pbMember != u64Val) 2631 return VERR_OUT_OF_RANGE; 2632 break; 2633 2634 default: 2635 AssertMsgFailedReturn(("%#x\n", ATTR_GET_SIZE(pDesc)), VERR_INTERNAL_ERROR_2); 2636 } 2637 return VINF_SUCCESS; 2638 } 2639 2640 2641 2642 /* 2643 * 2644 * DWARF debug_info parser 2645 * DWARF debug_info parser 2646 * DWARF debug_info parser 2647 * 2648 */ 2649 2650 2651 2135 2652 static const char *rtDwarfForm_GetString(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, uint16_t uForm, const char *pszErrValue) 2136 2653 { … … 2141 2658 2142 2659 case DW_FORM_strp: 2143 return rtDwarf Form_GetStrp(pThis, pCursor, pszErrValue);2660 return rtDwarfDecode_GetStrp(pThis, pCursor, pszErrValue); 2144 2661 2145 2662 default: … … 2147 2664 return pszErrValue; 2148 2665 } 2666 } 2667 2668 2669 /** 2670 * Creates a new internal DIE structure and links it up. 2671 * 2672 * @returns Pointer to the new DIE structure. 2673 * @param pThis The DWARF instance. 2674 * @param cbUnit The size required for this unit. 2675 * @param pAbbrev The abbreviation cache entry. 2676 * @param pParent The parent DIE (NULL if unit). 2677 */ 2678 static PRTDWARFDIE rtDwarfInfo_NewDie(PRTDBGMODDWARF pThis, size_t cbUnit, PCRTDWARFABBREV pAbbrev, PRTDWARFDIE pParent) 2679 { 2680 Assert(cbUnit >= sizeof(RTDWARFDIE)); 2681 PRTDWARFDIE pDie = (PRTDWARFDIE)RTMemAllocZ(cbUnit); 2682 if (pDie) 2683 { 2684 pDie->uTag = pAbbrev->uTag; 2685 pDie->offSpec = pAbbrev->offSpec; 2686 pDie->pParent = pParent; 2687 if (pParent) 2688 RTListAppend(&pParent->ChildList, &pDie->SiblingNode); 2689 else 2690 RTListInit(&pDie->SiblingNode); 2691 RTListInit(&pDie->ChildList); 2692 } 2693 return pDie; 2149 2694 } 2150 2695 … … 2245 2790 2246 2791 2792 #if 0 2247 2793 /** 2248 2794 * Parse a DIE. … … 2327 2873 return rtDwarfInfo_SkipDie(pCursor, pAbbrevCursor); 2328 2874 } 2875 #endif 2329 2876 2330 2877 … … 2337 2884 * Read the compilation unit header. 2338 2885 */ 2339 rtDwarfCursor_GetInitalLength(pCursor); 2886 uint64_t offUnit = rtDwarfCursor_CalcSectOffsetU32(pCursor); 2887 uint64_t cbUnit = rtDwarfCursor_GetInitalLength(pCursor); 2888 cbUnit += rtDwarfCursor_CalcSectOffsetU32(pCursor) - offUnit; 2340 2889 uint16_t const uVer = rtDwarfCursor_GetUHalf(pCursor, 0); 2341 2890 if ( uVer < 2 … … 2357 2906 2358 2907 /* 2359 * We want a DIE stack as well.2908 * The first DIE is a compile or partial unit, parse it here. 2360 2909 */ 2361 RTDWARFDIESTACK Stack; 2362 rtDwarfDieStack_Init(&Stack); 2910 uint32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX); 2911 if (!uAbbrCode) 2912 return VERR_DWARF_BAD_INFO; 2913 PCRTDWARFABBREV pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode); 2914 if (!pAbbrev) 2915 return VERR_DWARF_ABBREV_NOT_FOUND; 2916 if ( pAbbrev->uTag != DW_TAG_compile_unit 2917 && pAbbrev->uTag != DW_TAG_partial_unit) 2918 { 2919 Log(("Unexpected compile/partial unit tag %#x\n", pAbbrev->uTag)); 2920 return VERR_DWARF_BAD_INFO; 2921 } 2922 2923 PRTDWARFDIECOMPILEUNIT pUnit = (PRTDWARFDIECOMPILEUNIT)rtDwarfInfo_NewDie(pThis, sizeof(*pUnit), pAbbrev, NULL /*pParent*/); 2924 if (!pUnit) 2925 return VERR_NO_MEMORY; 2926 pUnit->offUnit = offUnit; 2927 pUnit->cbUnit = cbUnit; 2928 pUnit->offAbbrev = offAbbrev; 2929 pUnit->cbNativeAddr = cbNativeAddr; 2930 pUnit->uDwarfVer = uVer; 2931 RTListAppend(&pThis->CompileUnitList, &pUnit->Core.SiblingNode); 2932 2933 /** @todo Parse the DIE data using the descriptor. */ 2934 RTDWARFCURSOR AbbrevCursor; 2935 int rc = rtDwarfCursor_InitWithOffset(&AbbrevCursor, pThis, krtDbgModDwarfSect_abbrev, pAbbrev->offSpec); 2936 #if 0 2937 if (RT_SUCCESS(rc)) 2938 { 2939 rc = rtDwarfInfo_ParseDie(pThis, pCursor, pAbbrev, &AbbrevCursor, &Stack); 2940 rc = rtDwarfCursor_Delete(&AbbrevCursor, rc); 2941 } 2942 if (RT_FAILURE(rc)) 2943 break; 2363 2944 2364 2945 /* … … 2415 2996 2416 2997 rtDwarfDieStack_Delete(&Stack); 2998 #endif 2417 2999 return RT_SUCCESS(rc) ? pCursor->rc : rc; 2418 3000 }
Note:
See TracChangeset
for help on using the changeset viewer.