1 //===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "SymbolFileDWARF.h" 11 12 // Other libraries and framework includes 13 #include "clang/AST/ASTConsumer.h" 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/Decl.h" 16 #include "clang/AST/DeclGroup.h" 17 #include "clang/Basic/Builtins.h" 18 #include "clang/Basic/IdentifierTable.h" 19 #include "clang/Basic/LangOptions.h" 20 #include "clang/Basic/SourceManager.h" 21 #include "clang/Basic/TargetInfo.h" 22 #include "clang/Basic/Specifiers.h" 23 24 #include "lldb/Core/Module.h" 25 #include "lldb/Core/PluginManager.h" 26 #include "lldb/Core/RegularExpression.h" 27 #include "lldb/Core/Scalar.h" 28 #include "lldb/Core/Section.h" 29 #include "lldb/Core/Timer.h" 30 #include "lldb/Core/Value.h" 31 32 #include "lldb/Symbol/Block.h" 33 #include "lldb/Symbol/CompileUnit.h" 34 #include "lldb/Symbol/LineTable.h" 35 #include "lldb/Symbol/ObjectFile.h" 36 #include "lldb/Symbol/SymbolVendor.h" 37 #include "lldb/Symbol/VariableList.h" 38 39 #include "DWARFCompileUnit.h" 40 #include "DWARFDebugAbbrev.h" 41 #include "DWARFDebugAranges.h" 42 #include "DWARFDebugInfo.h" 43 #include "DWARFDebugInfoEntry.h" 44 #include "DWARFDebugLine.h" 45 #include "DWARFDebugPubnames.h" 46 #include "DWARFDebugRanges.h" 47 #include "DWARFDIECollection.h" 48 #include "DWARFFormValue.h" 49 #include "DWARFLocationList.h" 50 #include "LogChannelDWARF.h" 51 52 #include <map> 53 54 #define DIE_IS_BEING_PARSED ((void*)1) 55 56 using namespace lldb; 57 using namespace lldb_private; 58 59 60 static const ConstString& 61 GetSectionNameDebugInfo() 62 { 63 static const ConstString g_sect_name("__debug_info"); 64 return g_sect_name; 65 } 66 67 static const ConstString& 68 GetSectionNameDebugAbbrev() 69 { 70 static const ConstString g_sect_name ("__debug_abbrev"); 71 return g_sect_name; 72 } 73 74 static const ConstString& 75 GetSectionNameDebugAranges() 76 { 77 static const ConstString g_sect_name ("__debug_aranges"); 78 return g_sect_name; 79 } 80 81 static const ConstString& 82 GetSectionNameDebugFrame() 83 { 84 static const ConstString g_sect_name ("__debug_frame"); 85 return g_sect_name; 86 } 87 88 static const ConstString& 89 GetSectionNameDebugLine() 90 { 91 static const ConstString g_sect_name ("__debug_line"); 92 return g_sect_name; 93 } 94 95 static const ConstString& 96 GetSectionNameDebugLoc() 97 { 98 static const ConstString g_sect_name ("__debug_loc"); 99 return g_sect_name; 100 } 101 102 static const ConstString& 103 GetSectionNameDebugMacInfo() 104 { 105 static const ConstString g_sect_name ("__debug_macinfo"); 106 return g_sect_name; 107 } 108 109 static const ConstString& 110 GetSectionNameDebugPubNames() 111 { 112 static const ConstString g_sect_name ("__debug_pubnames"); 113 return g_sect_name; 114 } 115 116 static const ConstString& 117 GetSectionNameDebugPubTypes() 118 { 119 static const ConstString g_sect_name ("__debug_pubtypes"); 120 return g_sect_name; 121 } 122 123 static const ConstString& 124 GetSectionNameDebugRanges() 125 { 126 static const ConstString g_sect_name ("__debug_ranges"); 127 return g_sect_name; 128 } 129 130 static const ConstString& 131 GetSectionNameDebugStr() 132 { 133 static const ConstString g_sect_name ("__debug_str"); 134 return g_sect_name; 135 } 136 137 static uint32_t 138 DwarfToClangAccessibility (uint32_t dwarf_accessibility) 139 { 140 switch (dwarf_accessibility) 141 { 142 case DW_ACCESS_public: 143 return clang::AS_public; 144 case DW_ACCESS_private: 145 return clang::AS_private; 146 case DW_ACCESS_protected: 147 return clang::AS_protected; 148 default: 149 return clang::AS_none; 150 } 151 } 152 153 void 154 SymbolFileDWARF::Initialize() 155 { 156 LogChannelDWARF::Initialize(); 157 PluginManager::RegisterPlugin (GetPluginNameStatic(), 158 GetPluginDescriptionStatic(), 159 CreateInstance); 160 } 161 162 void 163 SymbolFileDWARF::Terminate() 164 { 165 PluginManager::UnregisterPlugin (CreateInstance); 166 LogChannelDWARF::Initialize(); 167 } 168 169 170 const char * 171 SymbolFileDWARF::GetPluginNameStatic() 172 { 173 return "symbol-file.dwarf2"; 174 } 175 176 const char * 177 SymbolFileDWARF::GetPluginDescriptionStatic() 178 { 179 return "DWARF and DWARF3 debug symbol file reader."; 180 } 181 182 183 SymbolFile* 184 SymbolFileDWARF::CreateInstance (ObjectFile* obj_file) 185 { 186 return new SymbolFileDWARF(obj_file); 187 } 188 189 //---------------------------------------------------------------------- 190 // Gets the first parent that is a lexical block, function or inlined 191 // subroutine, or compile unit. 192 //---------------------------------------------------------------------- 193 static const DWARFDebugInfoEntry * 194 GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die) 195 { 196 const DWARFDebugInfoEntry *die; 197 for (die = child_die->GetParent(); die != NULL; die = die->GetParent()) 198 { 199 dw_tag_t tag = die->Tag(); 200 201 switch (tag) 202 { 203 case DW_TAG_compile_unit: 204 case DW_TAG_subprogram: 205 case DW_TAG_inlined_subroutine: 206 case DW_TAG_lexical_block: 207 return die; 208 } 209 } 210 return NULL; 211 } 212 213 214 SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) : 215 SymbolFile(ofile), 216 m_flags(), 217 m_data_debug_abbrev(), 218 m_data_debug_aranges(), 219 m_data_debug_frame(), 220 m_data_debug_info(), 221 m_data_debug_line(), 222 m_data_debug_loc(), 223 m_data_debug_macinfo(), 224 m_data_debug_pubnames(), 225 m_data_debug_pubtypes(), 226 m_data_debug_ranges(), 227 m_data_debug_str(), 228 m_abbr(), 229 m_aranges(), 230 m_info(), 231 m_line(), 232 m_base_name_to_function_die(), 233 m_full_name_to_function_die(), 234 m_method_name_to_function_die(), 235 m_selector_name_to_function_die(), 236 m_name_to_global_die(), 237 m_name_to_type_die(), 238 m_indexed(false), 239 // m_pubnames(), 240 // m_pubtypes(), 241 // m_pubbasetypes(), 242 m_ranges()//, 243 // m_type_fixups(), 244 // m_indirect_fixups() 245 { 246 } 247 248 SymbolFileDWARF::~SymbolFileDWARF() 249 { 250 } 251 252 bool 253 SymbolFileDWARF::SupportedVersion(uint16_t version) 254 { 255 return version == 2 || version == 3; 256 } 257 258 uint32_t 259 SymbolFileDWARF::GetAbilities () 260 { 261 uint32_t abilities = 0; 262 if (m_obj_file != NULL) 263 { 264 const Section* section = NULL; 265 const SectionList *section_list = m_obj_file->GetSectionList(); 266 if (section_list == NULL) 267 return 0; 268 269 uint64_t debug_abbrev_file_size = 0; 270 uint64_t debug_aranges_file_size = 0; 271 uint64_t debug_frame_file_size = 0; 272 uint64_t debug_info_file_size = 0; 273 uint64_t debug_line_file_size = 0; 274 uint64_t debug_loc_file_size = 0; 275 uint64_t debug_macinfo_file_size = 0; 276 uint64_t debug_pubnames_file_size = 0; 277 uint64_t debug_pubtypes_file_size = 0; 278 uint64_t debug_ranges_file_size = 0; 279 uint64_t debug_str_file_size = 0; 280 281 static ConstString g_dwarf_section_name ("__DWARF"); 282 283 section = section_list->FindSectionByName(g_dwarf_section_name).get(); 284 285 if (section) 286 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data); 287 288 section = section_list->FindSectionByName (GetSectionNameDebugInfo()).get(); 289 if (section != NULL) 290 { 291 debug_info_file_size = section->GetByteSize(); 292 293 section = section_list->FindSectionByName (GetSectionNameDebugAbbrev()).get(); 294 if (section) 295 debug_abbrev_file_size = section->GetByteSize(); 296 else 297 m_flags.Set (flagsGotDebugAbbrevData); 298 299 section = section_list->FindSectionByName (GetSectionNameDebugAranges()).get(); 300 if (section) 301 debug_aranges_file_size = section->GetByteSize(); 302 else 303 m_flags.Set (flagsGotDebugArangesData); 304 305 section = section_list->FindSectionByName (GetSectionNameDebugFrame()).get(); 306 if (section) 307 debug_frame_file_size = section->GetByteSize(); 308 else 309 m_flags.Set (flagsGotDebugFrameData); 310 311 section = section_list->FindSectionByName (GetSectionNameDebugLine()).get(); 312 if (section) 313 debug_line_file_size = section->GetByteSize(); 314 else 315 m_flags.Set (flagsGotDebugLineData); 316 317 section = section_list->FindSectionByName (GetSectionNameDebugLoc()).get(); 318 if (section) 319 debug_loc_file_size = section->GetByteSize(); 320 else 321 m_flags.Set (flagsGotDebugLocData); 322 323 section = section_list->FindSectionByName (GetSectionNameDebugMacInfo()).get(); 324 if (section) 325 debug_macinfo_file_size = section->GetByteSize(); 326 else 327 m_flags.Set (flagsGotDebugMacInfoData); 328 329 section = section_list->FindSectionByName (GetSectionNameDebugPubNames()).get(); 330 if (section) 331 debug_pubnames_file_size = section->GetByteSize(); 332 else 333 m_flags.Set (flagsGotDebugPubNamesData); 334 335 section = section_list->FindSectionByName (GetSectionNameDebugPubTypes()).get(); 336 if (section) 337 debug_pubtypes_file_size = section->GetByteSize(); 338 else 339 m_flags.Set (flagsGotDebugPubTypesData); 340 341 section = section_list->FindSectionByName (GetSectionNameDebugRanges()).get(); 342 if (section) 343 debug_ranges_file_size = section->GetByteSize(); 344 else 345 m_flags.Set (flagsGotDebugRangesData); 346 347 section = section_list->FindSectionByName (GetSectionNameDebugStr()).get(); 348 if (section) 349 debug_str_file_size = section->GetByteSize(); 350 else 351 m_flags.Set (flagsGotDebugStrData); 352 } 353 354 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) 355 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes; 356 357 if (debug_line_file_size > 0) 358 abilities |= LineTables; 359 360 if (debug_aranges_file_size > 0) 361 abilities |= AddressAcceleratorTable; 362 363 if (debug_pubnames_file_size > 0) 364 abilities |= FunctionAcceleratorTable; 365 366 if (debug_pubtypes_file_size > 0) 367 abilities |= TypeAcceleratorTable; 368 369 if (debug_macinfo_file_size > 0) 370 abilities |= MacroInformation; 371 372 if (debug_frame_file_size > 0) 373 abilities |= CallFrameInformation; 374 } 375 return abilities; 376 } 377 378 const DataExtractor& 379 SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, const ConstString §ion_name, DataExtractor &data) 380 { 381 if (m_flags.IsClear (got_flag)) 382 { 383 m_flags.Set (got_flag); 384 const SectionList *section_list = m_obj_file->GetSectionList(); 385 if (section_list) 386 { 387 Section *section = section_list->FindSectionByName (section_name).get(); 388 if (section ) 389 { 390 // See if we memory mapped the DWARF segment? 391 if (m_dwarf_data.GetByteSize()) 392 { 393 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize()); 394 } 395 else 396 { 397 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0) 398 data.Clear(); 399 } 400 } 401 } 402 } 403 return data; 404 } 405 406 const DataExtractor& 407 SymbolFileDWARF::get_debug_abbrev_data() 408 { 409 return GetCachedSectionData (flagsGotDebugAbbrevData, GetSectionNameDebugAbbrev(), m_data_debug_abbrev); 410 } 411 412 const DataExtractor& 413 SymbolFileDWARF::get_debug_aranges_data() 414 { 415 return GetCachedSectionData (flagsGotDebugArangesData, GetSectionNameDebugAranges(), m_data_debug_aranges); 416 } 417 418 const DataExtractor& 419 SymbolFileDWARF::get_debug_frame_data() 420 { 421 return GetCachedSectionData (flagsGotDebugFrameData, GetSectionNameDebugFrame(), m_data_debug_frame); 422 } 423 424 const DataExtractor& 425 SymbolFileDWARF::get_debug_info_data() 426 { 427 return GetCachedSectionData (flagsGotDebugInfoData, GetSectionNameDebugInfo(), m_data_debug_info); 428 } 429 430 const DataExtractor& 431 SymbolFileDWARF::get_debug_line_data() 432 { 433 return GetCachedSectionData (flagsGotDebugLineData, GetSectionNameDebugLine(), m_data_debug_line); 434 } 435 436 const DataExtractor& 437 SymbolFileDWARF::get_debug_loc_data() 438 { 439 return GetCachedSectionData (flagsGotDebugLocData, GetSectionNameDebugLoc(), m_data_debug_loc); 440 } 441 442 const DataExtractor& 443 SymbolFileDWARF::get_debug_macinfo_data() 444 { 445 return GetCachedSectionData (flagsGotDebugMacInfoData, GetSectionNameDebugMacInfo(), m_data_debug_macinfo); 446 } 447 448 const DataExtractor& 449 SymbolFileDWARF::get_debug_pubnames_data() 450 { 451 return GetCachedSectionData (flagsGotDebugPubNamesData, GetSectionNameDebugPubNames(), m_data_debug_pubnames); 452 } 453 454 const DataExtractor& 455 SymbolFileDWARF::get_debug_pubtypes_data() 456 { 457 return GetCachedSectionData (flagsGotDebugPubTypesData, GetSectionNameDebugPubTypes(), m_data_debug_pubtypes); 458 } 459 460 const DataExtractor& 461 SymbolFileDWARF::get_debug_ranges_data() 462 { 463 return GetCachedSectionData (flagsGotDebugRangesData, GetSectionNameDebugRanges(), m_data_debug_ranges); 464 } 465 466 const DataExtractor& 467 SymbolFileDWARF::get_debug_str_data() 468 { 469 return GetCachedSectionData (flagsGotDebugStrData, GetSectionNameDebugStr(), m_data_debug_str); 470 } 471 472 473 DWARFDebugAbbrev* 474 SymbolFileDWARF::DebugAbbrev() 475 { 476 if (m_abbr.get() == NULL) 477 { 478 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data(); 479 if (debug_abbrev_data.GetByteSize() > 0) 480 { 481 m_abbr.reset(new DWARFDebugAbbrev()); 482 if (m_abbr.get()) 483 m_abbr->Parse(debug_abbrev_data); 484 } 485 } 486 return m_abbr.get(); 487 } 488 489 const DWARFDebugAbbrev* 490 SymbolFileDWARF::DebugAbbrev() const 491 { 492 return m_abbr.get(); 493 } 494 495 DWARFDebugAranges* 496 SymbolFileDWARF::DebugAranges() 497 { 498 if (m_aranges.get() == NULL) 499 { 500 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 501 m_aranges.reset(new DWARFDebugAranges()); 502 if (m_aranges.get()) 503 { 504 const DataExtractor &debug_aranges_data = get_debug_aranges_data(); 505 if (debug_aranges_data.GetByteSize() > 0) 506 m_aranges->Extract(debug_aranges_data); 507 else 508 m_aranges->Generate(this); 509 } 510 } 511 return m_aranges.get(); 512 } 513 514 const DWARFDebugAranges* 515 SymbolFileDWARF::DebugAranges() const 516 { 517 return m_aranges.get(); 518 } 519 520 521 DWARFDebugInfo* 522 SymbolFileDWARF::DebugInfo() 523 { 524 if (m_info.get() == NULL) 525 { 526 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 527 if (get_debug_info_data().GetByteSize() > 0) 528 { 529 m_info.reset(new DWARFDebugInfo()); 530 if (m_info.get()) 531 { 532 m_info->SetDwarfData(this); 533 } 534 } 535 } 536 return m_info.get(); 537 } 538 539 const DWARFDebugInfo* 540 SymbolFileDWARF::DebugInfo() const 541 { 542 return m_info.get(); 543 } 544 545 //DWARFDebugLine* 546 //SymbolFileDWARF::DebugLine() 547 //{ 548 // if (m_line.get() == NULL) 549 // { 550 // Timer scoped_timer(__PRETTY_FUNCTION__); 551 // const DataExtractor &debug_line_data = debug_line(); 552 // if (debug_line_data.GetByteSize() > 0) 553 // { 554 // m_line.reset(new DWARFDebugLine()); 555 // if (m_line.get()) 556 // m_line->Parse(debug_line_data); 557 // } 558 // } 559 // return m_line.get(); 560 //} 561 // 562 //const DWARFDebugLine* 563 //SymbolFileDWARF::DebugLine() const 564 //{ 565 // return m_line.get(); 566 //} 567 568 569 DWARFCompileUnit* 570 SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid) 571 { 572 DWARFDebugInfo* info = DebugInfo(); 573 if (info) 574 return info->GetCompileUnit(cu_uid).get(); 575 return NULL; 576 } 577 578 //DWARFCompileUnit* 579 //SymbolFileDWARF::GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu) 580 //{ 581 // DWARFCompileUnit* cu = NULL; 582 // DWARFDebugInfo* info = DebugInfo(); 583 // if (info) 584 // { 585 // uint32_t cu_idx = 0; 586 // if (prev_cu != NULL) 587 // { 588 // // Find the index of the previus DWARF compile unit if one was provided 589 // while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL) 590 // { 591 // ++cu_idx; 592 // if (cu == prev_cu) 593 // break; 594 // } 595 // } 596 // 597 // // Now find the next unparsed DWARF compile unit. We do this by checking the 598 // // user data in the DWARFCompileUnit class that starts as NULL, and eventually 599 // // holds a pointer to the CompileUnit that was created for it after it has 600 // // been parsed. 601 // while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL) 602 // { 603 // if (cu->GetUserData() == NULL) 604 // break; 605 // } 606 // } 607 // return cu; 608 //} 609 610 DWARFDebugRanges* 611 SymbolFileDWARF::DebugRanges() 612 { 613 if (m_ranges.get() == NULL) 614 { 615 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 616 if (get_debug_ranges_data().GetByteSize() > 0) 617 { 618 m_ranges.reset(new DWARFDebugRanges()); 619 if (m_ranges.get()) 620 m_ranges->Extract(this); 621 } 622 } 623 return m_ranges.get(); 624 } 625 626 const DWARFDebugRanges* 627 SymbolFileDWARF::DebugRanges() const 628 { 629 return m_ranges.get(); 630 } 631 // 632 //DWARFDebugPubnames* 633 //SymbolFileDWARF::DebugPubnames() 634 //{ 635 // if (m_pubnames.get() == NULL) 636 // { 637 // Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 638 // const DataExtractor &debug_pubnames_data = get_debug_pubnames_data(); 639 // if (debug_pubnames_data.GetByteSize() > 0) 640 // { 641 // // Pass false to indicate this is a pubnames section 642 // m_pubnames.reset(new DWARFDebugPubnames()); 643 // if (m_pubnames.get()) 644 // { 645 // // "m_pubnames->GeneratePubnames" is costly, but needed for global variables 646 // m_pubnames->GeneratePubnames(this); 647 // 648 //#if 0 649 // StreamFile s(stdout); 650 // s.Printf (".debug_pubnames for %s/%s:\n", 651 // m_obj_file->GetModule()->GetFileSpec().GetDirectory().AsCString(), 652 // m_obj_file->GetModule()->GetFileSpec().GetFilename().AsCString()); 653 // m_pubnames->Dump (&s); 654 //#endif 655 // // "m_pubnames->Extract" is quicker, but the pubnames don't always contain what we need. 656 // //m_pubnames->Extract(debug_pubnames_data); 657 // } 658 // } 659 // } 660 // return m_pubnames.get(); 661 //} 662 // 663 //const DWARFDebugPubnames* 664 //SymbolFileDWARF::DebugPubnames() const 665 //{ 666 // return m_pubnames.get(); 667 //} 668 669 //DWARFDebugPubnames* 670 //SymbolFileDWARF::DebugPubBaseTypes() 671 //{ 672 // if (m_pubbasetypes.get() == NULL) 673 // { 674 // Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 675 // // Pass false to indicate this is a pubnames section 676 // m_pubbasetypes.reset(new DWARFDebugPubnames()); 677 // if (m_pubbasetypes.get()) 678 // m_pubbasetypes->GeneratePubBaseTypes(this); 679 // } 680 // return m_pubbasetypes.get(); 681 //} 682 // 683 //const DWARFDebugPubnames* 684 //SymbolFileDWARF::DebugPubBaseTypes() const 685 //{ 686 // return m_pubbasetypes.get(); 687 //} 688 // 689 //const DWARFDebugPubnames* 690 //SymbolFileDWARF::DebugPubtypes() const 691 //{ 692 // return m_pubtypes.get(); 693 //} 694 // 695 //DWARFDebugPubnames* 696 //SymbolFileDWARF::DebugPubtypes() 697 //{ 698 // if (m_pubtypes.get() == NULL) 699 // { 700 // Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 701 // const DataExtractor &debug_pubtypes_data = get_debug_pubtypes_data(); 702 // if (debug_pubtypes_data.GetByteSize() > 0) 703 // { 704 // // Pass false to indicate this is a pubnames section 705 // m_pubtypes.reset(new DWARFDebugPubnames()); 706 // if (m_pubtypes.get()) 707 // m_pubtypes->Extract(debug_pubtypes_data); 708 // } 709 // } 710 // return m_pubtypes.get(); 711 //} 712 // 713 714 bool 715 SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp) 716 { 717 if (cu != NULL) 718 { 719 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly (); 720 if (cu_die) 721 { 722 const char * cu_die_name = cu_die->GetName(this, cu); 723 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL); 724 Language::Type language = (Language::Type)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0); 725 if (cu_die_name) 726 { 727 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0]) 728 { 729 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), language)); 730 } 731 else 732 { 733 std::string fullpath(cu_comp_dir); 734 if (*fullpath.rbegin() != '/') 735 fullpath += '/'; 736 fullpath += cu_die_name; 737 738 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), language)); 739 } 740 741 if (compile_unit_sp.get()) 742 { 743 cu->SetUserData(compile_unit_sp.get()); 744 return true; 745 } 746 } 747 } 748 } 749 return false; 750 } 751 752 #if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST 753 754 void 755 SymbolFileDWARF::ShrinkDSYM(CompileUnit *dc_cu, DWARFCompileUnit *dw_cu, const FileSpec& cu_fspec, const FileSpec& base_types_fspec, FSToDIES& fs_to_dies, const DWARFDebugInfoEntry *die) 756 { 757 while (die != NULL) 758 { 759 dw_tag_t tag = die->Tag(); 760 761 switch (tag) 762 { 763 case DW_TAG_base_type: 764 // Put all base types into the base type compile unit 765 fs_to_dies[base_types_fspec].Insert(die); 766 break; 767 768 default: 769 { 770 uint32_t decl_file = die->GetAttributeValueAsUnsigned(this, dw_cu, DW_AT_decl_file, 0); 771 if (decl_file) 772 { 773 fs_to_dies[dc_cu->GetSupportFiles().GetFileSpecAtIndex(decl_file)].Insert(die); 774 } 775 else 776 { 777 // add this to the current compile unit 778 fs_to_dies[cu_fspec].Insert(die); 779 } 780 } 781 break; 782 } 783 784 die = die->GetSibling(); 785 } 786 } 787 788 789 790 #endif 791 792 uint32_t 793 SymbolFileDWARF::GetNumCompileUnits() 794 { 795 DWARFDebugInfo* info = DebugInfo(); 796 if (info) 797 { 798 #if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST 799 uint32_t cu_idx; 800 FSToDIES fs_to_dies; 801 802 FileSpec base_type_fspec("DW_TAG_base_type"); 803 const uint32_t num_comp_units = info->GetNumCompileUnits(); 804 805 for (cu_idx=0; cu_idx < num_comp_units; ++cu_idx) 806 { 807 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx); 808 if (cu != NULL) 809 { 810 const DWARFDebugInfoEntry *cu_die = cu->DIE(); 811 if (cu_die) 812 { 813 CompUnitSP dc_cu_sp; 814 ParseCompileUnit(cu, dc_cu_sp); 815 if (dc_cu_sp.get()) 816 { 817 FileSpec cu_fspec(*dc_cu_sp.get()); 818 819 ShrinkDSYM(dc_cu_sp.get(), cu, cu_fspec, base_type_fspec, fs_to_dies, cu->DIE()->GetFirstChild()); 820 } 821 } 822 } 823 } 824 825 Stream strm(stdout); 826 FSToDIES::const_iterator pos, end = fs_to_dies.end(); 827 for (pos = fs_to_dies.begin(); pos != end; ++pos) 828 { 829 strm << "\n\nMinimal Compile Unit: " << pos->first << ":\n"; 830 const DWARFDIECollection& dies = pos->second; 831 dies.Dump(strm, NULL); 832 } 833 return num_comp_units; 834 #else 835 return info->GetNumCompileUnits(); 836 #endif 837 } 838 return 0; 839 } 840 841 CompUnitSP 842 SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) 843 { 844 CompUnitSP comp_unit; 845 DWARFDebugInfo* info = DebugInfo(); 846 if (info) 847 { 848 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx); 849 if (cu != NULL) 850 { 851 // Our symbol vendor shouldn't be asking us to add a compile unit that 852 // has already been added to it, which this DWARF plug-in knows as it 853 // stores the lldb compile unit (CompileUnit) pointer in each 854 // DWARFCompileUnit object when it gets added. 855 assert(cu->GetUserData() == NULL); 856 ParseCompileUnit(cu, comp_unit); 857 } 858 } 859 return comp_unit; 860 } 861 862 static void 863 AddRangesToBlock 864 ( 865 BlockList& blocks, 866 lldb::user_id_t blockID, 867 DWARFDebugRanges::RangeList& ranges, 868 addr_t block_base_addr 869 ) 870 { 871 ranges.SubtractOffset (block_base_addr); 872 size_t range_idx = 0; 873 const DWARFDebugRanges::Range *debug_range; 874 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++) 875 { 876 blocks.AddRange(blockID, debug_range->begin_offset, debug_range->end_offset); 877 } 878 } 879 880 881 Function * 882 SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die) 883 { 884 DWARFDebugRanges::RangeList func_ranges; 885 const char *name = NULL; 886 const char *mangled = NULL; 887 int decl_file = 0; 888 int decl_line = 0; 889 int decl_column = 0; 890 int call_file = 0; 891 int call_line = 0; 892 int call_column = 0; 893 DWARFExpression frame_base; 894 895 // Parse the function prototype as a type that can then be added to concrete function instance 896 ParseTypes (sc, dwarf_cu, die, false, false); 897 //FixupTypes(); 898 899 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base)) 900 { 901 // Union of all ranges in the function DIE (if the function is discontiguous) 902 AddressRange func_range; 903 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0); 904 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0); 905 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr) 906 { 907 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList()); 908 if (func_range.GetBaseAddress().IsValid()) 909 func_range.SetByteSize(highest_func_addr - lowest_func_addr); 910 } 911 912 if (func_range.GetBaseAddress().IsValid()) 913 { 914 Mangled func_name; 915 if (mangled) 916 func_name.SetValue(mangled, true); 917 else if (name) 918 func_name.SetValue(name, false); 919 920 FunctionSP func_sp; 921 std::auto_ptr<Declaration> decl_ap; 922 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 923 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); 924 925 Type *func_type = NULL; 926 927 if (die->GetUserData() != DIE_IS_BEING_PARSED) 928 func_type = (Type*)die->GetUserData(); 929 930 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); 931 932 func_range.GetBaseAddress().ResolveLinkedAddress(); 933 934 func_sp.reset(new Function (sc.comp_unit, 935 die->GetOffset(), // UserID is the DIE offset 936 die->GetOffset(), 937 func_name, 938 func_type, 939 func_range)); // first address range 940 941 if (func_sp.get() != NULL) 942 { 943 func_sp->GetFrameBaseExpression() = frame_base; 944 sc.comp_unit->AddFunction(func_sp); 945 return func_sp.get(); 946 } 947 } 948 } 949 return NULL; 950 } 951 952 size_t 953 SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) 954 { 955 assert (sc.comp_unit); 956 size_t functions_added = 0; 957 const DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 958 if (dwarf_cu) 959 { 960 DWARFDIECollection function_dies; 961 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies); 962 size_t func_idx; 963 for (func_idx = 0; func_idx < num_funtions; ++func_idx) 964 { 965 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx); 966 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL) 967 { 968 if (ParseCompileUnitFunction(sc, dwarf_cu, die)) 969 ++functions_added; 970 } 971 } 972 //FixupTypes(); 973 } 974 return functions_added; 975 } 976 977 bool 978 SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) 979 { 980 assert (sc.comp_unit); 981 DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 982 assert (cu); 983 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly(); 984 985 if (cu_die) 986 { 987 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL); 988 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 989 990 // All file indexes in DWARF are one based and a file of index zero is 991 // supposed to be the compile unit itself. 992 support_files.Append (*sc.comp_unit); 993 994 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files); 995 } 996 return false; 997 } 998 999 struct ParseDWARFLineTableCallbackInfo 1000 { 1001 LineTable* line_table; 1002 const SectionList *section_list; 1003 lldb::addr_t prev_sect_file_base_addr; 1004 lldb::addr_t curr_sect_file_base_addr; 1005 bool is_oso_for_debug_map; 1006 bool prev_in_final_executable; 1007 DWARFDebugLine::Row prev_row; 1008 SectionSP prev_section_sp; 1009 SectionSP curr_section_sp; 1010 }; 1011 1012 //---------------------------------------------------------------------- 1013 // ParseStatementTableCallback 1014 //---------------------------------------------------------------------- 1015 static void 1016 ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) 1017 { 1018 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table; 1019 if (state.row == DWARFDebugLine::State::StartParsingLineTable) 1020 { 1021 // Just started parsing the line table 1022 } 1023 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) 1024 { 1025 // Done parsing line table, nothing to do for the cleanup 1026 } 1027 else 1028 { 1029 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData; 1030 // We have a new row, lets append it 1031 1032 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false) 1033 { 1034 info->prev_section_sp = info->curr_section_sp; 1035 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr; 1036 // If this is an end sequence entry, then we subtract one from the 1037 // address to make sure we get an address that is not the end of 1038 // a section. 1039 if (state.end_sequence && state.address != 0) 1040 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1); 1041 else 1042 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address); 1043 1044 if (info->curr_section_sp.get()) 1045 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress (); 1046 else 1047 info->curr_sect_file_base_addr = 0; 1048 } 1049 if (info->curr_section_sp.get()) 1050 { 1051 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr; 1052 // Check for the fancy section magic to determine if we 1053 1054 if (info->is_oso_for_debug_map) 1055 { 1056 // When this is a debug map object file that contains DWARF 1057 // (referenced from an N_OSO debug map nlist entry) we will have 1058 // a file address in the file range for our section from the 1059 // original .o file, and a load address in the executable that 1060 // contains the debug map. 1061 // 1062 // If the sections for the file range and load range are 1063 // different, we have a remapped section for the function and 1064 // this address is resolved. If they are the same, then the 1065 // function for this address didn't make it into the final 1066 // executable. 1067 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL; 1068 1069 // If we are doing DWARF with debug map, then we need to carefully 1070 // add each line table entry as there may be gaps as functions 1071 // get moved around or removed. 1072 if (!info->prev_row.end_sequence && info->prev_section_sp.get()) 1073 { 1074 if (info->prev_in_final_executable) 1075 { 1076 bool terminate_previous_entry = false; 1077 if (!curr_in_final_executable) 1078 { 1079 // Check for the case where the previous line entry 1080 // in a function made it into the final executable, 1081 // yet the current line entry falls in a function 1082 // that didn't. The line table used to be contiguous 1083 // through this address range but now it isn't. We 1084 // need to terminate the previous line entry so 1085 // that we can reconstruct the line range correctly 1086 // for it and to keep the line table correct. 1087 terminate_previous_entry = true; 1088 } 1089 else if (info->curr_section_sp.get() != info->prev_section_sp.get()) 1090 { 1091 // Check for cases where the line entries used to be 1092 // contiguous address ranges, but now they aren't. 1093 // This can happen when order files specify the 1094 // ordering of the functions. 1095 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr; 1096 Section *curr_sect = info->curr_section_sp.get(); 1097 Section *prev_sect = info->prev_section_sp.get(); 1098 assert (curr_sect->GetLinkedSection()); 1099 assert (prev_sect->GetLinkedSection()); 1100 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address; 1101 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset; 1102 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset; 1103 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr; 1104 if (object_file_addr_delta != linked_file_addr_delta) 1105 terminate_previous_entry = true; 1106 } 1107 1108 if (terminate_previous_entry) 1109 { 1110 line_table->InsertLineEntry (info->prev_section_sp, 1111 state.address - info->prev_sect_file_base_addr, 1112 info->prev_row.line, 1113 info->prev_row.column, 1114 info->prev_row.file, 1115 false, // is_stmt 1116 false, // basic_block 1117 false, // state.prologue_end 1118 false, // state.epilogue_begin 1119 true); // end_sequence); 1120 } 1121 } 1122 } 1123 1124 if (curr_in_final_executable) 1125 { 1126 line_table->InsertLineEntry (info->curr_section_sp, 1127 curr_line_section_offset, 1128 state.line, 1129 state.column, 1130 state.file, 1131 state.is_stmt, 1132 state.basic_block, 1133 state.prologue_end, 1134 state.epilogue_begin, 1135 state.end_sequence); 1136 info->prev_section_sp = info->curr_section_sp; 1137 } 1138 else 1139 { 1140 // If the current address didn't make it into the final 1141 // executable, the current section will be the __text 1142 // segment in the .o file, so we need to clear this so 1143 // we can catch the next function that did make it into 1144 // the final executable. 1145 info->prev_section_sp.reset(); 1146 info->curr_section_sp.reset(); 1147 } 1148 1149 info->prev_in_final_executable = curr_in_final_executable; 1150 } 1151 else 1152 { 1153 // We are not in an object file that contains DWARF for an 1154 // N_OSO, this is just a normal DWARF file. The DWARF spec 1155 // guarantees that the addresses will be in increasing order 1156 // so, since we store line tables in file address order, we 1157 // can always just append the line entry without needing to 1158 // search for the correct insertion point (we don't need to 1159 // use LineEntry::InsertLineEntry()). 1160 line_table->AppendLineEntry (info->curr_section_sp, 1161 curr_line_section_offset, 1162 state.line, 1163 state.column, 1164 state.file, 1165 state.is_stmt, 1166 state.basic_block, 1167 state.prologue_end, 1168 state.epilogue_begin, 1169 state.end_sequence); 1170 } 1171 } 1172 1173 info->prev_row = state; 1174 } 1175 } 1176 1177 bool 1178 SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc) 1179 { 1180 assert (sc.comp_unit); 1181 if (sc.comp_unit->GetLineTable() != NULL) 1182 return true; 1183 1184 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 1185 if (dwarf_cu) 1186 { 1187 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); 1188 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 1189 if (cu_line_offset != DW_INVALID_OFFSET) 1190 { 1191 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit)); 1192 if (line_table_ap.get()) 1193 { 1194 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_flags.IsSet (flagsDWARFIsOSOForDebugMap), false}; 1195 uint32_t offset = cu_line_offset; 1196 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info); 1197 sc.comp_unit->SetLineTable(line_table_ap.release()); 1198 return true; 1199 } 1200 } 1201 } 1202 return false; 1203 } 1204 1205 size_t 1206 SymbolFileDWARF::ParseFunctionBlocks 1207 ( 1208 const SymbolContext& sc, 1209 lldb::user_id_t parentBlockID, 1210 const DWARFCompileUnit* dwarf_cu, 1211 const DWARFDebugInfoEntry *die, 1212 addr_t subprogram_low_pc, 1213 bool parse_siblings, 1214 bool parse_children 1215 ) 1216 { 1217 size_t blocks_added = 0; 1218 while (die != NULL) 1219 { 1220 dw_tag_t tag = die->Tag(); 1221 1222 switch (tag) 1223 { 1224 case DW_TAG_subprogram: 1225 case DW_TAG_inlined_subroutine: 1226 case DW_TAG_lexical_block: 1227 { 1228 DWARFDebugRanges::RangeList ranges; 1229 const char *name = NULL; 1230 const char *mangled_name = NULL; 1231 BlockList& blocks = sc.function->GetBlocks(false); 1232 1233 lldb::user_id_t blockID = blocks.AddChild(parentBlockID, die->GetOffset()); 1234 int decl_file = 0; 1235 int decl_line = 0; 1236 int decl_column = 0; 1237 int call_file = 0; 1238 int call_line = 0; 1239 int call_column = 0; 1240 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column)) 1241 { 1242 if (tag == DW_TAG_subprogram) 1243 { 1244 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); 1245 subprogram_low_pc = ranges.LowestAddress(0); 1246 } 1247 1248 AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc); 1249 1250 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) 1251 { 1252 std::auto_ptr<Declaration> decl_ap; 1253 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 1254 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); 1255 1256 std::auto_ptr<Declaration> call_ap; 1257 if (call_file != 0 || call_line != 0 || call_column != 0) 1258 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column)); 1259 1260 blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get()); 1261 } 1262 1263 ++blocks_added; 1264 1265 if (parse_children && die->HasChildren()) 1266 { 1267 blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true); 1268 } 1269 } 1270 } 1271 break; 1272 default: 1273 break; 1274 } 1275 1276 if (parse_siblings) 1277 die = die->GetSibling(); 1278 else 1279 die = NULL; 1280 } 1281 return blocks_added; 1282 } 1283 1284 size_t 1285 SymbolFileDWARF::ParseChildMembers 1286 ( 1287 const SymbolContext& sc, 1288 TypeSP& type_sp, 1289 const DWARFCompileUnit* dwarf_cu, 1290 const DWARFDebugInfoEntry *parent_die, 1291 std::vector<clang::CXXBaseSpecifier *>& base_classes, 1292 std::vector<int>& member_accessibilities, 1293 int& default_accessibility, 1294 bool &is_a_class 1295 ) 1296 { 1297 if (parent_die == NULL) 1298 return 0; 1299 1300 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 1301 1302 size_t count = 0; 1303 const DWARFDebugInfoEntry *die; 1304 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 1305 { 1306 dw_tag_t tag = die->Tag(); 1307 1308 switch (tag) 1309 { 1310 case DW_TAG_member: 1311 { 1312 DWARFDebugInfoEntry::Attributes attributes; 1313 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 1314 if (num_attributes > 0) 1315 { 1316 Declaration decl; 1317 DWARFExpression location; 1318 const char *name = NULL; 1319 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1320 uint32_t accessibility = clang::AS_none; 1321 off_t member_offset = 0; 1322 size_t byte_size = 0; 1323 size_t bit_offset = 0; 1324 size_t bit_size = 0; 1325 uint32_t i; 1326 for (i=0; i<num_attributes; ++i) 1327 { 1328 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1329 DWARFFormValue form_value; 1330 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1331 { 1332 switch (attr) 1333 { 1334 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1335 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1336 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1337 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 1338 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1339 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break; 1340 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break; 1341 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 1342 case DW_AT_data_member_location: 1343 if (form_value.BlockData()) 1344 { 1345 Value initialValue(0); 1346 Value memberOffset(0); 1347 const DataExtractor& debug_info_data = get_debug_info_data(); 1348 uint32_t block_length = form_value.Unsigned(); 1349 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1350 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL)) 1351 { 1352 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1353 } 1354 } 1355 break; 1356 1357 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility (form_value.Unsigned()); break; 1358 case DW_AT_declaration: 1359 case DW_AT_description: 1360 case DW_AT_mutable: 1361 case DW_AT_visibility: 1362 default: 1363 case DW_AT_sibling: 1364 break; 1365 } 1366 } 1367 } 1368 1369 Type *member_type = ResolveTypeUID(encoding_uid); 1370 assert(member_type); 1371 if (accessibility == clang::AS_none) 1372 accessibility = default_accessibility; 1373 member_accessibilities.push_back(accessibility); 1374 1375 type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size); 1376 } 1377 } 1378 break; 1379 1380 case DW_TAG_subprogram: 1381 { 1382 is_a_class = true; 1383 if (default_accessibility == clang::AS_none) 1384 default_accessibility = clang::AS_private; 1385 // TODO: implement DW_TAG_subprogram type parsing 1386 // UserDefTypeChildInfo method_info(die->GetOffset()); 1387 // 1388 // FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset())); 1389 // if (func_sp.get() == NULL) 1390 // ParseCompileUnitFunction(sc, dwarf_cu, die); 1391 // 1392 // method_info.SetEncodingTypeUID(die->GetOffset()); 1393 // struct_udt->AddMethod(method_info); 1394 } 1395 break; 1396 1397 case DW_TAG_inheritance: 1398 { 1399 is_a_class = true; 1400 if (default_accessibility == clang::AS_none) 1401 default_accessibility = clang::AS_private; 1402 // TODO: implement DW_TAG_inheritance type parsing 1403 DWARFDebugInfoEntry::Attributes attributes; 1404 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 1405 if (num_attributes > 0) 1406 { 1407 Declaration decl; 1408 DWARFExpression location; 1409 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1410 uint32_t accessibility = default_accessibility; 1411 bool is_virtual = false; 1412 bool is_base_of_class = true; 1413 off_t member_offset = 0; 1414 uint32_t i; 1415 for (i=0; i<num_attributes; ++i) 1416 { 1417 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1418 DWARFFormValue form_value; 1419 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1420 { 1421 switch (attr) 1422 { 1423 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1424 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1425 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1426 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1427 case DW_AT_data_member_location: 1428 if (form_value.BlockData()) 1429 { 1430 Value initialValue(0); 1431 Value memberOffset(0); 1432 const DataExtractor& debug_info_data = get_debug_info_data(); 1433 uint32_t block_length = form_value.Unsigned(); 1434 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1435 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL)) 1436 { 1437 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1438 } 1439 } 1440 break; 1441 1442 case DW_AT_accessibility: 1443 accessibility = DwarfToClangAccessibility(form_value.Unsigned()); 1444 break; 1445 1446 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 1447 default: 1448 case DW_AT_sibling: 1449 break; 1450 } 1451 } 1452 } 1453 1454 Type *base_class_dctype = ResolveTypeUID(encoding_uid); 1455 assert(base_class_dctype); 1456 base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class)); 1457 assert(base_classes.back()); 1458 } 1459 } 1460 break; 1461 1462 default: 1463 break; 1464 } 1465 } 1466 return count; 1467 } 1468 1469 1470 clang::DeclContext* 1471 SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid) 1472 { 1473 DWARFDebugInfo* debug_info = DebugInfo(); 1474 if (debug_info) 1475 { 1476 DWARFCompileUnitSP cu_sp; 1477 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1478 if (die) 1479 return GetClangDeclContextForDIE (cu_sp.get(), die); 1480 } 1481 return NULL; 1482 } 1483 1484 Type* 1485 SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) 1486 { 1487 DWARFDebugInfo* debug_info = DebugInfo(); 1488 if (debug_info) 1489 { 1490 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL); 1491 if (type_die != NULL) 1492 { 1493 void *type = type_die->GetUserData(); 1494 if (type == NULL) 1495 { 1496 DWARFCompileUnitSP cu_sp; 1497 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1498 if (die != NULL) 1499 { 1500 TypeSP owning_type_sp; 1501 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0)); 1502 } 1503 type = type_die->GetUserData(); 1504 } 1505 if (type != DIE_IS_BEING_PARSED) 1506 return (Type *)type; 1507 } 1508 } 1509 return NULL; 1510 } 1511 1512 CompileUnit* 1513 SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx) 1514 { 1515 // Check if the symbol vendor already knows about this compile unit? 1516 if (cu->GetUserData() == NULL) 1517 { 1518 // The symbol vendor doesn't know about this compile unit, we 1519 // need to parse and add it to the symbol vendor object. 1520 CompUnitSP dc_cu; 1521 ParseCompileUnit(cu, dc_cu); 1522 if (dc_cu.get()) 1523 { 1524 // Figure out the compile unit index if we weren't given one 1525 if (cu_idx == UINT_MAX) 1526 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx); 1527 1528 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx); 1529 } 1530 } 1531 return (CompileUnit*)cu->GetUserData(); 1532 } 1533 1534 bool 1535 SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc) 1536 { 1537 sc.Clear(); 1538 // Check if the symbol vendor already knows about this compile unit? 1539 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1540 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1541 1542 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get(); 1543 if (sc.function == NULL) 1544 sc.function = ParseCompileUnitFunction(sc, cu, func_die); 1545 1546 return sc.function != NULL; 1547 } 1548 1549 uint32_t 1550 SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 1551 { 1552 Timer scoped_timer(__PRETTY_FUNCTION__, 1553 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)", 1554 so_addr.GetSection(), 1555 so_addr.GetOffset(), 1556 resolve_scope); 1557 uint32_t resolved = 0; 1558 if (resolve_scope & ( eSymbolContextCompUnit | 1559 eSymbolContextFunction | 1560 eSymbolContextBlock | 1561 eSymbolContextLineEntry)) 1562 { 1563 lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1564 1565 DWARFDebugAranges* debug_aranges = DebugAranges(); 1566 DWARFDebugInfo* debug_info = DebugInfo(); 1567 if (debug_aranges) 1568 { 1569 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr); 1570 if (cu_offset != DW_INVALID_OFFSET) 1571 { 1572 uint32_t cu_idx; 1573 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get(); 1574 if (cu) 1575 { 1576 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1577 assert(sc.comp_unit != NULL); 1578 resolved |= eSymbolContextCompUnit; 1579 1580 if (resolve_scope & eSymbolContextLineEntry) 1581 { 1582 LineTable *line_table = sc.comp_unit->GetLineTable(); 1583 if (line_table == NULL) 1584 { 1585 if (ParseCompileUnitLineTable(sc)) 1586 line_table = sc.comp_unit->GetLineTable(); 1587 } 1588 if (line_table != NULL) 1589 { 1590 if (so_addr.IsLinkedAddress()) 1591 { 1592 Address linked_addr (so_addr); 1593 linked_addr.ResolveLinkedAddress(); 1594 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry)) 1595 { 1596 resolved |= eSymbolContextLineEntry; 1597 } 1598 } 1599 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry)) 1600 { 1601 resolved |= eSymbolContextLineEntry; 1602 } 1603 } 1604 } 1605 1606 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1607 { 1608 DWARFDebugInfoEntry *function_die = NULL; 1609 DWARFDebugInfoEntry *block_die = NULL; 1610 if (resolve_scope & eSymbolContextBlock) 1611 { 1612 cu->LookupAddress(file_vm_addr, &function_die, &block_die); 1613 } 1614 else 1615 { 1616 cu->LookupAddress(file_vm_addr, &function_die, NULL); 1617 } 1618 1619 if (function_die != NULL) 1620 { 1621 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1622 if (sc.function == NULL) 1623 sc.function = ParseCompileUnitFunction(sc, cu, function_die); 1624 } 1625 1626 if (sc.function != NULL) 1627 { 1628 resolved |= eSymbolContextFunction; 1629 1630 if (resolve_scope & eSymbolContextBlock) 1631 { 1632 BlockList& blocks = sc.function->GetBlocks(true); 1633 1634 if (block_die != NULL) 1635 sc.block = blocks.GetBlockByID(block_die->GetOffset()); 1636 else 1637 sc.block = blocks.GetBlockByID(function_die->GetOffset()); 1638 if (sc.block) 1639 resolved |= eSymbolContextBlock; 1640 } 1641 } 1642 } 1643 } 1644 } 1645 } 1646 } 1647 return resolved; 1648 } 1649 1650 1651 1652 uint32_t 1653 SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 1654 { 1655 const uint32_t prev_size = sc_list.GetSize(); 1656 if (resolve_scope & eSymbolContextCompUnit) 1657 { 1658 DWARFDebugInfo* debug_info = DebugInfo(); 1659 if (debug_info) 1660 { 1661 uint32_t cu_idx; 1662 DWARFCompileUnit* cu = NULL; 1663 1664 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) 1665 { 1666 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1667 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0; 1668 if (check_inlines || file_spec_matches_cu_file_spec) 1669 { 1670 SymbolContext sc (m_obj_file->GetModule()); 1671 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1672 assert(sc.comp_unit != NULL); 1673 1674 uint32_t file_idx = UINT32_MAX; 1675 1676 // If we are looking for inline functions only and we don't 1677 // find it in the support files, we are done. 1678 if (check_inlines) 1679 { 1680 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1681 if (file_idx == UINT32_MAX) 1682 continue; 1683 } 1684 1685 if (line != 0) 1686 { 1687 LineTable *line_table = sc.comp_unit->GetLineTable(); 1688 1689 if (line_table != NULL && line != 0) 1690 { 1691 // We will have already looked up the file index if 1692 // we are searching for inline entries. 1693 if (!check_inlines) 1694 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1695 1696 if (file_idx != UINT32_MAX) 1697 { 1698 uint32_t found_line; 1699 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); 1700 found_line = sc.line_entry.line; 1701 1702 while (line_idx != UINT_MAX) 1703 { 1704 sc.function = NULL; 1705 sc.block = NULL; 1706 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1707 { 1708 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); 1709 if (file_vm_addr != LLDB_INVALID_ADDRESS) 1710 { 1711 DWARFDebugInfoEntry *function_die = NULL; 1712 DWARFDebugInfoEntry *block_die = NULL; 1713 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL); 1714 1715 if (function_die != NULL) 1716 { 1717 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1718 if (sc.function == NULL) 1719 sc.function = ParseCompileUnitFunction(sc, cu, function_die); 1720 } 1721 1722 if (sc.function != NULL) 1723 { 1724 BlockList& blocks = sc.function->GetBlocks(true); 1725 1726 if (block_die != NULL) 1727 sc.block = blocks.GetBlockByID(block_die->GetOffset()); 1728 else 1729 sc.block = blocks.GetBlockByID(function_die->GetOffset()); 1730 } 1731 } 1732 } 1733 1734 sc_list.Append(sc); 1735 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); 1736 } 1737 } 1738 } 1739 else if (file_spec_matches_cu_file_spec && !check_inlines) 1740 { 1741 // only append the context if we aren't looking for inline call sites 1742 // by file and line and if the file spec matches that of the compile unit 1743 sc_list.Append(sc); 1744 } 1745 } 1746 else if (file_spec_matches_cu_file_spec && !check_inlines) 1747 { 1748 // only append the context if we aren't looking for inline call sites 1749 // by file and line and if the file spec matches that of the compile unit 1750 sc_list.Append(sc); 1751 } 1752 1753 if (!check_inlines) 1754 break; 1755 } 1756 } 1757 } 1758 } 1759 return sc_list.GetSize() - prev_size; 1760 } 1761 1762 void 1763 SymbolFileDWARF::Index () 1764 { 1765 if (m_indexed) 1766 return; 1767 m_indexed = true; 1768 Timer scoped_timer (__PRETTY_FUNCTION__, 1769 "SymbolFileDWARF::Index (%s)", 1770 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1771 1772 DWARFDebugInfo* debug_info = DebugInfo(); 1773 if (debug_info) 1774 { 1775 uint32_t cu_idx = 0; 1776 const uint32_t num_compile_units = GetNumCompileUnits(); 1777 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 1778 { 1779 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); 1780 1781 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1; 1782 1783 cu->Index (m_base_name_to_function_die, 1784 m_full_name_to_function_die, 1785 m_method_name_to_function_die, 1786 m_selector_name_to_function_die, 1787 m_name_to_global_die, 1788 m_name_to_type_die); 1789 1790 // Keep memory down by clearing DIEs if this generate function 1791 // caused them to be parsed 1792 if (clear_dies) 1793 cu->ClearDIEs (true); 1794 } 1795 1796 m_base_name_to_function_die.Sort(); 1797 m_full_name_to_function_die.Sort(); 1798 m_method_name_to_function_die.Sort(); 1799 m_selector_name_to_function_die.Sort(); 1800 m_name_to_global_die.Sort(); 1801 m_name_to_type_die.Sort(); 1802 } 1803 } 1804 1805 uint32_t 1806 SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 1807 { 1808 std::vector<dw_offset_t> die_offsets; 1809 1810 // If we aren't appending the results to this list, then clear the list 1811 if (!append) 1812 variables.Clear(); 1813 1814 // Remember how many variables are in the list before we search in case 1815 // we are appending the results to a variable list. 1816 const uint32_t original_size = variables.GetSize(); 1817 1818 // Index the DWARF if we haven't already 1819 if (!m_indexed) 1820 Index (); 1821 1822 const UniqueCStringMap<dw_offset_t>::Entry *entry; 1823 1824 for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString()); 1825 entry != NULL; 1826 entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry)) 1827 { 1828 DWARFCompileUnitSP cu_sp; 1829 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp); 1830 DWARFCompileUnit* cu = cu_sp.get(); 1831 if (die) 1832 { 1833 SymbolContext sc; 1834 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1835 assert (sc.module_sp); 1836 1837 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1838 assert(sc.comp_unit != NULL); 1839 1840 ParseVariables(sc, cu_sp.get(), die, false, false, &variables); 1841 1842 if (variables.GetSize() - original_size >= max_matches) 1843 break; 1844 } 1845 } 1846 1847 // Return the number of variable that were appended to the list 1848 return variables.GetSize() - original_size; 1849 } 1850 1851 uint32_t 1852 SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 1853 { 1854 std::vector<dw_offset_t> die_offsets; 1855 1856 // If we aren't appending the results to this list, then clear the list 1857 if (!append) 1858 variables.Clear(); 1859 1860 // Remember how many variables are in the list before we search in case 1861 // we are appending the results to a variable list. 1862 const uint32_t original_size = variables.GetSize(); 1863 1864 // Index the DWARF if we haven't already 1865 if (!m_indexed) 1866 Index (); 1867 1868 // Create the pubnames information so we can quickly lookup external symbols by name 1869 const size_t num_entries = m_name_to_global_die.GetSize(); 1870 for (size_t i=0; i<num_entries; i++) 1871 { 1872 if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i))) 1873 continue; 1874 1875 const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i); 1876 1877 DWARFCompileUnitSP cu_sp; 1878 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp); 1879 DWARFCompileUnit* cu = cu_sp.get(); 1880 if (die) 1881 { 1882 SymbolContext sc; 1883 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1884 assert (sc.module_sp); 1885 1886 1887 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1888 assert(sc.comp_unit != NULL); 1889 1890 ParseVariables(sc, cu_sp.get(), die, false, false, &variables); 1891 1892 if (variables.GetSize() - original_size >= max_matches) 1893 break; 1894 } 1895 } 1896 1897 // Return the number of variable that were appended to the list 1898 return variables.GetSize() - original_size; 1899 } 1900 1901 1902 void 1903 SymbolFileDWARF::FindFunctions 1904 ( 1905 const ConstString &name, 1906 UniqueCStringMap<dw_offset_t> &name_to_die, 1907 SymbolContextList& sc_list 1908 ) 1909 { 1910 const UniqueCStringMap<dw_offset_t>::Entry *entry; 1911 1912 SymbolContext sc; 1913 for (entry = name_to_die.FindFirstValueForName (name.AsCString()); 1914 entry != NULL; 1915 entry = name_to_die.FindNextValueForName (name.AsCString(), entry)) 1916 { 1917 DWARFCompileUnitSP cu_sp; 1918 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp); 1919 if (die) 1920 { 1921 if (GetFunction (cu_sp.get(), die, sc)) 1922 { 1923 // We found the function, so we should find the line table 1924 // and line table entry as well 1925 LineTable *line_table = sc.comp_unit->GetLineTable(); 1926 if (line_table == NULL) 1927 { 1928 if (ParseCompileUnitLineTable(sc)) 1929 line_table = sc.comp_unit->GetLineTable(); 1930 } 1931 if (line_table != NULL) 1932 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry); 1933 1934 sc_list.Append(sc); 1935 } 1936 } 1937 } 1938 1939 } 1940 1941 uint32_t 1942 SymbolFileDWARF::FindFunctions 1943 ( 1944 const ConstString &name, 1945 uint32_t name_type_mask, 1946 bool append, 1947 SymbolContextList& sc_list 1948 ) 1949 { 1950 Timer scoped_timer (__PRETTY_FUNCTION__, 1951 "SymbolFileDWARF::FindFunctions (name = '%s')", 1952 name.AsCString()); 1953 1954 std::vector<dw_offset_t> die_offsets; 1955 1956 // If we aren't appending the results to this list, then clear the list 1957 if (!append) 1958 sc_list.Clear(); 1959 1960 // Remember how many sc_list are in the list before we search in case 1961 // we are appending the results to a variable list. 1962 uint32_t original_size = sc_list.GetSize(); 1963 1964 // Index the DWARF if we haven't already 1965 if (!m_indexed) 1966 Index (); 1967 1968 if (name_type_mask & eFunctionNameTypeBase) 1969 FindFunctions (name, m_base_name_to_function_die, sc_list); 1970 1971 if (name_type_mask & eFunctionNameTypeFull) 1972 FindFunctions (name, m_full_name_to_function_die, sc_list); 1973 1974 if (name_type_mask & eFunctionNameTypeMethod) 1975 FindFunctions (name, m_method_name_to_function_die, sc_list); 1976 1977 if (name_type_mask & eFunctionNameTypeSelector) 1978 FindFunctions (name, m_selector_name_to_function_die, sc_list); 1979 1980 // Return the number of variable that were appended to the list 1981 return sc_list.GetSize() - original_size; 1982 } 1983 1984 1985 uint32_t 1986 SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list) 1987 { 1988 Timer scoped_timer (__PRETTY_FUNCTION__, 1989 "SymbolFileDWARF::FindFunctions (regex = '%s')", 1990 regex.GetText()); 1991 1992 std::vector<dw_offset_t> die_offsets; 1993 1994 // If we aren't appending the results to this list, then clear the list 1995 if (!append) 1996 sc_list.Clear(); 1997 1998 // Remember how many sc_list are in the list before we search in case 1999 // we are appending the results to a variable list. 2000 uint32_t original_size = sc_list.GetSize(); 2001 2002 // Index the DWARF if we haven't already 2003 if (!m_indexed) 2004 Index (); 2005 2006 // Create the pubnames information so we can quickly lookup external symbols by name 2007 // Create the pubnames information so we can quickly lookup external symbols by name 2008 const size_t num_entries = m_full_name_to_function_die.GetSize(); 2009 SymbolContext sc; 2010 for (size_t i=0; i<num_entries; i++) 2011 { 2012 if (!regex.Execute(m_full_name_to_function_die.GetCStringAtIndex (i))) 2013 continue; 2014 2015 const dw_offset_t die_offset = *m_full_name_to_function_die.GetValueAtIndex (i); 2016 2017 DWARFCompileUnitSP cu_sp; 2018 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp); 2019 if (die) 2020 { 2021 if (GetFunction (cu_sp.get(), die, sc)) 2022 { 2023 // We found the function, so we should find the line table 2024 // and line table entry as well 2025 LineTable *line_table = sc.comp_unit->GetLineTable(); 2026 if (line_table == NULL) 2027 { 2028 if (ParseCompileUnitLineTable(sc)) 2029 line_table = sc.comp_unit->GetLineTable(); 2030 } 2031 if (line_table != NULL) 2032 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry); 2033 2034 2035 sc_list.Append(sc); 2036 } 2037 } 2038 } 2039 2040 // Return the number of variable that were appended to the list 2041 return sc_list.GetSize() - original_size; 2042 } 2043 2044 #if 0 2045 uint32_t 2046 SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 2047 { 2048 // If we aren't appending the results to this list, then clear the list 2049 if (!append) 2050 types.Clear(); 2051 2052 // Create the pubnames information so we can quickly lookup external symbols by name 2053 DWARFDebugPubnames* pubtypes = DebugPubtypes(); 2054 if (pubtypes) 2055 { 2056 std::vector<dw_offset_t> die_offsets; 2057 if (!pubtypes->Find(name.AsCString(), false, die_offsets)) 2058 { 2059 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); 2060 if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets)) 2061 return 0; 2062 } 2063 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); 2064 } 2065 return 0; 2066 } 2067 2068 2069 uint32_t 2070 SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 2071 { 2072 // If we aren't appending the results to this list, then clear the list 2073 if (!append) 2074 types.Clear(); 2075 2076 // Create the pubnames information so we can quickly lookup external symbols by name 2077 DWARFDebugPubnames* pubtypes = DebugPubtypes(); 2078 if (pubtypes) 2079 { 2080 std::vector<dw_offset_t> die_offsets; 2081 if (!pubtypes->Find(regex, die_offsets)) 2082 { 2083 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); 2084 if (pub_base_types && !pub_base_types->Find(regex, die_offsets)) 2085 return 0; 2086 } 2087 2088 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); 2089 } 2090 2091 return 0; 2092 } 2093 2094 2095 2096 uint32_t 2097 SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 2098 { 2099 // Remember how many sc_list are in the list before we search in case 2100 // we are appending the results to a variable list. 2101 uint32_t original_size = types.Size(); 2102 2103 const uint32_t num_die_offsets = die_offsets.size(); 2104 // Parse all of the types we found from the pubtypes matches 2105 uint32_t i; 2106 uint32_t num_matches = 0; 2107 for (i = 0; i < num_die_offsets; ++i) 2108 { 2109 dw_offset_t die_offset = die_offsets[i]; 2110 DWARFCompileUnitSP cu_sp; 2111 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2112 2113 assert(die != NULL); 2114 2115 bool get_type_for_die = true; 2116 if (encoding) 2117 { 2118 // Check if this type has already been uniqued and registers with the module? 2119 Type* type = (Type*)die->GetUserData(); 2120 if (type != NULL && type != DIE_IS_BEING_PARSED) 2121 { 2122 get_type_for_die = type->GetEncoding() == encoding; 2123 } 2124 else 2125 { 2126 dw_tag_t tag = die->Tag(); 2127 switch (encoding) 2128 { 2129 case Type::address: 2130 case Type::boolean: 2131 case Type::complex_float: 2132 case Type::float_type: 2133 case Type::signed_int: 2134 case Type::signed_char: 2135 case Type::unsigned_int: 2136 case Type::unsigned_char: 2137 case Type::imaginary_float: 2138 case Type::packed_decimal: 2139 case Type::numeric_string: 2140 case Type::edited_string: 2141 case Type::signed_fixed: 2142 case Type::unsigned_fixed: 2143 case Type::decimal_float: 2144 if (tag != DW_TAG_base_type) 2145 get_type_for_die = false; 2146 else 2147 { 2148 if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding) 2149 get_type_for_die = false; 2150 } 2151 break; 2152 2153 case Type::indirect_const: get_type_for_die = tag == DW_TAG_const_type; break; 2154 case Type::indirect_restrict: get_type_for_die = tag == DW_TAG_restrict_type; break; 2155 case Type::indirect_volatile: get_type_for_die = tag == DW_TAG_volatile_type; break; 2156 case Type::indirect_typedef: get_type_for_die = tag == DW_TAG_typedef; break; 2157 case Type::indirect_pointer: get_type_for_die = tag == DW_TAG_pointer_type; break; 2158 case Type::indirect_reference: get_type_for_die = tag == DW_TAG_reference_type; break; 2159 2160 case Type::user_defined_type: 2161 switch (tag) 2162 { 2163 case DW_TAG_array_type: 2164 get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid); 2165 break; 2166 2167 case DW_TAG_structure_type: 2168 case DW_TAG_union_type: 2169 case DW_TAG_class_type: 2170 get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid); 2171 break; 2172 2173 case DW_TAG_enumeration_type: 2174 get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid); 2175 break; 2176 2177 case DW_TAG_subprogram: 2178 case DW_TAG_subroutine_type: 2179 get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid); 2180 break; 2181 } 2182 } 2183 } 2184 } 2185 2186 if (get_type_for_die) 2187 { 2188 TypeSP owning_type_sp; 2189 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0)); 2190 2191 if (type_sp.get()) 2192 { 2193 // See if we are filtering results based on encoding? 2194 bool add_type = (encoding == Type::invalid); 2195 if (!add_type) 2196 { 2197 // We are filtering base on encoding, so lets check the resulting type encoding 2198 add_type = (encoding == type_sp->GetEncoding()); 2199 if (add_type) 2200 { 2201 // The type encoding matches, if this is a user defined type, lets 2202 // make sure the exact user define type uid matches if one was provided 2203 if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID) 2204 { 2205 UserDefType* udt = type_sp->GetUserDefinedType().get(); 2206 if (udt) 2207 add_type = udt->UserDefinedTypeUID() == udt_uid; 2208 } 2209 } 2210 } 2211 // Add the type to our list as long as everything matched 2212 if (add_type) 2213 { 2214 types.InsertUnique(type_sp); 2215 if (++num_matches >= max_matches) 2216 break; 2217 } 2218 } 2219 } 2220 } 2221 2222 // Return the number of variable that were appended to the list 2223 return types.Size() - original_size; 2224 } 2225 2226 #endif 2227 2228 2229 size_t 2230 SymbolFileDWARF::ParseChildParameters 2231 ( 2232 const SymbolContext& sc, 2233 TypeSP& type_sp, 2234 const DWARFCompileUnit* dwarf_cu, 2235 const DWARFDebugInfoEntry *parent_die, 2236 TypeList* type_list, 2237 std::vector<void *>& function_param_types, 2238 std::vector<clang::ParmVarDecl*>& function_param_decls 2239 ) 2240 { 2241 if (parent_die == NULL) 2242 return 0; 2243 2244 size_t count = 0; 2245 const DWARFDebugInfoEntry *die; 2246 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2247 { 2248 dw_tag_t tag = die->Tag(); 2249 switch (tag) 2250 { 2251 case DW_TAG_formal_parameter: 2252 { 2253 DWARFDebugInfoEntry::Attributes attributes; 2254 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2255 if (num_attributes > 0) 2256 { 2257 const char *name = NULL; 2258 Declaration decl; 2259 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET; 2260 // one of None, Auto, Register, Extern, Static, PrivateExtern 2261 2262 clang::VarDecl::StorageClass storage = clang::VarDecl::None; 2263 uint32_t i; 2264 for (i=0; i<num_attributes; ++i) 2265 { 2266 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2267 DWARFFormValue form_value; 2268 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2269 { 2270 switch (attr) 2271 { 2272 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2273 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2274 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2275 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 2276 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break; 2277 case DW_AT_location: 2278 // if (form_value.BlockData()) 2279 // { 2280 // const DataExtractor& debug_info_data = debug_info(); 2281 // uint32_t block_length = form_value.Unsigned(); 2282 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); 2283 // } 2284 // else 2285 // { 2286 // } 2287 // break; 2288 case DW_AT_artificial: 2289 case DW_AT_const_value: 2290 case DW_AT_default_value: 2291 case DW_AT_description: 2292 case DW_AT_endianity: 2293 case DW_AT_is_optional: 2294 case DW_AT_segment: 2295 case DW_AT_variable_parameter: 2296 default: 2297 case DW_AT_abstract_origin: 2298 case DW_AT_sibling: 2299 break; 2300 } 2301 } 2302 } 2303 Type *dc_type = ResolveTypeUID(param_type_die_offset); 2304 if (dc_type) 2305 { 2306 function_param_types.push_back (dc_type->GetOpaqueClangQualType()); 2307 2308 clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage); 2309 assert(param_var_decl); 2310 function_param_decls.push_back(param_var_decl); 2311 } 2312 } 2313 } 2314 break; 2315 2316 default: 2317 break; 2318 } 2319 } 2320 return count; 2321 } 2322 2323 size_t 2324 SymbolFileDWARF::ParseChildEnumerators 2325 ( 2326 const SymbolContext& sc, 2327 TypeSP& type_sp, 2328 void * enumerator_qual_type, 2329 uint32_t enumerator_byte_size, 2330 const DWARFCompileUnit* dwarf_cu, 2331 const DWARFDebugInfoEntry *parent_die 2332 ) 2333 { 2334 if (parent_die == NULL) 2335 return 0; 2336 2337 size_t enumerators_added = 0; 2338 const DWARFDebugInfoEntry *die; 2339 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2340 { 2341 const dw_tag_t tag = die->Tag(); 2342 if (tag == DW_TAG_enumerator) 2343 { 2344 DWARFDebugInfoEntry::Attributes attributes; 2345 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2346 if (num_child_attributes > 0) 2347 { 2348 const char *name = NULL; 2349 bool got_value = false; 2350 int64_t enum_value = 0; 2351 Declaration decl; 2352 2353 uint32_t i; 2354 for (i=0; i<num_child_attributes; ++i) 2355 { 2356 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2357 DWARFFormValue form_value; 2358 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2359 { 2360 switch (attr) 2361 { 2362 case DW_AT_const_value: 2363 got_value = true; 2364 enum_value = form_value.Unsigned(); 2365 break; 2366 2367 case DW_AT_name: 2368 name = form_value.AsCString(&get_debug_str_data()); 2369 break; 2370 2371 case DW_AT_description: 2372 default: 2373 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2374 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2375 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2376 case DW_AT_sibling: 2377 break; 2378 } 2379 } 2380 } 2381 2382 if (name && name[0] && got_value) 2383 { 2384 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2385 type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8); 2386 ++enumerators_added; 2387 } 2388 } 2389 } 2390 } 2391 return enumerators_added; 2392 } 2393 2394 void 2395 SymbolFileDWARF::ParseChildArrayInfo 2396 ( 2397 const SymbolContext& sc, 2398 const DWARFCompileUnit* dwarf_cu, 2399 const DWARFDebugInfoEntry *parent_die, 2400 int64_t& first_index, 2401 std::vector<uint64_t>& element_orders, 2402 uint32_t& byte_stride, 2403 uint32_t& bit_stride 2404 ) 2405 { 2406 if (parent_die == NULL) 2407 return; 2408 2409 const DWARFDebugInfoEntry *die; 2410 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2411 { 2412 const dw_tag_t tag = die->Tag(); 2413 switch (tag) 2414 { 2415 case DW_TAG_enumerator: 2416 { 2417 DWARFDebugInfoEntry::Attributes attributes; 2418 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2419 if (num_child_attributes > 0) 2420 { 2421 const char *name = NULL; 2422 bool got_value = false; 2423 int64_t enum_value = 0; 2424 2425 uint32_t i; 2426 for (i=0; i<num_child_attributes; ++i) 2427 { 2428 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2429 DWARFFormValue form_value; 2430 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2431 { 2432 switch (attr) 2433 { 2434 case DW_AT_const_value: 2435 got_value = true; 2436 enum_value = form_value.Unsigned(); 2437 break; 2438 2439 case DW_AT_name: 2440 name = form_value.AsCString(&get_debug_str_data()); 2441 break; 2442 2443 case DW_AT_description: 2444 default: 2445 case DW_AT_decl_file: 2446 case DW_AT_decl_line: 2447 case DW_AT_decl_column: 2448 case DW_AT_sibling: 2449 break; 2450 } 2451 } 2452 } 2453 } 2454 } 2455 break; 2456 2457 case DW_TAG_subrange_type: 2458 { 2459 DWARFDebugInfoEntry::Attributes attributes; 2460 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2461 if (num_child_attributes > 0) 2462 { 2463 const char *name = NULL; 2464 bool got_value = false; 2465 uint64_t byte_size = 0; 2466 int64_t enum_value = 0; 2467 uint64_t num_elements = 0; 2468 uint64_t lower_bound = 0; 2469 uint64_t upper_bound = 0; 2470 uint32_t i; 2471 for (i=0; i<num_child_attributes; ++i) 2472 { 2473 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2474 DWARFFormValue form_value; 2475 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2476 { 2477 switch (attr) 2478 { 2479 case DW_AT_const_value: 2480 got_value = true; 2481 enum_value = form_value.Unsigned(); 2482 break; 2483 2484 case DW_AT_name: 2485 name = form_value.AsCString(&get_debug_str_data()); 2486 break; 2487 2488 case DW_AT_count: 2489 num_elements = form_value.Unsigned(); 2490 break; 2491 2492 case DW_AT_bit_stride: 2493 bit_stride = form_value.Unsigned(); 2494 break; 2495 2496 case DW_AT_byte_stride: 2497 byte_stride = form_value.Unsigned(); 2498 break; 2499 2500 case DW_AT_byte_size: 2501 byte_size = form_value.Unsigned(); 2502 break; 2503 2504 case DW_AT_lower_bound: 2505 lower_bound = form_value.Unsigned(); 2506 break; 2507 2508 case DW_AT_upper_bound: 2509 upper_bound = form_value.Unsigned(); 2510 break; 2511 2512 default: 2513 //printf("0x%8.8x: %-30s skipping attribute at 0x%8.8x: %s\n", die->GetOffset(), DW_TAG_value_to_name(tag), attributes.die_offsets[i], DW_AT_value_to_name(attr)); // remove this, debug only 2514 2515 case DW_AT_abstract_origin: 2516 case DW_AT_accessibility: 2517 case DW_AT_allocated: 2518 case DW_AT_associated: 2519 case DW_AT_data_location: 2520 case DW_AT_declaration: 2521 case DW_AT_description: 2522 case DW_AT_sibling: 2523 case DW_AT_threads_scaled: 2524 case DW_AT_type: 2525 case DW_AT_visibility: 2526 break; 2527 } 2528 } 2529 } 2530 2531 if (upper_bound > lower_bound) 2532 num_elements = upper_bound - lower_bound + 1; 2533 2534 if (num_elements > 0) 2535 element_orders.push_back (num_elements); 2536 } 2537 } 2538 break; 2539 } 2540 } 2541 } 2542 2543 Type* 2544 SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe) 2545 { 2546 if (type_die_offset != DW_INVALID_OFFSET) 2547 { 2548 DWARFCompileUnitSP cu_sp; 2549 const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp); 2550 assert(type_die != NULL); 2551 GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx); 2552 // Return the uniqued type if there is one 2553 Type* type = (Type*)type_die->GetUserData(); 2554 if (type == DIE_IS_BEING_PARSED && safe) 2555 return NULL; 2556 return type; 2557 } 2558 return NULL; 2559 } 2560 2561 TypeSP 2562 SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx) 2563 { 2564 TypeSP type_sp; 2565 if (die != NULL) 2566 { 2567 assert(cu != NULL); 2568 Type *type_ptr = (Type *)die->GetUserData(); 2569 if (type_ptr == NULL) 2570 { 2571 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu)); 2572 bool type_is_new = false; 2573 type_sp = ParseType(sc, cu, die, type_is_new); 2574 type_ptr = (Type *)die->GetUserData(); 2575 if (owning_type_sp.get() == NULL) 2576 owning_type_sp = type_sp; 2577 } 2578 else if (type_ptr != DIE_IS_BEING_PARSED) 2579 { 2580 // Grab the existing type from the master types lists 2581 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID()); 2582 } 2583 2584 } 2585 return type_sp; 2586 } 2587 2588 clang::DeclContext * 2589 SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset) 2590 { 2591 if (die_offset != DW_INVALID_OFFSET) 2592 { 2593 DWARFCompileUnitSP cu_sp; 2594 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2595 return GetClangDeclContextForDIE (cu_sp.get(), die); 2596 } 2597 return NULL; 2598 } 2599 2600 2601 2602 clang::DeclContext * 2603 SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 2604 { 2605 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); 2606 if (pos != m_die_to_decl_ctx.end()) 2607 return pos->second; 2608 2609 while (die != NULL) 2610 { 2611 switch (die->Tag()) 2612 { 2613 case DW_TAG_namespace: 2614 { 2615 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL); 2616 if (namespace_name) 2617 { 2618 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2619 assert(type_list); 2620 Declaration decl; // TODO: fill in the decl object 2621 clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent())); 2622 if (namespace_decl) 2623 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl; 2624 return namespace_decl; 2625 } 2626 } 2627 break; 2628 2629 default: 2630 break; 2631 } 2632 clang::DeclContext *decl_ctx; 2633 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET)); 2634 if (decl_ctx) 2635 return decl_ctx; 2636 2637 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET)); 2638 if (decl_ctx) 2639 return decl_ctx; 2640 2641 die = die->GetParent(); 2642 } 2643 return NULL; 2644 } 2645 2646 TypeSP 2647 SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new) 2648 { 2649 TypeSP type_sp; 2650 2651 uint32_t accessibility = clang::AS_none; 2652 if (die != NULL) 2653 { 2654 dw_tag_t tag = die->Tag(); 2655 if (die->GetUserData() == NULL) 2656 { 2657 type_is_new = true; 2658 2659 bool is_forward_declaration = false; 2660 DWARFDebugInfoEntry::Attributes attributes; 2661 const char *type_name_cstr = NULL; 2662 ConstString type_name_dbstr; 2663 Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID; 2664 void *clang_type = NULL; 2665 2666 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2667 dw_attr_t attr; 2668 2669 switch (tag) 2670 { 2671 case DW_TAG_base_type: 2672 case DW_TAG_pointer_type: 2673 case DW_TAG_reference_type: 2674 case DW_TAG_typedef: 2675 case DW_TAG_const_type: 2676 case DW_TAG_restrict_type: 2677 case DW_TAG_volatile_type: 2678 { 2679 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2680 // Set a bit that lets us know that we are currently parsing this 2681 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2682 2683 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2684 Declaration decl; 2685 uint32_t encoding = 0; 2686 size_t byte_size = 0; 2687 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 2688 2689 if (num_attributes > 0) 2690 { 2691 uint32_t i; 2692 for (i=0; i<num_attributes; ++i) 2693 { 2694 attr = attributes.AttributeAtIndex(i); 2695 DWARFFormValue form_value; 2696 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2697 { 2698 switch (attr) 2699 { 2700 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2701 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2702 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2703 case DW_AT_name: 2704 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2705 type_name_dbstr.SetCString(type_name_cstr); 2706 break; 2707 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2708 case DW_AT_encoding: encoding = form_value.Unsigned(); break; 2709 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 2710 default: 2711 case DW_AT_sibling: 2712 break; 2713 } 2714 } 2715 } 2716 } 2717 2718 switch (tag) 2719 { 2720 default: 2721 case DW_TAG_base_type: 2722 clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8); 2723 break; 2724 2725 case DW_TAG_pointer_type: 2726 // The encoding_uid will be embedded into the 2727 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2728 encoding_uid_type = Type::ePointerToTypeWithUID; 2729 break; 2730 2731 case DW_TAG_reference_type: 2732 // The encoding_uid will be embedded into the 2733 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2734 encoding_uid_type = Type::eLValueReferenceToTypeWithUID; 2735 break; 2736 2737 case DW_TAG_typedef: 2738 // The encoding_uid will be embedded into the 2739 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2740 encoding_uid_type = Type::eTypedefToTypeWithUID; 2741 break; 2742 2743 case DW_TAG_const_type: 2744 // The encoding_uid will be embedded into the 2745 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2746 encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type); 2747 break; 2748 2749 case DW_TAG_restrict_type: 2750 // The encoding_uid will be embedded into the 2751 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2752 encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type); 2753 break; 2754 2755 case DW_TAG_volatile_type: 2756 // The encoding_uid will be embedded into the 2757 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2758 encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type); 2759 break; 2760 } 2761 2762 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type)); 2763 2764 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2765 2766 2767 // Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); 2768 // if (encoding_type != NULL) 2769 // { 2770 // if (encoding_type != DIE_IS_BEING_PARSED) 2771 // type_sp->SetEncodingType(encoding_type); 2772 // else 2773 // m_indirect_fixups.push_back(type_sp.get()); 2774 // } 2775 } 2776 break; 2777 2778 case DW_TAG_structure_type: 2779 case DW_TAG_union_type: 2780 case DW_TAG_class_type: 2781 { 2782 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2783 // Set a bit that lets us know that we are currently parsing this 2784 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2785 2786 size_t byte_size = 0; 2787 //bool struct_is_class = false; 2788 Declaration decl; 2789 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2790 if (num_attributes > 0) 2791 { 2792 uint32_t i; 2793 for (i=0; i<num_attributes; ++i) 2794 { 2795 attr = attributes.AttributeAtIndex(i); 2796 DWARFFormValue form_value; 2797 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2798 { 2799 switch (attr) 2800 { 2801 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2802 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2803 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2804 case DW_AT_name: 2805 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2806 type_name_dbstr.SetCString(type_name_cstr); 2807 break; 2808 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2809 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; break; 2810 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 2811 case DW_AT_allocated: 2812 case DW_AT_associated: 2813 case DW_AT_data_location: 2814 case DW_AT_description: 2815 case DW_AT_start_scope: 2816 case DW_AT_visibility: 2817 default: 2818 case DW_AT_sibling: 2819 break; 2820 } 2821 } 2822 } 2823 } 2824 2825 int tag_decl_kind = -1; 2826 int default_accessibility = clang::AS_none; 2827 if (tag == DW_TAG_structure_type) 2828 { 2829 tag_decl_kind = clang::TTK_Struct; 2830 default_accessibility = clang::AS_public; 2831 } 2832 else if (tag == DW_TAG_union_type) 2833 { 2834 tag_decl_kind = clang::TTK_Union; 2835 default_accessibility = clang::AS_public; 2836 } 2837 else if (tag == DW_TAG_class_type) 2838 { 2839 tag_decl_kind = clang::TTK_Class; 2840 default_accessibility = clang::AS_private; 2841 } 2842 2843 assert (tag_decl_kind != -1); 2844 clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die)); 2845 2846 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); 2847 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 2848 2849 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2850 2851 // assert(type_sp.get()); 2852 // if (accessibility) 2853 // type_sp->SetAccess(accessibility); 2854 // 2855 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type); 2856 if (die->HasChildren()) 2857 { 2858 std::vector<clang::CXXBaseSpecifier *> base_classes; 2859 std::vector<int> member_accessibilities; 2860 bool is_a_class = false; 2861 ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class); 2862 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we 2863 // need to tell the clang type it is actually a class. 2864 if (is_a_class && tag_decl_kind != clang::TTK_Class) 2865 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class); 2866 2867 // Since DW_TAG_structure_type gets used for both classes 2868 // and structures, we may need to set any DW_TAG_member 2869 // fields to have a "private" access if none was specified. 2870 // When we parsed the child members we tracked that actual 2871 // accessibility value for each DW_TAG_member in the 2872 // "member_accessibilities" array. If the value for the 2873 // member is zero, then it was set to the "default_accessibility" 2874 // which for structs was "public". Below we correct this 2875 // by setting any fields to "private" that weren't correctly 2876 // set. 2877 if (is_a_class && !member_accessibilities.empty()) 2878 { 2879 // This is a class and all members that didn't have 2880 // their access specified are private. 2881 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, clang::AS_private, member_accessibilities.data(), member_accessibilities.size()); 2882 } 2883 2884 if (!base_classes.empty()) 2885 { 2886 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, base_classes.data(), base_classes.size()); 2887 } 2888 } 2889 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type); 2890 } 2891 break; 2892 2893 case DW_TAG_enumeration_type: 2894 { 2895 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2896 // Set a bit that lets us know that we are currently parsing this 2897 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2898 2899 size_t byte_size = 0; 2900 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET; 2901 Declaration decl; 2902 2903 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2904 if (num_attributes > 0) 2905 { 2906 uint32_t i; 2907 2908 for (i=0; i<num_attributes; ++i) 2909 { 2910 attr = attributes.AttributeAtIndex(i); 2911 DWARFFormValue form_value; 2912 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2913 { 2914 switch (attr) 2915 { 2916 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2917 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2918 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2919 case DW_AT_name: 2920 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2921 type_name_dbstr.SetCString(type_name_cstr); 2922 break; 2923 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 2924 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2925 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; 2926 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 2927 case DW_AT_allocated: 2928 case DW_AT_associated: 2929 case DW_AT_bit_stride: 2930 case DW_AT_byte_stride: 2931 case DW_AT_data_location: 2932 case DW_AT_description: 2933 case DW_AT_start_scope: 2934 case DW_AT_visibility: 2935 case DW_AT_specification: 2936 case DW_AT_abstract_origin: 2937 case DW_AT_sibling: 2938 break; 2939 } 2940 } 2941 } 2942 2943 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr); 2944 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); 2945 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type)); 2946 2947 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2948 2949 if (die->HasChildren()) 2950 { 2951 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type); 2952 void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8); 2953 ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die); 2954 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type); 2955 } 2956 } 2957 } 2958 break; 2959 2960 case DW_TAG_subprogram: 2961 case DW_TAG_subroutine_type: 2962 { 2963 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2964 // Set a bit that lets us know that we are currently parsing this 2965 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2966 2967 const char *mangled = NULL; 2968 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 2969 Declaration decl; 2970 bool isVariadic = false; 2971 bool is_inline = false; 2972 unsigned type_quals = 0; 2973 clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern 2974 2975 2976 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2977 if (num_attributes > 0) 2978 { 2979 uint32_t i; 2980 for (i=0; i<num_attributes; ++i) 2981 { 2982 attr = attributes.AttributeAtIndex(i); 2983 DWARFFormValue form_value; 2984 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2985 { 2986 switch (attr) 2987 { 2988 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2989 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2990 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2991 case DW_AT_name: 2992 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2993 type_name_dbstr.SetCString(type_name_cstr); 2994 break; 2995 2996 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 2997 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 2998 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; 2999 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3000 case DW_AT_external: 3001 if (form_value.Unsigned()) 3002 { 3003 if (storage == clang::FunctionDecl::None) 3004 storage = clang::FunctionDecl::Extern; 3005 else 3006 storage = clang::FunctionDecl::PrivateExtern; 3007 } 3008 break; 3009 case DW_AT_inline: 3010 is_inline = form_value.Unsigned() != 0; 3011 break; 3012 3013 case DW_AT_allocated: 3014 case DW_AT_associated: 3015 case DW_AT_address_class: 3016 case DW_AT_artificial: 3017 case DW_AT_calling_convention: 3018 case DW_AT_data_location: 3019 case DW_AT_elemental: 3020 case DW_AT_entry_pc: 3021 case DW_AT_explicit: 3022 case DW_AT_frame_base: 3023 case DW_AT_high_pc: 3024 case DW_AT_low_pc: 3025 case DW_AT_object_pointer: 3026 case DW_AT_prototyped: 3027 case DW_AT_pure: 3028 case DW_AT_ranges: 3029 case DW_AT_recursive: 3030 case DW_AT_return_addr: 3031 case DW_AT_segment: 3032 case DW_AT_specification: 3033 case DW_AT_start_scope: 3034 case DW_AT_static_link: 3035 case DW_AT_trampoline: 3036 case DW_AT_visibility: 3037 case DW_AT_virtuality: 3038 case DW_AT_vtable_elem_location: 3039 case DW_AT_abstract_origin: 3040 case DW_AT_description: 3041 case DW_AT_sibling: 3042 break; 3043 } 3044 } 3045 } 3046 3047 void *return_clang_type = NULL; 3048 Type *func_type = ResolveTypeUID(type_die_offset); 3049 if (func_type) 3050 return_clang_type = func_type->GetOpaqueClangQualType(); 3051 else 3052 return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType(); 3053 3054 std::vector<void *> function_param_types; 3055 std::vector<clang::ParmVarDecl*> function_param_decls; 3056 3057 // Parse the function children for the parameters 3058 ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls); 3059 3060 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals); 3061 if (type_name_cstr) 3062 { 3063 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline); 3064 // Add the decl to our DIE to decl context map 3065 assert (function_decl); 3066 m_die_to_decl_ctx[die] = function_decl; 3067 if (!function_param_decls.empty()) 3068 type_list->GetClangASTContext().SetFunctionParameters (function_decl, function_param_decls.data(), function_param_decls.size()); 3069 } 3070 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 3071 3072 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 3073 assert(type_sp.get()); 3074 } 3075 } 3076 break; 3077 3078 case DW_TAG_array_type: 3079 { 3080 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 3081 // Set a bit that lets us know that we are currently parsing this 3082 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 3083 3084 size_t byte_size = 0; 3085 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; 3086 Declaration decl; 3087 int64_t first_index = 0; 3088 uint32_t byte_stride = 0; 3089 uint32_t bit_stride = 0; 3090 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 3091 3092 if (num_attributes > 0) 3093 { 3094 uint32_t i; 3095 for (i=0; i<num_attributes; ++i) 3096 { 3097 attr = attributes.AttributeAtIndex(i); 3098 DWARFFormValue form_value; 3099 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3100 { 3101 switch (attr) 3102 { 3103 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3104 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3105 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3106 case DW_AT_name: 3107 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3108 type_name_dbstr.SetCString(type_name_cstr); 3109 break; 3110 3111 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 3112 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 3113 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; 3114 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; 3115 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; 3116 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3117 case DW_AT_allocated: 3118 case DW_AT_associated: 3119 case DW_AT_data_location: 3120 case DW_AT_description: 3121 case DW_AT_ordering: 3122 case DW_AT_start_scope: 3123 case DW_AT_visibility: 3124 case DW_AT_specification: 3125 case DW_AT_abstract_origin: 3126 case DW_AT_sibling: 3127 break; 3128 } 3129 } 3130 } 3131 3132 Type *element_type = ResolveTypeUID(type_die_offset); 3133 3134 if (element_type) 3135 { 3136 std::vector<uint64_t> element_orders; 3137 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride); 3138 if (byte_stride == 0 && bit_stride == 0) 3139 byte_stride = element_type->GetByteSize(); 3140 void *array_element_type = element_type->GetOpaqueClangQualType(); 3141 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; 3142 uint64_t num_elements = 0; 3143 std::vector<uint64_t>::const_reverse_iterator pos; 3144 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); 3145 for (pos = element_orders.rbegin(); pos != end; ++pos) 3146 { 3147 num_elements = *pos; 3148 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride); 3149 array_element_type = clang_type; 3150 array_element_bit_stride = array_element_bit_stride * num_elements; 3151 } 3152 ConstString empty_name; 3153 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 3154 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 3155 } 3156 } 3157 } 3158 break; 3159 3160 case DW_TAG_ptr_to_member_type: 3161 { 3162 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 3163 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET; 3164 3165 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 3166 3167 if (num_attributes > 0) { 3168 uint32_t i; 3169 for (i=0; i<num_attributes; ++i) 3170 { 3171 attr = attributes.AttributeAtIndex(i); 3172 DWARFFormValue form_value; 3173 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3174 { 3175 switch (attr) 3176 { 3177 case DW_AT_type: 3178 type_die_offset = form_value.Reference(dwarf_cu); break; 3179 case DW_AT_containing_type: 3180 containing_type_die_offset = form_value.Reference(dwarf_cu); break; 3181 } 3182 } 3183 } 3184 3185 Type *pointee_type = ResolveTypeUID(type_die_offset); 3186 Type *class_type = ResolveTypeUID(containing_type_die_offset); 3187 3188 void *pointee_clang_type = pointee_type->GetOpaqueClangQualType(); 3189 void *class_clang_type = class_type->GetOpaqueClangQualType(); 3190 3191 void *clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type); 3192 3193 size_t byte_size = ClangASTContext::GetTypeBitSize(type_list->GetClangASTContext().getASTContext(), clang_type) / 8; 3194 3195 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type)); 3196 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 3197 } 3198 3199 break; 3200 } 3201 default: 3202 assert(false && "Unhandled type tag!"); 3203 break; 3204 } 3205 3206 if (type_sp.get()) 3207 { 3208 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 3209 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3210 3211 SymbolContextScope * symbol_context_scope = NULL; 3212 if (sc_parent_tag == DW_TAG_compile_unit) 3213 { 3214 symbol_context_scope = sc.comp_unit; 3215 } 3216 else if (sc.function != NULL) 3217 { 3218 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset()); 3219 if (symbol_context_scope == NULL) 3220 symbol_context_scope = sc.function; 3221 } 3222 3223 if (symbol_context_scope != NULL) 3224 { 3225 type_sp->SetSymbolContextScope(symbol_context_scope); 3226 } 3227 3228 // if (udt_sp.get()) 3229 // { 3230 // if (is_forward_declaration) 3231 // udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition); 3232 // type_sp->SetUserDefinedType(udt_sp); 3233 // } 3234 3235 if (type_sp.unique()) 3236 { 3237 // We are ready to put this type into the uniqued list up at the module level 3238 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp)); 3239 3240 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get()); 3241 3242 type_sp = uniqued_type_sp; 3243 } 3244 } 3245 } 3246 else 3247 { 3248 switch (tag) 3249 { 3250 case DW_TAG_base_type: 3251 case DW_TAG_pointer_type: 3252 case DW_TAG_reference_type: 3253 case DW_TAG_typedef: 3254 case DW_TAG_const_type: 3255 case DW_TAG_restrict_type: 3256 case DW_TAG_volatile_type: 3257 case DW_TAG_structure_type: 3258 case DW_TAG_union_type: 3259 case DW_TAG_class_type: 3260 case DW_TAG_enumeration_type: 3261 case DW_TAG_subprogram: 3262 case DW_TAG_subroutine_type: 3263 case DW_TAG_array_type: 3264 { 3265 Type *existing_type = (Type*)die->GetUserData(); 3266 if (existing_type != DIE_IS_BEING_PARSED) 3267 { 3268 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID()); 3269 } 3270 } 3271 break; 3272 default: 3273 //assert(!"invalid type tag..."); 3274 break; 3275 } 3276 } 3277 } 3278 return type_sp; 3279 } 3280 3281 size_t 3282 SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children) 3283 { 3284 size_t types_added = 0; 3285 while (die != NULL) 3286 { 3287 bool type_is_new = false; 3288 if (ParseType(sc, dwarf_cu, die, type_is_new).get()) 3289 { 3290 if (type_is_new) 3291 ++types_added; 3292 } 3293 3294 if (parse_children && die->HasChildren()) 3295 { 3296 if (die->Tag() == DW_TAG_subprogram) 3297 { 3298 SymbolContext child_sc(sc); 3299 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get(); 3300 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true); 3301 } 3302 else 3303 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true); 3304 } 3305 3306 if (parse_siblings) 3307 die = die->GetSibling(); 3308 else 3309 die = NULL; 3310 } 3311 return types_added; 3312 } 3313 3314 3315 size_t 3316 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) 3317 { 3318 assert(sc.comp_unit && sc.function); 3319 size_t functions_added = 0; 3320 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3321 if (dwarf_cu) 3322 { 3323 dw_offset_t function_die_offset = sc.function->GetID(); 3324 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); 3325 if (function_die) 3326 { 3327 ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true); 3328 } 3329 } 3330 3331 return functions_added; 3332 } 3333 3334 3335 size_t 3336 SymbolFileDWARF::ParseTypes (const SymbolContext &sc) 3337 { 3338 // At least a compile unit must be valid 3339 assert(sc.comp_unit); 3340 size_t types_added = 0; 3341 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3342 if (dwarf_cu) 3343 { 3344 if (sc.function) 3345 { 3346 dw_offset_t function_die_offset = sc.function->GetID(); 3347 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset); 3348 if (func_die && func_die->HasChildren()) 3349 { 3350 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true); 3351 } 3352 } 3353 else 3354 { 3355 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE(); 3356 if (dwarf_cu_die && dwarf_cu_die->HasChildren()) 3357 { 3358 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true); 3359 } 3360 } 3361 } 3362 3363 return types_added; 3364 } 3365 3366 size_t 3367 SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) 3368 { 3369 if (sc.comp_unit != NULL) 3370 { 3371 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3372 3373 if (dwarf_cu == NULL) 3374 return 0; 3375 3376 if (sc.function) 3377 { 3378 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); 3379 return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true); 3380 } 3381 else if (sc.comp_unit) 3382 { 3383 uint32_t vars_added = 0; 3384 VariableListSP variables (sc.comp_unit->GetVariableList(false)); 3385 3386 if (variables.get() == NULL) 3387 { 3388 variables.reset(new VariableList()); 3389 sc.comp_unit->SetVariableList(variables); 3390 3391 // Index if we already haven't to make sure the compile units 3392 // get indexed and make their global DIE index list 3393 if (!m_indexed) 3394 Index (); 3395 3396 const size_t num_globals = dwarf_cu->GetNumGlobals(); 3397 for (size_t idx=0; idx<num_globals; ++idx) 3398 { 3399 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx))); 3400 if (var_sp) 3401 { 3402 variables->AddVariable(var_sp); 3403 ++vars_added; 3404 } 3405 } 3406 } 3407 return vars_added; 3408 } 3409 } 3410 return 0; 3411 } 3412 3413 3414 VariableSP 3415 SymbolFileDWARF::ParseVariableDIE 3416 ( 3417 const SymbolContext& sc, 3418 const DWARFCompileUnit* dwarf_cu, 3419 const DWARFDebugInfoEntry *die 3420 ) 3421 { 3422 3423 VariableSP var_sp; 3424 3425 const dw_tag_t tag = die->Tag(); 3426 DWARFDebugInfoEntry::Attributes attributes; 3427 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 3428 if (num_attributes > 0) 3429 { 3430 const char *name = NULL; 3431 Declaration decl; 3432 uint32_t i; 3433 TypeSP type_sp; 3434 Type *var_type = NULL; 3435 DWARFExpression location; 3436 bool is_external = false; 3437 bool is_artificial = false; 3438 uint32_t accessibility = clang::AS_none; 3439 3440 for (i=0; i<num_attributes; ++i) 3441 { 3442 dw_attr_t attr = attributes.AttributeAtIndex(i); 3443 DWARFFormValue form_value; 3444 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3445 { 3446 switch (attr) 3447 { 3448 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3449 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3450 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3451 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 3452 case DW_AT_type: var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break; 3453 case DW_AT_external: is_external = form_value.Unsigned() != 0; break; 3454 case DW_AT_location: 3455 { 3456 if (form_value.BlockData()) 3457 { 3458 const DataExtractor& debug_info_data = get_debug_info_data(); 3459 3460 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 3461 uint32_t block_length = form_value.Unsigned(); 3462 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL); 3463 } 3464 else 3465 { 3466 const DataExtractor& debug_loc_data = get_debug_loc_data(); 3467 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 3468 3469 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 3470 if (loc_list_length > 0) 3471 { 3472 Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList()); 3473 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address); 3474 } 3475 } 3476 } 3477 break; 3478 3479 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 3480 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; 3481 case DW_AT_const_value: 3482 case DW_AT_declaration: 3483 case DW_AT_description: 3484 case DW_AT_endianity: 3485 case DW_AT_segment: 3486 case DW_AT_start_scope: 3487 case DW_AT_visibility: 3488 default: 3489 case DW_AT_abstract_origin: 3490 case DW_AT_sibling: 3491 case DW_AT_specification: 3492 break; 3493 } 3494 } 3495 } 3496 3497 if (location.IsValid()) 3498 { 3499 assert(var_type != DIE_IS_BEING_PARSED); 3500 3501 ConstString var_name(name); 3502 3503 ValueType scope = eValueTypeInvalid; 3504 3505 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 3506 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3507 3508 if (tag == DW_TAG_formal_parameter) 3509 scope = eValueTypeVariableArgument; 3510 else if (is_external || parent_tag == DW_TAG_compile_unit) 3511 scope = eValueTypeVariableGlobal; 3512 else 3513 scope = eValueTypeVariableLocal; 3514 3515 SymbolContextScope * symbol_context_scope = NULL; 3516 if (parent_tag == DW_TAG_compile_unit) 3517 { 3518 symbol_context_scope = sc.comp_unit; 3519 } 3520 else if (sc.function != NULL) 3521 { 3522 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset()); 3523 if (symbol_context_scope == NULL) 3524 symbol_context_scope = sc.function; 3525 } 3526 3527 assert(symbol_context_scope != NULL); 3528 var_sp.reset (new Variable(die->GetOffset(), 3529 var_name, 3530 var_type, 3531 scope, 3532 symbol_context_scope, 3533 &decl, 3534 location, 3535 is_external, 3536 is_artificial)); 3537 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get()); 3538 } 3539 } 3540 return var_sp; 3541 } 3542 3543 size_t 3544 SymbolFileDWARF::ParseVariables 3545 ( 3546 const SymbolContext& sc, 3547 const DWARFCompileUnit* dwarf_cu, 3548 const DWARFDebugInfoEntry *orig_die, 3549 bool parse_siblings, 3550 bool parse_children, 3551 VariableList* cc_variable_list 3552 ) 3553 { 3554 if (orig_die == NULL) 3555 return 0; 3556 3557 size_t vars_added = 0; 3558 const DWARFDebugInfoEntry *die = orig_die; 3559 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die); 3560 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3561 VariableListSP variables; 3562 switch (parent_tag) 3563 { 3564 case DW_TAG_compile_unit: 3565 if (sc.comp_unit != NULL) 3566 { 3567 variables = sc.comp_unit->GetVariableList(false); 3568 if (variables.get() == NULL) 3569 { 3570 variables.reset(new VariableList()); 3571 sc.comp_unit->SetVariableList(variables); 3572 } 3573 } 3574 else 3575 { 3576 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context..."); 3577 vars_added = 0; 3578 } 3579 break; 3580 3581 case DW_TAG_subprogram: 3582 case DW_TAG_inlined_subroutine: 3583 case DW_TAG_lexical_block: 3584 if (sc.function != NULL) 3585 { 3586 // Check to see if we already have parsed the variables for the given scope 3587 variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false); 3588 if (variables.get() == NULL) 3589 { 3590 variables.reset(new VariableList()); 3591 sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables); 3592 } 3593 } 3594 else 3595 { 3596 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context..."); 3597 vars_added = 0; 3598 } 3599 break; 3600 3601 default: 3602 assert(!"Didn't find appropriate parent DIE for variable list..."); 3603 break; 3604 } 3605 3606 // We need to have a variable list at this point that we can add variables to 3607 assert(variables.get()); 3608 3609 while (die != NULL) 3610 { 3611 dw_tag_t tag = die->Tag(); 3612 3613 // Check to see if we have already parsed this variable or constant? 3614 if (die->GetUserData() == NULL) 3615 { 3616 // We haven't already parsed it, lets do that now. 3617 if ((tag == DW_TAG_variable) || 3618 (tag == DW_TAG_constant) || 3619 (tag == DW_TAG_formal_parameter && sc.function)) 3620 { 3621 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die)); 3622 if (var_sp) 3623 { 3624 variables->AddVariable(var_sp); 3625 ++vars_added; 3626 } 3627 } 3628 } 3629 3630 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 3631 3632 if (!skip_children && parse_children && die->HasChildren()) 3633 { 3634 vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true); 3635 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children); 3636 } 3637 3638 if (parse_siblings) 3639 die = die->GetSibling(); 3640 else 3641 die = NULL; 3642 } 3643 3644 if (cc_variable_list) 3645 { 3646 cc_variable_list->AddVariables(variables.get()); 3647 } 3648 3649 return vars_added; 3650 } 3651 3652 //------------------------------------------------------------------ 3653 // PluginInterface protocol 3654 //------------------------------------------------------------------ 3655 const char * 3656 SymbolFileDWARF::GetPluginName() 3657 { 3658 return "SymbolFileDWARF"; 3659 } 3660 3661 const char * 3662 SymbolFileDWARF::GetShortPluginName() 3663 { 3664 return GetPluginNameStatic(); 3665 } 3666 3667 uint32_t 3668 SymbolFileDWARF::GetPluginVersion() 3669 { 3670 return 1; 3671 } 3672 3673 void 3674 SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm) 3675 { 3676 } 3677 3678 Error 3679 SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm) 3680 { 3681 Error error; 3682 error.SetErrorString("No plug-in command are currently supported."); 3683 return error; 3684 } 3685 3686 Log * 3687 SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command) 3688 { 3689 return NULL; 3690 } 3691 3692