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 if (debug_aranges->IsEmpty()) 450 { 451 // We got nothing from the functions, maybe we have a line tables only 452 // situation. Check the line tables and build the arange table from this. 453 SymbolContext sc; 454 sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); 455 if (sc.comp_unit) 456 { 457 LineTable *line_table = sc.comp_unit->GetLineTable(); 458 459 if (line_table) 460 { 461 LineTable::FileAddressRanges file_ranges; 462 const bool append = true; 463 const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append); 464 for (uint32_t idx=0; idx<num_ranges; ++idx) 465 { 466 const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); 467 debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); 468 printf ("0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); 469 } 470 } 471 } 472 } 473 474 // Keep memory down by clearing DIEs if this generate function 475 // caused them to be parsed 476 if (clear_dies) 477 ClearDIEs (true); 478 479 } 480 481 482 const DWARFDebugAranges & 483 DWARFCompileUnit::GetFunctionAranges () 484 { 485 if (m_func_aranges_ap.get() == NULL) 486 { 487 m_func_aranges_ap.reset (new DWARFDebugAranges()); 488 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); 489 490 if (log) 491 { 492 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log, 493 "DWARFCompileUnit::GetFunctionAranges() for compile unit at .debug_info[0x%8.8x]", 494 GetOffset()); 495 } 496 const DWARFDebugInfoEntry* die = DIE(); 497 if (die) 498 die->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get()); 499 const bool minimize = false; 500 m_func_aranges_ap->Sort(minimize); 501 } 502 return *m_func_aranges_ap.get(); 503 } 504 505 bool 506 DWARFCompileUnit::LookupAddress 507 ( 508 const dw_addr_t address, 509 DWARFDebugInfoEntry** function_die_handle, 510 DWARFDebugInfoEntry** block_die_handle 511 ) 512 { 513 bool success = false; 514 515 if (function_die_handle != NULL && DIE()) 516 { 517 518 const DWARFDebugAranges &func_aranges = GetFunctionAranges (); 519 520 // Re-check the aranges auto pointer contents in case it was created above 521 if (!func_aranges.IsEmpty()) 522 { 523 *function_die_handle = GetDIEPtr(func_aranges.FindAddress(address)); 524 if (*function_die_handle != NULL) 525 { 526 success = true; 527 if (block_die_handle != NULL) 528 { 529 DWARFDebugInfoEntry* child = (*function_die_handle)->GetFirstChild(); 530 while (child) 531 { 532 if (child->LookupAddress(address, m_dwarf2Data, this, NULL, block_die_handle)) 533 break; 534 child = child->GetSibling(); 535 } 536 } 537 } 538 } 539 } 540 return success; 541 } 542 543 //---------------------------------------------------------------------- 544 // Compare function DWARFDebugAranges::Range structures 545 //---------------------------------------------------------------------- 546 static bool CompareDIEOffset (const DWARFDebugInfoEntry& die1, const DWARFDebugInfoEntry& die2) 547 { 548 return die1.GetOffset() < die2.GetOffset(); 549 } 550 551 //---------------------------------------------------------------------- 552 // GetDIEPtr() 553 // 554 // Get the DIE (Debug Information Entry) with the specified offset. 555 //---------------------------------------------------------------------- 556 DWARFDebugInfoEntry* 557 DWARFCompileUnit::GetDIEPtr(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 return &(*pos); 570 } 571 } 572 return NULL; // Not found in any compile units 573 } 574 575 //---------------------------------------------------------------------- 576 // GetDIEPtrContainingOffset() 577 // 578 // Get the DIE (Debug Information Entry) that contains the specified 579 // .debug_info offset. 580 //---------------------------------------------------------------------- 581 const DWARFDebugInfoEntry* 582 DWARFCompileUnit::GetDIEPtrContainingOffset(dw_offset_t die_offset) 583 { 584 if (die_offset != DW_INVALID_OFFSET) 585 { 586 ExtractDIEsIfNeeded (false); 587 DWARFDebugInfoEntry compare_die; 588 compare_die.SetOffset(die_offset); 589 DWARFDebugInfoEntry::iterator end = m_die_array.end(); 590 DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset); 591 if (pos != end) 592 { 593 if (die_offset >= (*pos).GetOffset()) 594 { 595 DWARFDebugInfoEntry::iterator next = pos + 1; 596 if (next != end) 597 { 598 if (die_offset < (*next).GetOffset()) 599 return &(*pos); 600 } 601 } 602 } 603 } 604 return NULL; // Not found in any compile units 605 } 606 607 608 609 size_t 610 DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const 611 { 612 size_t old_size = dies.Size(); 613 DWARFDebugInfoEntry::const_iterator pos; 614 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 615 for (pos = m_die_array.begin(); pos != end; ++pos) 616 { 617 if (pos->Tag() == tag) 618 dies.Append (&(*pos)); 619 } 620 621 // Return the number of DIEs added to the collection 622 return dies.Size() - old_size; 623 } 624 625 //void 626 //DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx) 627 //{ 628 // m_global_die_indexes.push_back (die_idx); 629 //} 630 // 631 // 632 //void 633 //DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die) 634 //{ 635 // // Indexes to all file level global and static variables 636 // m_global_die_indexes; 637 // 638 // if (m_die_array.empty()) 639 // return; 640 // 641 // const DWARFDebugInfoEntry* first_die = &m_die_array[0]; 642 // const DWARFDebugInfoEntry* end = first_die + m_die_array.size(); 643 // if (first_die <= die && die < end) 644 // m_global_die_indexes.push_back (die - first_die); 645 //} 646 647 648 void 649 DWARFCompileUnit::Index (const uint32_t cu_idx, 650 NameToDIE& func_basenames, 651 NameToDIE& func_fullnames, 652 NameToDIE& func_methods, 653 NameToDIE& func_selectors, 654 NameToDIE& objc_class_selectors, 655 NameToDIE& globals, 656 NameToDIE& types, 657 NameToDIE& namespaces) 658 { 659 const DWARFDataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data(); 660 661 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); 662 663 Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS)); 664 665 if (log) 666 { 667 m_dwarf2Data->GetObjectFile()->GetModule()->LogMessage (log, 668 "DWARFCompileUnit::Index() for compile unit at .debug_info[0x%8.8x]", 669 GetOffset()); 670 } 671 672 const LanguageType cu_language = GetLanguageType(); 673 DWARFDebugInfoEntry::const_iterator pos; 674 DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin(); 675 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 676 for (pos = begin; pos != end; ++pos) 677 { 678 const DWARFDebugInfoEntry &die = *pos; 679 680 const dw_tag_t tag = die.Tag(); 681 682 switch (tag) 683 { 684 case DW_TAG_subprogram: 685 case DW_TAG_inlined_subroutine: 686 case DW_TAG_base_type: 687 case DW_TAG_class_type: 688 case DW_TAG_constant: 689 case DW_TAG_enumeration_type: 690 case DW_TAG_string_type: 691 case DW_TAG_subroutine_type: 692 case DW_TAG_structure_type: 693 case DW_TAG_union_type: 694 case DW_TAG_typedef: 695 case DW_TAG_namespace: 696 case DW_TAG_variable: 697 case DW_TAG_unspecified_type: 698 break; 699 700 default: 701 continue; 702 } 703 704 DWARFDebugInfoEntry::Attributes attributes; 705 const char *name = NULL; 706 const char *mangled_cstr = NULL; 707 bool is_declaration = false; 708 //bool is_artificial = false; 709 bool has_address = false; 710 bool has_location = false; 711 bool is_global_or_static_variable = false; 712 713 dw_offset_t specification_die_offset = DW_INVALID_OFFSET; 714 const size_t num_attributes = die.GetAttributes(m_dwarf2Data, this, fixed_form_sizes, attributes); 715 if (num_attributes > 0) 716 { 717 for (uint32_t i=0; i<num_attributes; ++i) 718 { 719 dw_attr_t attr = attributes.AttributeAtIndex(i); 720 DWARFFormValue form_value; 721 switch (attr) 722 { 723 case DW_AT_name: 724 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 725 name = form_value.AsCString(debug_str); 726 break; 727 728 case DW_AT_declaration: 729 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 730 is_declaration = form_value.Unsigned() != 0; 731 break; 732 733 // case DW_AT_artificial: 734 // if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 735 // is_artificial = form_value.Unsigned() != 0; 736 // break; 737 738 case DW_AT_MIPS_linkage_name: 739 case DW_AT_linkage_name: 740 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 741 mangled_cstr = form_value.AsCString(debug_str); 742 break; 743 744 case DW_AT_low_pc: 745 case DW_AT_high_pc: 746 case DW_AT_ranges: 747 has_address = true; 748 break; 749 750 case DW_AT_entry_pc: 751 has_address = true; 752 break; 753 754 case DW_AT_location: 755 has_location = true; 756 if (tag == DW_TAG_variable) 757 { 758 const DWARFDebugInfoEntry* parent_die = die.GetParent(); 759 while ( parent_die != NULL ) 760 { 761 switch (parent_die->Tag()) 762 { 763 case DW_TAG_subprogram: 764 case DW_TAG_lexical_block: 765 case DW_TAG_inlined_subroutine: 766 // Even if this is a function level static, we don't add it. We could theoretically 767 // add these if we wanted to by introspecting into the DW_AT_location and seeing 768 // if the location describes a hard coded address, but we dont want the performance 769 // penalty of that right now. 770 is_global_or_static_variable = false; 771 // if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value)) 772 // { 773 // // If we have valid block data, then we have location expression bytes 774 // // that are fixed (not a location list). 775 // const uint8_t *block_data = form_value.BlockData(); 776 // if (block_data) 777 // { 778 // uint32_t block_length = form_value.Unsigned(); 779 // if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize()) 780 // { 781 // if (block_data[0] == DW_OP_addr) 782 // add_die = true; 783 // } 784 // } 785 // } 786 parent_die = NULL; // Terminate the while loop. 787 break; 788 789 case DW_TAG_compile_unit: 790 is_global_or_static_variable = true; 791 parent_die = NULL; // Terminate the while loop. 792 break; 793 794 default: 795 parent_die = parent_die->GetParent(); // Keep going in the while loop. 796 break; 797 } 798 } 799 } 800 break; 801 802 case DW_AT_specification: 803 if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) 804 specification_die_offset = form_value.Reference(); 805 break; 806 } 807 } 808 } 809 810 switch (tag) 811 { 812 case DW_TAG_subprogram: 813 if (has_address) 814 { 815 if (name) 816 { 817 // Note, this check is also done in ParseMethodName, but since this is a hot loop, we do the 818 // simple inlined check outside the call. 819 ObjCLanguageRuntime::MethodName objc_method(name, true); 820 if (objc_method.IsValid(true)) 821 { 822 ConstString objc_class_name_with_category (objc_method.GetClassNameWithCategory()); 823 ConstString objc_selector_name (objc_method.GetSelector()); 824 ConstString objc_fullname_no_category_name (objc_method.GetFullNameWithoutCategory(true)); 825 ConstString objc_class_name_no_category (objc_method.GetClassName()); 826 func_fullnames.Insert (ConstString(name), die.GetOffset()); 827 if (objc_class_name_with_category) 828 objc_class_selectors.Insert(objc_class_name_with_category, die.GetOffset()); 829 if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category) 830 objc_class_selectors.Insert(objc_class_name_no_category, die.GetOffset()); 831 if (objc_selector_name) 832 func_selectors.Insert (objc_selector_name, die.GetOffset()); 833 if (objc_fullname_no_category_name) 834 func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset()); 835 } 836 // If we have a mangled name, then the DW_AT_name attribute 837 // is usually the method name without the class or any parameters 838 const DWARFDebugInfoEntry *parent = die.GetParent(); 839 bool is_method = false; 840 if (parent) 841 { 842 dw_tag_t parent_tag = parent->Tag(); 843 if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type) 844 { 845 is_method = true; 846 } 847 else 848 { 849 if (specification_die_offset != DW_INVALID_OFFSET) 850 { 851 const DWARFDebugInfoEntry *specification_die = m_dwarf2Data->DebugInfo()->GetDIEPtr (specification_die_offset, NULL); 852 if (specification_die) 853 { 854 parent = specification_die->GetParent(); 855 if (parent) 856 { 857 parent_tag = parent->Tag(); 858 859 if (parent_tag == DW_TAG_class_type || parent_tag == DW_TAG_structure_type) 860 is_method = true; 861 } 862 } 863 } 864 } 865 } 866 867 868 if (is_method) 869 func_methods.Insert (ConstString(name), die.GetOffset()); 870 else 871 func_basenames.Insert (ConstString(name), die.GetOffset()); 872 873 if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) 874 func_fullnames.Insert (ConstString(name), die.GetOffset()); 875 } 876 if (mangled_cstr) 877 { 878 // Make sure our mangled name isn't the same string table entry 879 // as our name. If it starts with '_', then it is ok, else compare 880 // the string to make sure it isn't the same and we don't end up 881 // with duplicate entries 882 if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (name && ::strcmp(name, mangled_cstr) != 0))) 883 { 884 Mangled mangled (ConstString(mangled_cstr), true); 885 func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); 886 ConstString demangled = mangled.GetDemangledName(cu_language); 887 if (demangled) 888 func_fullnames.Insert (demangled, die.GetOffset()); 889 } 890 } 891 } 892 break; 893 894 case DW_TAG_inlined_subroutine: 895 if (has_address) 896 { 897 if (name) 898 func_basenames.Insert (ConstString(name), die.GetOffset()); 899 if (mangled_cstr) 900 { 901 // Make sure our mangled name isn't the same string table entry 902 // as our name. If it starts with '_', then it is ok, else compare 903 // the string to make sure it isn't the same and we don't end up 904 // with duplicate entries 905 if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 906 { 907 Mangled mangled (ConstString(mangled_cstr), true); 908 func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); 909 ConstString demangled = mangled.GetDemangledName(cu_language); 910 if (demangled) 911 func_fullnames.Insert (demangled, die.GetOffset()); 912 } 913 } 914 else 915 func_fullnames.Insert (ConstString(name), die.GetOffset()); 916 } 917 break; 918 919 case DW_TAG_base_type: 920 case DW_TAG_class_type: 921 case DW_TAG_constant: 922 case DW_TAG_enumeration_type: 923 case DW_TAG_string_type: 924 case DW_TAG_subroutine_type: 925 case DW_TAG_structure_type: 926 case DW_TAG_union_type: 927 case DW_TAG_typedef: 928 case DW_TAG_unspecified_type: 929 if (name && is_declaration == false) 930 { 931 types.Insert (ConstString(name), die.GetOffset()); 932 } 933 break; 934 935 case DW_TAG_namespace: 936 if (name) 937 namespaces.Insert (ConstString(name), die.GetOffset()); 938 break; 939 940 case DW_TAG_variable: 941 if (name && has_location && is_global_or_static_variable) 942 { 943 globals.Insert (ConstString(name), die.GetOffset()); 944 // Be sure to include variables by their mangled and demangled 945 // names if they have any since a variable can have a basename 946 // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled 947 // mangled name "(anonymous namespace)::i"... 948 949 // Make sure our mangled name isn't the same string table entry 950 // as our name. If it starts with '_', then it is ok, else compare 951 // the string to make sure it isn't the same and we don't end up 952 // with duplicate entries 953 if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) 954 { 955 Mangled mangled (ConstString(mangled_cstr), true); 956 globals.Insert (mangled.GetMangledName(), die.GetOffset()); 957 ConstString demangled = mangled.GetDemangledName(cu_language); 958 if (demangled) 959 globals.Insert (demangled, die.GetOffset()); 960 } 961 } 962 break; 963 964 default: 965 continue; 966 } 967 } 968 } 969 970 bool 971 DWARFCompileUnit::Supports_unnamed_objc_bitfields () 972 { 973 if (GetProducer() == eProducerClang) 974 { 975 const uint32_t major_version = GetProducerVersionMajor(); 976 if (major_version > 425 || (major_version == 425 && GetProducerVersionUpdate() >= 13)) 977 return true; 978 else 979 return false; 980 } 981 return true; // Assume all other compilers didn't have incorrect ObjC bitfield info 982 } 983 984 bool 985 DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type () 986 { 987 if (GetProducer() == eProducerLLVMGCC) 988 return false; 989 return true; 990 } 991 992 bool 993 DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() 994 { 995 // llvm-gcc makes completely invalid decl file attributes and won't ever 996 // be fixed, so we need to know to ignore these. 997 return GetProducer() == eProducerLLVMGCC; 998 } 999 1000 void 1001 DWARFCompileUnit::ParseProducerInfo () 1002 { 1003 m_producer_version_major = UINT32_MAX; 1004 m_producer_version_minor = UINT32_MAX; 1005 m_producer_version_update = UINT32_MAX; 1006 1007 const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly(); 1008 if (die) 1009 { 1010 1011 const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL); 1012 if (producer_cstr) 1013 { 1014 RegularExpression llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$"); 1015 if (llvm_gcc_regex.Execute (producer_cstr)) 1016 { 1017 m_producer = eProducerLLVMGCC; 1018 } 1019 else if (strstr(producer_cstr, "clang")) 1020 { 1021 static RegularExpression g_clang_version_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"); 1022 RegularExpression::Match regex_match(3); 1023 if (g_clang_version_regex.Execute (producer_cstr, ®ex_match)) 1024 { 1025 std::string str; 1026 if (regex_match.GetMatchAtIndex (producer_cstr, 1, str)) 1027 m_producer_version_major = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1028 if (regex_match.GetMatchAtIndex (producer_cstr, 2, str)) 1029 m_producer_version_minor = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1030 if (regex_match.GetMatchAtIndex (producer_cstr, 3, str)) 1031 m_producer_version_update = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 1032 } 1033 m_producer = eProducerClang; 1034 } 1035 else if (strstr(producer_cstr, "GNU")) 1036 m_producer = eProducerGCC; 1037 } 1038 } 1039 if (m_producer == eProducerInvalid) 1040 m_producer = eProcucerOther; 1041 } 1042 1043 DWARFCompileUnit::Producer 1044 DWARFCompileUnit::GetProducer () 1045 { 1046 if (m_producer == eProducerInvalid) 1047 ParseProducerInfo (); 1048 return m_producer; 1049 } 1050 1051 1052 uint32_t 1053 DWARFCompileUnit::GetProducerVersionMajor() 1054 { 1055 if (m_producer_version_major == 0) 1056 ParseProducerInfo (); 1057 return m_producer_version_major; 1058 } 1059 1060 uint32_t 1061 DWARFCompileUnit::GetProducerVersionMinor() 1062 { 1063 if (m_producer_version_minor == 0) 1064 ParseProducerInfo (); 1065 return m_producer_version_minor; 1066 } 1067 1068 uint32_t 1069 DWARFCompileUnit::GetProducerVersionUpdate() 1070 { 1071 if (m_producer_version_update == 0) 1072 ParseProducerInfo (); 1073 return m_producer_version_update; 1074 } 1075 1076 LanguageType 1077 DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) 1078 { 1079 // Note: user languages between lo_user and hi_user 1080 // must be handled explicitly here. 1081 switch (val) 1082 { 1083 case DW_LANG_Mips_Assembler: 1084 return eLanguageTypeMipsAssembler; 1085 case 0x8e57: // FIXME: needs to be added to llvm 1086 return eLanguageTypeExtRenderScript; 1087 default: 1088 return static_cast<LanguageType>(val); 1089 } 1090 } 1091 1092 LanguageType 1093 DWARFCompileUnit::GetLanguageType() 1094 { 1095 if (m_language_type != eLanguageTypeUnknown) 1096 return m_language_type; 1097 1098 const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly(); 1099 if (die) 1100 m_language_type = LanguageTypeFromDWARF( 1101 die->GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0)); 1102 return m_language_type; 1103 } 1104 1105 bool 1106 DWARFCompileUnit::IsDWARF64() const 1107 { 1108 return m_is_dwarf64; 1109 } 1110 1111