1 //===-- DWARFUnit.cpp -------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "DWARFUnit.h" 10 11 #include "lldb/Core/Module.h" 12 #include "lldb/Host/StringConvert.h" 13 #include "lldb/Symbol/CompileUnit.h" 14 #include "lldb/Symbol/LineTable.h" 15 #include "lldb/Symbol/ObjectFile.h" 16 #include "lldb/Utility/LLDBAssert.h" 17 #include "lldb/Utility/StreamString.h" 18 #include "lldb/Utility/Timer.h" 19 #include "llvm/Object/Error.h" 20 21 #include "DWARFCompileUnit.h" 22 #include "DWARFDebugAranges.h" 23 #include "DWARFDebugInfo.h" 24 #include "DWARFTypeUnit.h" 25 #include "LogChannelDWARF.h" 26 #include "SymbolFileDWARFDebugMap.h" 27 #include "SymbolFileDWARFDwo.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 using namespace std; 32 33 extern int g_verbose; 34 35 DWARFUnit::DWARFUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid, 36 const DWARFUnitHeader &header, 37 const DWARFAbbreviationDeclarationSet &abbrevs, 38 DIERef::Section section) 39 : UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs), 40 m_cancel_scopes(false), m_section(section) {} 41 42 DWARFUnit::~DWARFUnit() = default; 43 44 // Parses first DIE of a compile unit. 45 void DWARFUnit::ExtractUnitDIEIfNeeded() { 46 { 47 llvm::sys::ScopedReader lock(m_first_die_mutex); 48 if (m_first_die) 49 return; // Already parsed 50 } 51 llvm::sys::ScopedWriter lock(m_first_die_mutex); 52 if (m_first_die) 53 return; // Already parsed 54 55 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 56 Timer scoped_timer(func_cat, "%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()", 57 GetOffset()); 58 59 // Set the offset to that of the first DIE and calculate the start of the 60 // next compilation unit header. 61 lldb::offset_t offset = GetFirstDIEOffset(); 62 63 // We are in our compile unit, parse starting at the offset we were told to 64 // parse 65 const DWARFDataExtractor &data = GetData(); 66 DWARFFormValue::FixedFormSizes fixed_form_sizes = 67 DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize()); 68 if (offset < GetNextUnitOffset() && 69 m_first_die.FastExtract(data, this, fixed_form_sizes, &offset)) { 70 AddUnitDIE(m_first_die); 71 return; 72 } 73 } 74 75 // Parses a compile unit and indexes its DIEs if it hasn't already been done. 76 // It will leave this compile unit extracted forever. 77 void DWARFUnit::ExtractDIEsIfNeeded() { 78 m_cancel_scopes = true; 79 80 { 81 llvm::sys::ScopedReader lock(m_die_array_mutex); 82 if (!m_die_array.empty()) 83 return; // Already parsed 84 } 85 llvm::sys::ScopedWriter lock(m_die_array_mutex); 86 if (!m_die_array.empty()) 87 return; // Already parsed 88 89 ExtractDIEsRWLocked(); 90 } 91 92 // Parses a compile unit and indexes its DIEs if it hasn't already been done. 93 // It will clear this compile unit after returned instance gets out of scope, 94 // no other ScopedExtractDIEs instance is running for this compile unit 95 // and no ExtractDIEsIfNeeded() has been executed during this ScopedExtractDIEs 96 // lifetime. 97 DWARFUnit::ScopedExtractDIEs DWARFUnit::ExtractDIEsScoped() { 98 ScopedExtractDIEs scoped(this); 99 100 { 101 llvm::sys::ScopedReader lock(m_die_array_mutex); 102 if (!m_die_array.empty()) 103 return scoped; // Already parsed 104 } 105 llvm::sys::ScopedWriter lock(m_die_array_mutex); 106 if (!m_die_array.empty()) 107 return scoped; // Already parsed 108 109 // Otherwise m_die_array would be already populated. 110 lldbassert(!m_cancel_scopes); 111 112 ExtractDIEsRWLocked(); 113 scoped.m_clear_dies = true; 114 return scoped; 115 } 116 117 DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(DWARFUnit *cu) : m_cu(cu) { 118 lldbassert(m_cu); 119 m_cu->m_die_array_scoped_mutex.lock_shared(); 120 } 121 122 DWARFUnit::ScopedExtractDIEs::~ScopedExtractDIEs() { 123 if (!m_cu) 124 return; 125 m_cu->m_die_array_scoped_mutex.unlock_shared(); 126 if (!m_clear_dies || m_cu->m_cancel_scopes) 127 return; 128 // Be sure no other ScopedExtractDIEs is running anymore. 129 llvm::sys::ScopedWriter lock_scoped(m_cu->m_die_array_scoped_mutex); 130 llvm::sys::ScopedWriter lock(m_cu->m_die_array_mutex); 131 if (m_cu->m_cancel_scopes) 132 return; 133 m_cu->ClearDIEsRWLocked(); 134 } 135 136 DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(ScopedExtractDIEs &&rhs) 137 : m_cu(rhs.m_cu), m_clear_dies(rhs.m_clear_dies) { 138 rhs.m_cu = nullptr; 139 } 140 141 DWARFUnit::ScopedExtractDIEs &DWARFUnit::ScopedExtractDIEs::operator=( 142 DWARFUnit::ScopedExtractDIEs &&rhs) { 143 m_cu = rhs.m_cu; 144 rhs.m_cu = nullptr; 145 m_clear_dies = rhs.m_clear_dies; 146 return *this; 147 } 148 149 // Parses a compile unit and indexes its DIEs, m_die_array_mutex must be 150 // held R/W and m_die_array must be empty. 151 void DWARFUnit::ExtractDIEsRWLocked() { 152 llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex); 153 154 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 155 Timer scoped_timer(func_cat, "%8.8x: DWARFUnit::ExtractDIEsIfNeeded()", 156 GetOffset()); 157 158 // Set the offset to that of the first DIE and calculate the start of the 159 // next compilation unit header. 160 lldb::offset_t offset = GetFirstDIEOffset(); 161 lldb::offset_t next_cu_offset = GetNextUnitOffset(); 162 163 DWARFDebugInfoEntry die; 164 165 uint32_t depth = 0; 166 // We are in our compile unit, parse starting at the offset we were told to 167 // parse 168 const DWARFDataExtractor &data = GetData(); 169 std::vector<uint32_t> die_index_stack; 170 die_index_stack.reserve(32); 171 die_index_stack.push_back(0); 172 bool prev_die_had_children = false; 173 DWARFFormValue::FixedFormSizes fixed_form_sizes = 174 DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize()); 175 while (offset < next_cu_offset && 176 die.FastExtract(data, this, fixed_form_sizes, &offset)) { 177 const bool null_die = die.IsNULL(); 178 if (depth == 0) { 179 assert(m_die_array.empty() && "Compile unit DIE already added"); 180 181 // The average bytes per DIE entry has been seen to be around 14-20 so 182 // lets pre-reserve half of that since we are now stripping the NULL 183 // tags. 184 185 // Only reserve the memory if we are adding children of the main 186 // compile unit DIE. The compile unit DIE is always the first entry, so 187 // if our size is 1, then we are adding the first compile unit child 188 // DIE and should reserve the memory. 189 m_die_array.reserve(GetDebugInfoSize() / 24); 190 m_die_array.push_back(die); 191 192 if (!m_first_die) 193 AddUnitDIE(m_die_array.front()); 194 } else { 195 if (null_die) { 196 if (prev_die_had_children) { 197 // This will only happen if a DIE says is has children but all it 198 // contains is a NULL tag. Since we are removing the NULL DIEs from 199 // the list (saves up to 25% in C++ code), we need a way to let the 200 // DIE know that it actually doesn't have children. 201 if (!m_die_array.empty()) 202 m_die_array.back().SetHasChildren(false); 203 } 204 } else { 205 die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]); 206 207 if (die_index_stack.back()) 208 m_die_array[die_index_stack.back()].SetSiblingIndex( 209 m_die_array.size() - die_index_stack.back()); 210 211 // Only push the DIE if it isn't a NULL DIE 212 m_die_array.push_back(die); 213 } 214 } 215 216 if (null_die) { 217 // NULL DIE. 218 if (!die_index_stack.empty()) 219 die_index_stack.pop_back(); 220 221 if (depth > 0) 222 --depth; 223 prev_die_had_children = false; 224 } else { 225 die_index_stack.back() = m_die_array.size() - 1; 226 // Normal DIE 227 const bool die_has_children = die.HasChildren(); 228 if (die_has_children) { 229 die_index_stack.push_back(0); 230 ++depth; 231 } 232 prev_die_had_children = die_has_children; 233 } 234 235 if (depth == 0) 236 break; // We are done with this compile unit! 237 } 238 239 if (!m_die_array.empty()) { 240 if (m_first_die) { 241 // Only needed for the assertion. 242 m_first_die.SetHasChildren(m_die_array.front().HasChildren()); 243 lldbassert(m_first_die == m_die_array.front()); 244 } 245 m_first_die = m_die_array.front(); 246 } 247 248 m_die_array.shrink_to_fit(); 249 250 if (m_dwo_symbol_file) { 251 DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); 252 dwo_cu->ExtractDIEsIfNeeded(); 253 } 254 } 255 256 // This is used when a split dwarf is enabled. 257 // A skeleton compilation unit may contain the DW_AT_str_offsets_base attribute 258 // that points to the first string offset of the CU contribution to the 259 // .debug_str_offsets. At the same time, the corresponding split debug unit also 260 // may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and 261 // for that case, we should find the offset (skip the section header). 262 static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) { 263 lldb::offset_t baseOffset = 0; 264 265 const DWARFDataExtractor &strOffsets = 266 dwo_cu->GetSymbolFileDWARF()->GetDWARFContext().getOrLoadStrOffsetsData(); 267 uint64_t length = strOffsets.GetU32(&baseOffset); 268 if (length == 0xffffffff) 269 length = strOffsets.GetU64(&baseOffset); 270 271 // Check version. 272 if (strOffsets.GetU16(&baseOffset) < 5) 273 return; 274 275 // Skip padding. 276 baseOffset += 2; 277 278 dwo_cu->SetStrOffsetsBase(baseOffset); 279 } 280 281 // m_die_array_mutex must be already held as read/write. 282 void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { 283 dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned( 284 this, DW_AT_addr_base, LLDB_INVALID_ADDRESS); 285 if (addr_base != LLDB_INVALID_ADDRESS) 286 SetAddrBase(addr_base); 287 288 dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( 289 this, DW_AT_rnglists_base, LLDB_INVALID_ADDRESS); 290 if (ranges_base != LLDB_INVALID_ADDRESS) 291 SetRangesBase(ranges_base); 292 293 SetStrOffsetsBase( 294 cu_die.GetAttributeValueAsUnsigned(this, DW_AT_str_offsets_base, 0)); 295 296 uint64_t base_addr = cu_die.GetAttributeValueAsAddress(this, DW_AT_low_pc, 297 LLDB_INVALID_ADDRESS); 298 if (base_addr == LLDB_INVALID_ADDRESS) 299 base_addr = cu_die.GetAttributeValueAsAddress(this, DW_AT_entry_pc, 0); 300 SetBaseAddress(base_addr); 301 302 std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file = 303 m_dwarf->GetDwoSymbolFileForCompileUnit(*this, cu_die); 304 if (!dwo_symbol_file) 305 return; 306 307 DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); 308 if (!dwo_cu) 309 return; // Can't fetch the compile unit from the dwo file. 310 311 DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly(); 312 if (!dwo_cu_die.IsValid()) 313 return; // Can't fetch the compile unit DIE from the dwo file. 314 315 uint64_t main_dwo_id = 316 cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0); 317 uint64_t sub_dwo_id = 318 dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0); 319 if (main_dwo_id != sub_dwo_id) 320 return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to 321 // a differectn compilation. 322 323 m_dwo_symbol_file = std::move(dwo_symbol_file); 324 325 // Here for DWO CU we want to use the address base set in the skeleton unit 326 // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base 327 // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_* 328 // attributes which were applicable to the DWO units. The corresponding 329 // DW_AT_* attributes standardized in DWARF v5 are also applicable to the main 330 // unit in contrast. 331 if (addr_base == LLDB_INVALID_ADDRESS) 332 addr_base = 333 cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_addr_base, 0); 334 dwo_cu->SetAddrBase(addr_base); 335 336 if (ranges_base == LLDB_INVALID_ADDRESS) 337 ranges_base = 338 cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_ranges_base, 0); 339 dwo_cu->SetRangesBase(ranges_base); 340 341 dwo_cu->SetBaseObjOffset(GetOffset()); 342 343 SetDwoStrOffsetsBase(dwo_cu); 344 } 345 346 DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) { 347 if (DIE()) { 348 const DWARFDebugAranges &func_aranges = GetFunctionAranges(); 349 350 // Re-check the aranges auto pointer contents in case it was created above 351 if (!func_aranges.IsEmpty()) 352 return GetDIE(func_aranges.FindAddress(address)); 353 } 354 return DWARFDIE(); 355 } 356 357 size_t DWARFUnit::AppendDIEsWithTag(const dw_tag_t tag, 358 std::vector<DWARFDIE> &dies, 359 uint32_t depth) const { 360 size_t old_size = dies.size(); 361 { 362 llvm::sys::ScopedReader lock(m_die_array_mutex); 363 DWARFDebugInfoEntry::const_iterator pos; 364 DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); 365 for (pos = m_die_array.begin(); pos != end; ++pos) { 366 if (pos->Tag() == tag) 367 dies.emplace_back(this, &(*pos)); 368 } 369 } 370 371 // Return the number of DIEs added to the collection 372 return dies.size() - old_size; 373 } 374 375 size_t DWARFUnit::GetDebugInfoSize() const { 376 return GetLengthByteSize() + GetLength() - GetHeaderByteSize(); 377 } 378 379 const DWARFAbbreviationDeclarationSet *DWARFUnit::GetAbbreviations() const { 380 return m_abbrevs; 381 } 382 383 dw_offset_t DWARFUnit::GetAbbrevOffset() const { 384 return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; 385 } 386 387 void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; } 388 389 void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) { 390 m_ranges_base = ranges_base; 391 } 392 393 void DWARFUnit::SetBaseObjOffset(dw_offset_t base_obj_offset) { 394 m_base_obj_offset = base_obj_offset; 395 } 396 397 void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) { 398 m_str_offsets_base = str_offsets_base; 399 } 400 401 // It may be called only with m_die_array_mutex held R/W. 402 void DWARFUnit::ClearDIEsRWLocked() { 403 m_die_array.clear(); 404 m_die_array.shrink_to_fit(); 405 406 if (m_dwo_symbol_file) 407 m_dwo_symbol_file->GetCompileUnit()->ClearDIEsRWLocked(); 408 } 409 410 void DWARFUnit::BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) { 411 // This function is usually called if there in no .debug_aranges section in 412 // order to produce a compile unit level set of address ranges that is 413 // accurate. 414 415 size_t num_debug_aranges = debug_aranges->GetNumRanges(); 416 417 // First get the compile unit DIE only and check if it has a DW_AT_ranges 418 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 419 420 const dw_offset_t cu_offset = GetOffset(); 421 if (die) { 422 DWARFRangeList ranges; 423 const size_t num_ranges = 424 die->GetAttributeAddressRanges(this, ranges, false); 425 if (num_ranges > 0) { 426 // This compile unit has DW_AT_ranges, assume this is correct if it is 427 // present since clang no longer makes .debug_aranges by default and it 428 // emits DW_AT_ranges for DW_TAG_compile_units. GCC also does this with 429 // recent GCC builds. 430 for (size_t i = 0; i < num_ranges; ++i) { 431 const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); 432 debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), 433 range.GetRangeEnd()); 434 } 435 436 return; // We got all of our ranges from the DW_AT_ranges attribute 437 } 438 } 439 // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF 440 441 // If the DIEs weren't parsed, then we don't want all dies for all compile 442 // units to stay loaded when they weren't needed. So we can end up parsing 443 // the DWARF and then throwing them all away to keep memory usage down. 444 ScopedExtractDIEs clear_dies(ExtractDIEsScoped()); 445 446 die = DIEPtr(); 447 if (die) 448 die->BuildAddressRangeTable(this, debug_aranges); 449 450 if (debug_aranges->GetNumRanges() == num_debug_aranges) { 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 = m_dwarf->GetCompUnitForDWARFCompUnit(this); 455 if (sc.comp_unit) { 456 SymbolFileDWARFDebugMap *debug_map_sym_file = 457 m_dwarf->GetDebugMapSymfile(); 458 if (debug_map_sym_file == NULL) { 459 LineTable *line_table = sc.comp_unit->GetLineTable(); 460 461 if (line_table) { 462 LineTable::FileAddressRanges file_ranges; 463 const bool append = true; 464 const size_t num_ranges = 465 line_table->GetContiguousFileAddressRanges(file_ranges, append); 466 for (uint32_t idx = 0; idx < num_ranges; ++idx) { 467 const LineTable::FileAddressRanges::Entry &range = 468 file_ranges.GetEntryRef(idx); 469 debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), 470 range.GetRangeEnd()); 471 } 472 } 473 } else 474 debug_map_sym_file->AddOSOARanges(m_dwarf, debug_aranges); 475 } 476 } 477 478 if (debug_aranges->GetNumRanges() == num_debug_aranges) { 479 // We got nothing from the functions, maybe we have a line tables only 480 // situation. Check the line tables and build the arange table from this. 481 SymbolContext sc; 482 sc.comp_unit = m_dwarf->GetCompUnitForDWARFCompUnit(this); 483 if (sc.comp_unit) { 484 LineTable *line_table = sc.comp_unit->GetLineTable(); 485 486 if (line_table) { 487 LineTable::FileAddressRanges file_ranges; 488 const bool append = true; 489 const size_t num_ranges = 490 line_table->GetContiguousFileAddressRanges(file_ranges, append); 491 for (uint32_t idx = 0; idx < num_ranges; ++idx) { 492 const LineTable::FileAddressRanges::Entry &range = 493 file_ranges.GetEntryRef(idx); 494 debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), 495 range.GetRangeEnd()); 496 } 497 } 498 } 499 } 500 } 501 502 lldb::ByteOrder DWARFUnit::GetByteOrder() const { 503 return m_dwarf->GetObjectFile()->GetByteOrder(); 504 } 505 506 TypeSystem *DWARFUnit::GetTypeSystem() { 507 if (m_dwarf) 508 return m_dwarf->GetTypeSystemForLanguage(GetLanguageType()); 509 else 510 return nullptr; 511 } 512 513 DWARFFormValue::FixedFormSizes DWARFUnit::GetFixedFormSizes() { 514 return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize()); 515 } 516 517 void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; } 518 519 // Compare function DWARFDebugAranges::Range structures 520 static bool CompareDIEOffset(const DWARFDebugInfoEntry &die, 521 const dw_offset_t die_offset) { 522 return die.GetOffset() < die_offset; 523 } 524 525 // GetDIE() 526 // 527 // Get the DIE (Debug Information Entry) with the specified offset by first 528 // checking if the DIE is contained within this compile unit and grabbing the 529 // DIE from this compile unit. Otherwise we grab the DIE from the DWARF file. 530 DWARFDIE 531 DWARFUnit::GetDIE(dw_offset_t die_offset) { 532 if (die_offset != DW_INVALID_OFFSET) { 533 if (GetDwoSymbolFile()) 534 return GetDwoSymbolFile()->GetCompileUnit()->GetDIE(die_offset); 535 536 if (ContainsDIEOffset(die_offset)) { 537 ExtractDIEsIfNeeded(); 538 DWARFDebugInfoEntry::const_iterator end = m_die_array.cend(); 539 DWARFDebugInfoEntry::const_iterator pos = 540 lower_bound(m_die_array.cbegin(), end, die_offset, CompareDIEOffset); 541 if (pos != end) { 542 if (die_offset == (*pos).GetOffset()) 543 return DWARFDIE(this, &(*pos)); 544 } 545 } else 546 GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( 547 "GetDIE for DIE 0x%" PRIx32 " is outside of its CU 0x%" PRIx32, 548 die_offset, GetOffset()); 549 } 550 return DWARFDIE(); // Not found 551 } 552 553 uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) { 554 if (cu) 555 return cu->GetAddressByteSize(); 556 return DWARFUnit::GetDefaultAddressSize(); 557 } 558 559 uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; } 560 561 void *DWARFUnit::GetUserData() const { return m_user_data; } 562 563 void DWARFUnit::SetUserData(void *d) { 564 m_user_data = d; 565 if (m_dwo_symbol_file) 566 m_dwo_symbol_file->GetCompileUnit()->SetUserData(d); 567 } 568 569 bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() { 570 return GetProducer() != eProducerLLVMGCC; 571 } 572 573 bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() { 574 // llvm-gcc makes completely invalid decl file attributes and won't ever be 575 // fixed, so we need to know to ignore these. 576 return GetProducer() == eProducerLLVMGCC; 577 } 578 579 bool DWARFUnit::Supports_unnamed_objc_bitfields() { 580 if (GetProducer() == eProducerClang) { 581 const uint32_t major_version = GetProducerVersionMajor(); 582 return major_version > 425 || 583 (major_version == 425 && GetProducerVersionUpdate() >= 13); 584 } 585 return true; // Assume all other compilers didn't have incorrect ObjC bitfield 586 // info 587 } 588 589 SymbolFileDWARF *DWARFUnit::GetSymbolFileDWARF() const { return m_dwarf; } 590 591 void DWARFUnit::ParseProducerInfo() { 592 m_producer_version_major = UINT32_MAX; 593 m_producer_version_minor = UINT32_MAX; 594 m_producer_version_update = UINT32_MAX; 595 596 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 597 if (die) { 598 599 const char *producer_cstr = 600 die->GetAttributeValueAsString(this, DW_AT_producer, NULL); 601 if (producer_cstr) { 602 RegularExpression llvm_gcc_regex( 603 llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple " 604 "Inc\\. build [0-9]+\\) \\(LLVM build " 605 "[\\.0-9]+\\)$")); 606 if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) { 607 m_producer = eProducerLLVMGCC; 608 } else if (strstr(producer_cstr, "clang")) { 609 static RegularExpression g_clang_version_regex( 610 llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)")); 611 RegularExpression::Match regex_match(3); 612 if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr), 613 ®ex_match)) { 614 std::string str; 615 if (regex_match.GetMatchAtIndex(producer_cstr, 1, str)) 616 m_producer_version_major = 617 StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 618 if (regex_match.GetMatchAtIndex(producer_cstr, 2, str)) 619 m_producer_version_minor = 620 StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 621 if (regex_match.GetMatchAtIndex(producer_cstr, 3, str)) 622 m_producer_version_update = 623 StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10); 624 } 625 m_producer = eProducerClang; 626 } else if (strstr(producer_cstr, "GNU")) 627 m_producer = eProducerGCC; 628 } 629 } 630 if (m_producer == eProducerInvalid) 631 m_producer = eProcucerOther; 632 } 633 634 DWARFProducer DWARFUnit::GetProducer() { 635 if (m_producer == eProducerInvalid) 636 ParseProducerInfo(); 637 return m_producer; 638 } 639 640 uint32_t DWARFUnit::GetProducerVersionMajor() { 641 if (m_producer_version_major == 0) 642 ParseProducerInfo(); 643 return m_producer_version_major; 644 } 645 646 uint32_t DWARFUnit::GetProducerVersionMinor() { 647 if (m_producer_version_minor == 0) 648 ParseProducerInfo(); 649 return m_producer_version_minor; 650 } 651 652 uint32_t DWARFUnit::GetProducerVersionUpdate() { 653 if (m_producer_version_update == 0) 654 ParseProducerInfo(); 655 return m_producer_version_update; 656 } 657 LanguageType DWARFUnit::LanguageTypeFromDWARF(uint64_t val) { 658 // Note: user languages between lo_user and hi_user must be handled 659 // explicitly here. 660 switch (val) { 661 case DW_LANG_Mips_Assembler: 662 return eLanguageTypeMipsAssembler; 663 case DW_LANG_GOOGLE_RenderScript: 664 return eLanguageTypeExtRenderScript; 665 default: 666 return static_cast<LanguageType>(val); 667 } 668 } 669 670 LanguageType DWARFUnit::GetLanguageType() { 671 if (m_language_type != eLanguageTypeUnknown) 672 return m_language_type; 673 674 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 675 if (die) 676 m_language_type = LanguageTypeFromDWARF( 677 die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0)); 678 return m_language_type; 679 } 680 681 bool DWARFUnit::GetIsOptimized() { 682 if (m_is_optimized == eLazyBoolCalculate) { 683 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 684 if (die) { 685 m_is_optimized = eLazyBoolNo; 686 if (die->GetAttributeValueAsUnsigned(this, DW_AT_APPLE_optimized, 0) == 687 1) { 688 m_is_optimized = eLazyBoolYes; 689 } 690 } 691 } 692 return m_is_optimized == eLazyBoolYes; 693 } 694 695 FileSpec::Style DWARFUnit::GetPathStyle() { 696 if (!m_comp_dir) 697 ComputeCompDirAndGuessPathStyle(); 698 return m_comp_dir->GetPathStyle(); 699 } 700 701 const FileSpec &DWARFUnit::GetCompilationDirectory() { 702 if (!m_comp_dir) 703 ComputeCompDirAndGuessPathStyle(); 704 return *m_comp_dir; 705 } 706 707 // DWARF2/3 suggests the form hostname:pathname for compilation directory. 708 // Remove the host part if present. 709 static llvm::StringRef 710 removeHostnameFromPathname(llvm::StringRef path_from_dwarf) { 711 llvm::StringRef host, path; 712 std::tie(host, path) = path_from_dwarf.split(':'); 713 714 if (host.contains('/')) 715 return path_from_dwarf; 716 717 // check whether we have a windows path, and so the first character is a 718 // drive-letter not a hostname. 719 if (host.size() == 1 && llvm::isAlpha(host[0]) && path.startswith("\\")) 720 return path_from_dwarf; 721 722 return path; 723 } 724 725 static FileSpec resolveCompDir(const FileSpec &path) { 726 bool is_symlink = SymbolFileDWARF::GetSymlinkPaths().FindFileIndex( 727 0, path, /*full*/ true) != UINT32_MAX; 728 729 if (!is_symlink) 730 return path; 731 732 namespace fs = llvm::sys::fs; 733 if (fs::get_file_type(path.GetPath(), false) != fs::file_type::symlink_file) 734 return path; 735 736 FileSpec resolved_symlink; 737 const auto error = FileSystem::Instance().Readlink(path, resolved_symlink); 738 if (error.Success()) 739 return resolved_symlink; 740 741 return path; 742 } 743 744 void DWARFUnit::ComputeCompDirAndGuessPathStyle() { 745 m_comp_dir = FileSpec(); 746 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 747 if (!die) 748 return; 749 750 llvm::StringRef comp_dir = removeHostnameFromPathname( 751 die->GetAttributeValueAsString(this, DW_AT_comp_dir, NULL)); 752 if (!comp_dir.empty()) { 753 FileSpec::Style comp_dir_style = 754 FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native); 755 m_comp_dir = resolveCompDir(FileSpec(comp_dir, comp_dir_style)); 756 } else { 757 // Try to detect the style based on the DW_AT_name attribute, but just store 758 // the detected style in the m_comp_dir field. 759 const char *name = die->GetAttributeValueAsString(this, DW_AT_name, NULL); 760 m_comp_dir = FileSpec( 761 "", FileSpec::GuessPathStyle(name).getValueOr(FileSpec::Style::native)); 762 } 763 } 764 765 SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() const { 766 return m_dwo_symbol_file.get(); 767 } 768 769 dw_offset_t DWARFUnit::GetBaseObjOffset() const { return m_base_obj_offset; } 770 771 const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { 772 if (m_func_aranges_up == NULL) { 773 m_func_aranges_up.reset(new DWARFDebugAranges()); 774 const DWARFDebugInfoEntry *die = DIEPtr(); 775 if (die) 776 die->BuildFunctionAddressRangeTable(this, m_func_aranges_up.get()); 777 778 if (m_dwo_symbol_file) { 779 DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); 780 const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr(); 781 if (dwo_die) 782 dwo_die->BuildFunctionAddressRangeTable(dwo_cu, 783 m_func_aranges_up.get()); 784 } 785 786 const bool minimize = false; 787 m_func_aranges_up->Sort(minimize); 788 } 789 return *m_func_aranges_up; 790 } 791 792 llvm::Expected<DWARFUnitHeader> 793 DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section, 794 lldb::offset_t *offset_ptr) { 795 DWARFUnitHeader header; 796 header.m_offset = *offset_ptr; 797 header.m_length = data.GetDWARFInitialLength(offset_ptr); 798 header.m_version = data.GetU16(offset_ptr); 799 if (header.m_version == 5) { 800 header.m_unit_type = data.GetU8(offset_ptr); 801 header.m_addr_size = data.GetU8(offset_ptr); 802 header.m_abbr_offset = data.GetDWARFOffset(offset_ptr); 803 if (header.m_unit_type == llvm::dwarf::DW_UT_skeleton) 804 header.m_dwo_id = data.GetU64(offset_ptr); 805 } else { 806 header.m_abbr_offset = data.GetDWARFOffset(offset_ptr); 807 header.m_addr_size = data.GetU8(offset_ptr); 808 header.m_unit_type = 809 section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile; 810 } 811 812 bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1); 813 bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version); 814 bool addr_size_OK = (header.m_addr_size == 4) || (header.m_addr_size == 8); 815 816 if (!length_OK) 817 return llvm::make_error<llvm::object::GenericBinaryError>( 818 "Invalid unit length"); 819 if (!version_OK) 820 return llvm::make_error<llvm::object::GenericBinaryError>( 821 "Unsupported unit version"); 822 if (!addr_size_OK) 823 return llvm::make_error<llvm::object::GenericBinaryError>( 824 "Invalid unit address size"); 825 826 return header; 827 } 828 829 llvm::Expected<DWARFUnitSP> 830 DWARFUnit::extract(SymbolFileDWARF *dwarf, user_id_t uid, 831 const DWARFDataExtractor &debug_info, DIERef::Section section, 832 lldb::offset_t *offset_ptr) { 833 assert(debug_info.ValidOffset(*offset_ptr)); 834 835 auto expected_header = 836 DWARFUnitHeader::extract(debug_info, section, offset_ptr); 837 if (!expected_header) 838 return expected_header.takeError(); 839 840 const DWARFDebugAbbrev *abbr = dwarf->DebugAbbrev(); 841 if (!abbr) 842 return llvm::make_error<llvm::object::GenericBinaryError>( 843 "No debug_abbrev data"); 844 845 bool abbr_offset_OK = 846 dwarf->GetDWARFContext().getOrLoadAbbrevData().ValidOffset( 847 expected_header->GetAbbrOffset()); 848 if (!abbr_offset_OK) 849 return llvm::make_error<llvm::object::GenericBinaryError>( 850 "Abbreviation offset for unit is not valid"); 851 852 const DWARFAbbreviationDeclarationSet *abbrevs = 853 abbr->GetAbbreviationDeclarationSet(expected_header->GetAbbrOffset()); 854 if (!abbrevs) 855 return llvm::make_error<llvm::object::GenericBinaryError>( 856 "No abbrev exists at the specified offset."); 857 858 if (expected_header->IsTypeUnit()) 859 return DWARFUnitSP( 860 new DWARFTypeUnit(dwarf, uid, *expected_header, *abbrevs, section)); 861 return DWARFUnitSP( 862 new DWARFCompileUnit(dwarf, uid, *expected_header, *abbrevs, section)); 863 } 864 865 const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const { 866 return m_section == DIERef::Section::DebugTypes 867 ? m_dwarf->GetDWARFContext().getOrLoadDebugTypesData() 868 : m_dwarf->GetDWARFContext().getOrLoadDebugInfoData(); 869 } 870 871 uint32_t DWARFUnit::GetHeaderByteSize() const { 872 switch (m_header.GetUnitType()) { 873 case llvm::dwarf::DW_UT_compile: 874 case llvm::dwarf::DW_UT_partial: 875 return GetVersion() < 5 ? 11 : 12; 876 case llvm::dwarf::DW_UT_skeleton: 877 case llvm::dwarf::DW_UT_split_compile: 878 return 20; 879 case llvm::dwarf::DW_UT_type: 880 case llvm::dwarf::DW_UT_split_type: 881 return GetVersion() < 5 ? 23 : 24; 882 } 883 llvm_unreachable("invalid UnitType."); 884 } 885