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