1 //===-- DWARFCompileUnit.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 "DWARFCompileUnit.h" 11 12 #include "lldb/Core/Mangled.h" 13 #include "lldb/Core/Module.h" 14 #include "lldb/Core/Stream.h" 15 #include "lldb/Core/Timer.h" 16 #include "lldb/Symbol/CompileUnit.h" 17 #include "lldb/Symbol/LineTable.h" 18 #include "lldb/Symbol/ObjectFile.h" 19 #include "lldb/Target/ObjCLanguageRuntime.h" 20 21 #include "DWARFDebugAbbrev.h" 22 #include "DWARFDebugAranges.h" 23 #include "DWARFDebugInfo.h" 24 #include "DWARFDIECollection.h" 25 #include "DWARFFormValue.h" 26 #include "LogChannelDWARF.h" 27 #include "NameToDIE.h" 28 #include "SymbolFileDWARF.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 using namespace std; 33 34 35 extern int g_verbose; 36 37 DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) : 38 m_dwarf2Data (dwarf2Data), 39 m_abbrevs (NULL), 40 m_user_data (NULL), 41 m_die_array (), 42 m_func_aranges_ap (), 43 m_base_addr (0), 44 m_offset (DW_INVALID_OFFSET), 45 m_length (0), 46 m_version (0), 47 m_addr_size (DWARFCompileUnit::GetDefaultAddressSize()), 48 m_producer (eProducerInvalid), 49 m_producer_version_major (0), 50 m_producer_version_minor (0), 51 m_producer_version_update (0) 52 { 53 } 54 55 void 56 DWARFCompileUnit::Clear() 57 { 58 m_offset = DW_INVALID_OFFSET; 59 m_length = 0; 60 m_version = 0; 61 m_abbrevs = NULL; 62 m_addr_size = DWARFCompileUnit::GetDefaultAddressSize(); 63 m_base_addr = 0; 64 m_die_array.clear(); 65 m_func_aranges_ap.reset(); 66 m_user_data = NULL; 67 m_producer = eProducerInvalid; 68 } 69 70 bool 71 DWARFCompileUnit::Extract(const DataExtractor &debug_info, lldb::offset_t *offset_ptr) 72 { 73 Clear(); 74 75 m_offset = *offset_ptr; 76 77 if (debug_info.ValidOffset(*offset_ptr)) 78 { 79 dw_offset_t abbr_offset; 80 const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev(); 81 m_length = debug_info.GetU32(offset_ptr); 82 m_version = debug_info.GetU16(offset_ptr); 83 abbr_offset = debug_info.GetU32(offset_ptr); 84 m_addr_size = debug_info.GetU8 (offset_ptr); 85 86 bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); 87 bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); 88 bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); 89 bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); 90 91 if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr != NULL) 92 { 93 m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); 94 return true; 95 } 96 97 // reset the offset to where we tried to parse from if anything went wrong 98 *offset_ptr = m_offset; 99 } 100 101 return false; 102 } 103 104 105 dw_offset_t 106 DWARFCompileUnit::Extract(lldb::offset_t offset, const DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs) 107 { 108 Clear(); 109 110 m_offset = offset; 111 112 if (debug_info_data.ValidOffset(offset)) 113 { 114 m_length = debug_info_data.GetU32(&offset); 115 m_version = debug_info_data.GetU16(&offset); 116 bool abbrevs_OK = debug_info_data.GetU32(&offset) == abbrevs->GetOffset(); 117 m_abbrevs = abbrevs; 118 m_addr_size = debug_info_data.GetU8 (&offset); 119 120 bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); 121 bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); 122 123 if (version_OK && addr_size_OK && abbrevs_OK && debug_info_data.ValidOffset(offset)) 124 return offset; 125 } 126 return DW_INVALID_OFFSET; 127 } 128 129 void 130 DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) 131 { 132 if (m_die_array.size() > 1) 133 { 134 // std::vectors never get any smaller when resized to a smaller size, 135 // or when clear() or erase() are called, the size will report that it 136 // is smaller, but the memory allocated remains intact (call capacity() 137 // to see this). So we need to create a temporary vector and swap the 138 // contents which will cause just the internal pointers to be swapped 139 // so that when "tmp_array" goes out of scope, it will destroy the 140 // contents. 141 142 // Save at least the compile unit DIE 143 DWARFDebugInfoEntry::collection tmp_array; 144 m_die_array.swap(tmp_array); 145 if (keep_compile_unit_die) 146 m_die_array.push_back(tmp_array.front()); 147 } 148 } 149 150 //---------------------------------------------------------------------- 151 // ParseCompileUnitDIEsIfNeeded 152 // 153 // Parses a compile unit and indexes its DIEs if it hasn't already been 154 // done. 155 //---------------------------------------------------------------------- 156 size_t 157 DWARFCompileUnit::ExtractDIEsIfNeeded (bool cu_die_only) 158 { 159 const size_t initial_die_array_size = m_die_array.size(); 160 if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1) 161 return 0; // Already parsed 162 163 Timer scoped_timer (__PRETTY_FUNCTION__, 164 "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )", 165 m_offset, 166 cu_die_only); 167 168 // Set the offset to that of the first DIE and calculate the start of the 169 // next compilation unit header. 170 lldb::offset_t offset = GetFirstDIEOffset(); 171 lldb::offset_t next_cu_offset = GetNextCompileUnitOffset(); 172 173 DWARFDebugInfoEntry die; 174 // Keep a flat array of the DIE for binary lookup by DIE offset 175 if (!cu_die_only) 176 { 177 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_LOOKUPS)); 178 if (log) 179 { 180 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log, 181 "DWARFCompileUnit::ExtractDIEsIfNeeded () for compile unit at .debug_info[0x%8.8x]", 182 GetOffset()); 183 } 184 } 185 186 uint32_t depth = 0; 187 // We are in our compile unit, parse starting at the offset 188 // we were told to parse 189 const DataExtractor& debug_info_data = m_dwarf2Data->get_debug_info_data(); 190 std::vector<uint32_t> die_index_stack; 191 die_index_stack.reserve(32); 192 die_index_stack.push_back(0); 193 bool prev_die_had_children = false; 194 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize()); 195 while (offset < next_cu_offset && 196 die.FastExtract (debug_info_data, this, fixed_form_sizes, &offset)) 197 { 198 // if (log) 199 // log->Printf("0x%8.8x: %*.*s%s%s", 200 // die.GetOffset(), 201 // depth * 2, depth * 2, "", 202 // DW_TAG_value_to_name (die.Tag()), 203 // die.HasChildren() ? " *" : ""); 204 205 const bool null_die = die.IsNULL(); 206 if (depth == 0) 207 { 208 uint64_t base_addr = die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); 209 if (base_addr == LLDB_INVALID_ADDRESS) 210 base_addr = die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_entry_pc, 0); 211 SetBaseAddress (base_addr); 212 if (initial_die_array_size == 0) 213 AddDIE (die); 214 if (cu_die_only) 215 return 1; 216 } 217 else 218 { 219 if (null_die) 220 { 221 if (prev_die_had_children) 222 { 223 // This will only happen if a DIE says is has children 224 // but all it contains is a NULL tag. Since we are removing 225 // the NULL DIEs from the list (saves up to 25% in C++ code), 226 // we need a way to let the DIE know that it actually doesn't 227 // have children. 228 if (!m_die_array.empty()) 229 m_die_array.back().SetEmptyChildren(true); 230 } 231 } 232 else 233 { 234 die.SetParentIndex(m_die_array.size() - die_index_stack[depth-1]); 235 236 if (die_index_stack.back()) 237 m_die_array[die_index_stack.back()].SetSiblingIndex(m_die_array.size()-die_index_stack.back()); 238 239 // Only push the DIE if it isn't a NULL DIE 240 m_die_array.push_back(die); 241 } 242 } 243 244 if (null_die) 245 { 246 // NULL DIE. 247 if (!die_index_stack.empty()) 248 die_index_stack.pop_back(); 249 250 if (depth > 0) 251 --depth; 252 if (depth == 0) 253 break; // We are done with this compile unit! 254 255 prev_die_had_children = false; 256 } 257 else 258 { 259 die_index_stack.back() = m_die_array.size() - 1; 260 // Normal DIE 261 const bool die_has_children = die.HasChildren(); 262 if (die_has_children) 263 { 264 die_index_stack.push_back(0); 265 ++depth; 266 } 267 prev_die_had_children = die_has_children; 268 } 269 } 270 271 // Give a little bit of info if we encounter corrupt DWARF (our offset 272 // should always terminate at or before the start of the next compilation 273 // unit header). 274 if (offset > next_cu_offset) 275 { 276 m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8" PRIx64 "\n", 277 GetOffset(), 278 offset); 279 } 280 281 // Since std::vector objects will double their size, we really need to 282 // make a new array with the perfect size so we don't end up wasting 283 // space. So here we copy and swap to make sure we don't have any extra 284 // memory taken up. 285 286 if (m_die_array.size () < m_die_array.capacity()) 287 { 288 DWARFDebugInfoEntry::collection exact_size_die_array (m_die_array.begin(), m_die_array.end()); 289 exact_size_die_array.swap (m_die_array); 290 } 291 Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_DEBUG_INFO | DWARF_LOG_VERBOSE)); 292 if (log) 293 { 294 StreamString strm; 295 DWARFDebugInfoEntry::DumpDIECollection (strm, m_die_array); 296 log->PutCString (strm.GetString().c_str()); 297 } 298 299 return m_die_array.size(); 300 } 301 302 303 dw_offset_t 304 DWARFCompileUnit::GetAbbrevOffset() const 305 { 306 return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; 307 } 308 309 310 311 bool 312 DWARFCompileUnit::Verify(Stream *s) const 313 { 314 const DataExtractor& debug_info = m_dwarf2Data->get_debug_info_data(); 315 bool valid_offset = debug_info.ValidOffset(m_offset); 316 bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); 317 bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); 318 bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset()); 319 bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); 320 bool verbose = s->GetVerbose(); 321 if (valid_offset && length_OK && version_OK && addr_size_OK && abbr_offset_OK) 322 { 323 if (verbose) 324 s->Printf(" 0x%8.8x: OK\n", m_offset); 325 return true; 326 } 327 else 328 { 329 s->Printf(" 0x%8.8x: ", m_offset); 330 331 m_dwarf2Data->get_debug_info_data().Dump (s, m_offset, lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0, 0); 332 s->EOL(); 333 if (valid_offset) 334 { 335 if (!length_OK) 336 s->Printf(" The length (0x%8.8x) for this compile unit is too large for the .debug_info provided.\n", m_length); 337 if (!version_OK) 338 s->Printf(" The 16 bit compile unit header version is not supported.\n"); 339 if (!abbr_offset_OK) 340 s->Printf(" The offset into the .debug_abbrev section (0x%8.8x) is not valid.\n", GetAbbrevOffset()); 341 if (!addr_size_OK) 342 s->Printf(" The address size is unsupported: 0x%2.2x\n", m_addr_size); 343 } 344 else 345 s->Printf(" The start offset of the compile unit header in the .debug_info is invalid.\n"); 346 } 347 return false; 348 } 349 350 351 void 352 DWARFCompileUnit::Dump(Stream *s) const 353 { 354 s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at {0x%8.8x})\n", 355 m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, GetNextCompileUnitOffset()); 356 } 357 358 359 static uint8_t g_default_addr_size = 4; 360 361 uint8_t 362 DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit* cu) 363 { 364 if (cu) 365 return cu->GetAddressByteSize(); 366 return DWARFCompileUnit::GetDefaultAddressSize(); 367 } 368 369 uint8_t 370 DWARFCompileUnit::GetDefaultAddressSize() 371 { 372 return g_default_addr_size; 373 } 374 375 void 376 DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) 377 { 378 g_default_addr_size = addr_size; 379 } 380 381 void 382 DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, 383 DWARFDebugAranges* debug_aranges, 384 bool clear_dies_if_already_not_parsed) 385 { 386 // This function is usually called if there in no .debug_aranges section 387 // in order to produce a compile unit level set of address ranges that 388 // is accurate. If the DIEs weren't parsed, then we don't want all dies for 389 // all compile units to stay loaded when they weren't needed. So we can end 390 // up parsing the DWARF and then throwing them all away to keep memory usage 391 // down. 392 const bool clear_dies = ExtractDIEsIfNeeded (false) > 1; 393 394 const DWARFDebugInfoEntry* die = DIE(); 395 if (die) 396 die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges); 397 398 if (debug_aranges->IsEmpty()) 399 { 400 // We got nothing from the functions, maybe we have a line tables only 401 // situation. Check the line tables and build the arange table from this. 402 SymbolContext sc; 403 sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); 404 if (sc.comp_unit) 405 { 406 LineTable *line_table = sc.comp_unit->GetLineTable(); 407 408 if (line_table) 409 { 410 LineTable::FileAddressRanges file_ranges; 411 const bool append = true; 412 const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append); 413 for (uint32_t idx=0; idx<num_ranges; ++idx) 414 { 415 const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); 416 debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); 417 printf ("0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); 418 } 419 } 420 } 421 } 422 423 // Keep memory down by clearing DIEs if this generate function 424 // caused them to be parsed 425 if (clear_dies) 426 ClearDIEs (true); 427 428 } 429 430 431 const DWARFDebugAranges & 432 DWARFCompileUnit::GetFunctionAranges () 433 { 434 if (m_func_aranges_ap.get() == NULL) 435 { 436 m_func_aranges_ap.reset (new DWARFDebugAranges()); 437 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); 438 439 if (log) 440 { 441 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log, 442 "DWARFCompileUnit::GetFunctionAranges() for compile unit at .debug_info[0x%8.8x]", 443 GetOffset()); 444 } 445 const DWARFDebugInfoEntry* die = DIE(); 446 if (die) 447 die->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get()); 448 const bool minimize = false; 449 m_func_aranges_ap->Sort(minimize); 450 } 451 return *m_func_aranges_ap.get(); 452 } 453 454 bool 455 DWARFCompileUnit::LookupAddress 456 ( 457 const dw_addr_t address, 458 DWARFDebugInfoEntry** function_die_handle, 459 DWARFDebugInfoEntry** block_die_handle 460 ) 461 { 462 bool success = false; 463 464 if (function_die_handle != NULL && DIE()) 465 { 466 467 const DWARFDebugAranges &func_aranges = GetFunctionAranges (); 468 469 // Re-check the aranges auto pointer contents in case it was created above 470 if (!func_aranges.IsEmpty()) 471 { 472 *function_die_handle = GetDIEPtr(func_aranges.FindAddress(address)); 473 if (*function_die_handle != NULL) 474 { 475 success = true; 476 if (block_die_handle != NULL) 477 { 478 DWARFDebugInfoEntry* child = (*function_die_handle)->GetFirstChild(); 479 while (child) 480 { 481 if (child->LookupAddress(address, m_dwarf2Data, this, NULL, block_die_handle)) 482 break; 483 child = child->GetSibling(); 484 } 485 } 486 } 487 } 488 } 489 return success; 490 } 491 492 //---------------------------------------------------------------------- 493 // Compare function DWARFDebugAranges::Range structures 494 //---------------------------------------------------------------------- 495 static bool CompareDIEOffset (const DWARFDebugInfoEntry& die1, const DWARFDebugInfoEntry& die2) 496 { 497 return die1.GetOffset() < die2.GetOffset(); 498 } 499 500 //---------------------------------------------------------------------- 501 // GetDIEPtr() 502 // 503 // Get the DIE (Debug Information Entry) with the specified offset. 504 //---------------------------------------------------------------------- 505 DWARFDebugInfoEntry* 506 DWARFCompileUnit::GetDIEPtr(dw_offset_t die_offset) 507 { 508 if (die_offset != DW_INVALID_OFFSET) 509 { 510 ExtractDIEsIfNeeded (false); 511 DWARFDebugInfoEntry compare_die; 512 compare_die.SetOffset(die_offset); 513 DWARFDebugInfoEntry::iterator end = m_die_array.end(); 514 DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset); 515 if (pos != end) 516 { 517 if (die_offset == (*pos).GetOffset()) 518 return &(*pos); 519 } 520 } 521 return NULL; // Not found in any compile units 522 } 523 524 //---------------------------------------------------------------------- 525 // GetDIEPtrContainingOffset() 526 // 527 // Get the DIE (Debug Information Entry) that contains the specified 528 // .debug_info offset. 529 //---------------------------------------------------------------------- 530 const DWARFDebugInfoEntry* 531 DWARFCompileUnit::GetDIEPtrContainingOffset(dw_offset_t die_offset) 532 { 533 if (die_offset != DW_INVALID_OFFSET) 534 { 535 ExtractDIEsIfNeeded (false); 536 DWARFDebugInfoEntry compare_die; 537 compare_die.SetOffset(die_offset); 538 DWARFDebugInfoEntry::iterator end = m_die_array.end(); 539 DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset); 540 if (pos != end) 541 { 542 if (die_offset >= (*pos).GetOffset()) 543 { 544 DWARFDebugInfoEntry::iterator next = pos + 1; 545 if (next != end) 546 { 547 if (die_offset < (*next).GetOffset()) 548 return &(*pos); 549 } 550 } 551 } 552 } 553 return NULL; // Not found in any compile units 554 } 555 556 557 558 size_t 559 DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const 560 { 561 size_t old_size = dies.Size(); 562 DWARFDebugInfoEntry::const_iterator pos; 563 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 564 for (pos = m_die_array.begin(); pos != end; ++pos) 565 { 566 if (pos->Tag() == tag) 567 dies.Append (&(*pos)); 568 } 569 570 // Return the number of DIEs added to the collection 571 return dies.Size() - old_size; 572 } 573 574 //void 575 //DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx) 576 //{ 577 // m_global_die_indexes.push_back (die_idx); 578 //} 579 // 580 // 581 //void 582 //DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die) 583 //{ 584 // // Indexes to all file level global and static variables 585 // m_global_die_indexes; 586 // 587 // if (m_die_array.empty()) 588 // return; 589 // 590 // const DWARFDebugInfoEntry* first_die = &m_die_array[0]; 591 // const DWARFDebugInfoEntry* end = first_die + m_die_array.size(); 592 // if (first_die <= die && die < end) 593 // m_global_die_indexes.push_back (die - first_die); 594 //} 595 596 597 void 598 DWARFCompileUnit::Index (const uint32_t cu_idx, 599 NameToDIE& func_basenames, 600 NameToDIE& func_fullnames, 601 NameToDIE& func_methods, 602 NameToDIE& func_selectors, 603 NameToDIE& objc_class_selectors, 604 NameToDIE& globals, 605 NameToDIE& types, 606 NameToDIE& namespaces) 607 { 608 const DataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data(); 609 610 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize()); 611 612 Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS)); 613 614 if (log) 615 { 616 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log, 617 "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]", 618 GetOffset()); 619 } 620 621 DWARFDebugInfoEntry::const_iterator pos; 622 DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin(); 623 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 624 for (pos = begin; pos != end; ++pos) 625 { 626 const DWARFDebugInfoEntry &die = *pos; 627 628 const dw_tag_t tag = die.Tag(); 629 630 switch (tag) 631 { 632 case DW_TAG_subprogram: 633 case DW_TAG_inlined_subroutine: 634 case DW_TAG_base_type: 635 case DW_TAG_class_type: 636 case DW_TAG_constant: 637 case DW_TAG_enumeration_type: 638 case DW_TAG_string_type: 639 case DW_TAG_subroutine_type: 640 case DW_TAG_structure_type: 641 case DW_TAG_union_type: 642 case DW_TAG_typedef: 643 case DW_TAG_namespace: 644 case DW_TAG_variable: 645 case DW_TAG_unspecified_type: 646 break; 647 648 default: 649 continue; 650 } 651 652 DWARFDebugInfoEntry::Attributes attributes; 653 const char *name = NULL; 654 const char *mangled_cstr = NULL; 655 bool is_declaration = false; 656 //bool is_artificial = false; 657 bool has_address = false; 658 bool has_location = false; 659 bool is_global_or_static_variable = false; 660 661 dw_offset_t specification_die_offset = DW_INVALID_OFFSET; 662 const size_t num_attributes = die.GetAttributes(m_dwarf2Data, this, fixed_form_sizes, attributes); 663 if (num_attributes > 0) 664 { 665 for (uint32_t i=0; i<num_attributes; ++i) 666 { 667 dw_attr_t attr = attributes.AttributeAtIndex(i); 668 DWARFFormValue form_value; 669 switch (attr) 670 { 671 case DW_AT_name: 672 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 673 name = form_value.AsCString(debug_str); 674 break; 675 676 case DW_AT_declaration: 677 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 678 is_declaration = form_value.Unsigned() != 0; 679 break; 680 681 // case DW_AT_artificial: 682 // if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 683 // is_artificial = form_value.Unsigned() != 0; 684 // break; 685 686 case DW_AT_MIPS_linkage_name: 687 case DW_AT_linkage_name: 688 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 689 mangled_cstr = form_value.AsCString(debug_str); 690 break; 691 692 case DW_AT_low_pc: 693 case DW_AT_high_pc: 694 case DW_AT_ranges: 695 has_address = true; 696 break; 697 698 case DW_AT_entry_pc: 699 has_address = true; 700 break; 701 702 case DW_AT_location: 703 has_location = true; 704 if (tag == DW_TAG_variable) 705 { 706 const DWARFDebugInfoEntry* parent_die = die.GetParent(); 707 while ( parent_die != NULL ) 708 { 709 switch (parent_die->Tag()) 710 { 711 case DW_TAG_subprogram: 712 case DW_TAG_lexical_block: 713 case DW_TAG_inlined_subroutine: 714 // Even if this is a function level static, we don't add it. We could theoretically 715 // add these if we wanted to by introspecting into the DW_AT_location and seeing 716 // if the location describes a hard coded address, but we dont want the performance 717 // penalty of that right now. 718 is_global_or_static_variable = false; 719 // if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value)) 720 // { 721 // // If we have valid block data, then we have location expression bytes 722 // // that are fixed (not a location list). 723 // const uint8_t *block_data = form_value.BlockData(); 724 // if (block_data) 725 // { 726 // uint32_t block_length = form_value.Unsigned(); 727 // if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) 728 // { 729 // if (block_data[0] == DW_OP_addr) 730 // add_die = true; 731 // } 732 // } 733 // } 734 parent_die = NULL; // Terminate the while loop. 735 break; 736 737 case DW_TAG_compile_unit: 738 is_global_or_static_variable = true; 739 parent_die = NULL; // Terminate the while loop. 740 break; 741 742 default: 743 parent_die = parent_die->GetParent(); // Keep going in the while loop. 744 break; 745 } 746 } 747 } 748 break; 749 750 case DW_AT_specification: 751 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 752 specification_die_offset = form_value.Reference(this); 753 break; 754 } 755 } 756 } 757 758 switch (tag) 759 { 760 case DW_TAG_subprogram: 761 if (has_address) 762 { 763 if (name) 764 { 765 // Note, this check is also done in ParseMethodName, but since this is a hot loop, we do the 766 // simple inlined check outside the call. 767 ObjCLanguageRuntime::MethodName objc_method(name, true); 768 if (objc_method.IsValid(true)) 769 { 770 ConstString objc_class_name_with_category (objc_method.GetClassNameWithCategory()); 771 ConstString objc_selector_name (objc_method.GetSelector()); 772 ConstString objc_fullname_no_category_name (objc_method.GetFullNameWithoutCategory(true)); 773 ConstString objc_class_name_no_category (objc_method.GetClassName()); 774 func_fullnames.Insert (ConstString(name), die.GetOffset()); 775 if (objc_class_name_with_category) 776 objc_class_selectors.Insert(objc_class_name_with_category, die.GetOffset()); 777 if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category) 778 objc_class_selectors.Insert(objc_class_name_no_category, die.GetOffset()); 779 if (objc_selector_name) 780 func_selectors.Insert (objc_selector_name, die.GetOffset()); 781 if (objc_fullname_no_category_name) 782 func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset()); 783 } 784 // If we have a mangled name, then the DW_AT_name attribute 785 // is usually the method name without the class or any parameters 786 const DWARFDebugInfoEntry *parent = die.GetParent(); 787 bool is_method = false; 788 if (parent) 789 { 790 dw_tag_t parent_tag = parent->Tag(); 791 if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type) 792 { 793 is_method = true; 794 } 795 else 796 { 797 if (specification_die_offset != DW_INVALID_OFFSET) 798 { 799 const DWARFDebugInfoEntry *specification_die = m_dwarf2Data->DebugInfo()->GetDIEPtr (specification_die_offset, NULL); 800 if (specification_die) 801 { 802 parent = specification_die->GetParent(); 803 if (parent) 804 { 805 parent_tag = parent->Tag(); 806 807 if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type) 808 is_method = true; 809 } 810 } 811 } 812 } 813 } 814 815 816 if (is_method) 817 func_methods.Insert (ConstString(name), die.GetOffset()); 818 else 819 func_basenames.Insert (ConstString(name), die.GetOffset()); 820 821 if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) 822 func_fullnames.Insert (ConstString(name), die.GetOffset()); 823 } 824 if (mangled_cstr) 825 { 826 // Make sure our mangled name isn't the same string table entry 827 // as our name. If it starts with '_', then it is ok, else compare 828 // the string to make sure it isn't the same and we don't end up 829 // with duplicate entries 830 if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (name && ::strcmp(name, mangled_cstr) != 0))) 831 { 832 Mangled mangled (ConstString(mangled_cstr), true); 833 func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); 834 if (mangled.GetDemangledName()) 835 func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); 836 } 837 } 838 } 839 break; 840 841 case DW_TAG_inlined_subroutine: 842 if (has_address) 843 { 844 if (name) 845 func_basenames.Insert (ConstString(name), die.GetOffset()); 846 if (mangled_cstr) 847 { 848 // Make sure our mangled name isn't the same string table entry 849 // as our name. If it starts with '_', then it is ok, else compare 850 // the string to make sure it isn't the same and we don't end up 851 // with duplicate entries 852 if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 853 { 854 Mangled mangled (ConstString(mangled_cstr), true); 855 func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); 856 if (mangled.GetDemangledName()) 857 func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); 858 } 859 } 860 else 861 func_fullnames.Insert (ConstString(name), die.GetOffset()); 862 } 863 break; 864 865 case DW_TAG_base_type: 866 case DW_TAG_class_type: 867 case DW_TAG_constant: 868 case DW_TAG_enumeration_type: 869 case DW_TAG_string_type: 870 case DW_TAG_subroutine_type: 871 case DW_TAG_structure_type: 872 case DW_TAG_union_type: 873 case DW_TAG_typedef: 874 case DW_TAG_unspecified_type: 875 if (name && is_declaration == false) 876 { 877 types.Insert (ConstString(name), die.GetOffset()); 878 } 879 break; 880 881 case DW_TAG_namespace: 882 if (name) 883 namespaces.Insert (ConstString(name), die.GetOffset()); 884 break; 885 886 case DW_TAG_variable: 887 if (name && has_location && is_global_or_static_variable) 888 { 889 globals.Insert (ConstString(name), die.GetOffset()); 890 // Be sure to include variables by their mangled and demangled 891 // names if they have any since a variable can have a basename 892 // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled 893 // mangled name "(anonymous namespace)::i"... 894 895 // Make sure our mangled name isn't the same string table entry 896 // as our name. If it starts with '_', then it is ok, else compare 897 // the string to make sure it isn't the same and we don't end up 898 // with duplicate entries 899 if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 900 { 901 Mangled mangled (ConstString(mangled_cstr), true); 902 globals.Insert (mangled.GetMangledName(), die.GetOffset()); 903 if (mangled.GetDemangledName()) 904 globals.Insert (mangled.GetDemangledName(), die.GetOffset()); 905 } 906 } 907 break; 908 909 default: 910 continue; 911 } 912 } 913 } 914 915 bool 916 DWARFCompileUnit::Supports_unnamed_objc_bitfields () 917 { 918 if (GetProducer() == eProducerClang) 919 { 920 const uint32_t major_version = GetProducerVersionMajor(); 921 if (major_version > 425 || (major_version == 425 && GetProducerVersionUpdate() >= 13)) 922 return true; 923 else 924 return false; 925 } 926 return true; // Assume all other compilers didn't have incorrect ObjC bitfield info 927 } 928 929 bool 930 DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type () 931 { 932 if (GetProducer() == eProducerLLVMGCC) 933 return false; 934 return true; 935 } 936 937 bool 938 DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() 939 { 940 // llvm-gcc makes completely invalid decl file attributes and won't ever 941 // be fixed, so we need to know to ignore these. 942 return GetProducer() == eProducerLLVMGCC; 943 } 944 945 void 946 DWARFCompileUnit::ParseProducerInfo () 947 { 948 m_producer_version_major = UINT32_MAX; 949 m_producer_version_minor = UINT32_MAX; 950 m_producer_version_update = UINT32_MAX; 951 952 const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly(); 953 if (die) 954 { 955 956 const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL); 957 if (producer_cstr) 958 { 959 RegularExpression llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$"); 960 if (llvm_gcc_regex.Execute (producer_cstr)) 961 { 962 m_producer = eProducerLLVMGCC; 963 } 964 else if (strstr(producer_cstr, "clang")) 965 { 966 static RegularExpression g_clang_version_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"); 967 RegularExpression::Match regex_match(3); 968 if (g_clang_version_regex.Execute (producer_cstr, ®ex_match)) 969 { 970 std::string str; 971 if (regex_match.GetMatchAtIndex (producer_cstr, 1, str)) 972 m_producer_version_major = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10); 973 if (regex_match.GetMatchAtIndex (producer_cstr, 2, str)) 974 m_producer_version_minor = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10); 975 if (regex_match.GetMatchAtIndex (producer_cstr, 3, str)) 976 m_producer_version_update = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10); 977 } 978 m_producer = eProducerClang; 979 } 980 else if (strstr(producer_cstr, "GNU")) 981 m_producer = eProducerGCC; 982 } 983 } 984 if (m_producer == eProducerInvalid) 985 m_producer = eProcucerOther; 986 } 987 988 DWARFCompileUnit::Producer 989 DWARFCompileUnit::GetProducer () 990 { 991 if (m_producer == eProducerInvalid) 992 ParseProducerInfo (); 993 return m_producer; 994 } 995 996 997 uint32_t 998 DWARFCompileUnit::GetProducerVersionMajor() 999 { 1000 if (m_producer_version_major == 0) 1001 ParseProducerInfo (); 1002 return m_producer_version_major; 1003 } 1004 1005 uint32_t 1006 DWARFCompileUnit::GetProducerVersionMinor() 1007 { 1008 if (m_producer_version_minor == 0) 1009 ParseProducerInfo (); 1010 return m_producer_version_minor; 1011 } 1012 1013 uint32_t 1014 DWARFCompileUnit::GetProducerVersionUpdate() 1015 { 1016 if (m_producer_version_update == 0) 1017 ParseProducerInfo (); 1018 return m_producer_version_update; 1019 } 1020 1021