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