1 //===-- DWARFUnit.cpp -----------------------------------------------------===// 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/Symbol/ObjectFile.h" 13 #include "lldb/Utility/LLDBAssert.h" 14 #include "lldb/Utility/StreamString.h" 15 #include "lldb/Utility/Timer.h" 16 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 17 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" 18 #include "llvm/Object/Error.h" 19 20 #include "DWARFCompileUnit.h" 21 #include "DWARFDebugAranges.h" 22 #include "DWARFDebugInfo.h" 23 #include "DWARFTypeUnit.h" 24 #include "LogChannelDWARF.h" 25 #include "SymbolFileDWARFDwo.h" 26 #include <optional> 27 28 using namespace lldb; 29 using namespace lldb_private; 30 using namespace lldb_private::dwarf; 31 using namespace lldb_private::plugin::dwarf; 32 33 extern int g_verbose; 34 35 DWARFUnit::DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, 36 const llvm::DWARFUnitHeader &header, 37 const llvm::DWARFAbbreviationDeclarationSet &abbrevs, 38 DIERef::Section section, bool is_dwo) 39 : UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs), 40 m_cancel_scopes(false), m_section(section), m_is_dwo(is_dwo), 41 m_has_parsed_non_skeleton_unit(false), m_dwo_id(header.getDWOId()) {} 42 43 DWARFUnit::~DWARFUnit() = default; 44 45 // Parses first DIE of a compile unit, excluding DWO. 46 void DWARFUnit::ExtractUnitDIENoDwoIfNeeded() { 47 { 48 llvm::sys::ScopedReader lock(m_first_die_mutex); 49 if (m_first_die) 50 return; // Already parsed 51 } 52 llvm::sys::ScopedWriter lock(m_first_die_mutex); 53 if (m_first_die) 54 return; // Already parsed 55 56 ElapsedTime elapsed(m_dwarf.GetDebugInfoParseTimeRef()); 57 58 // Set the offset to that of the first DIE and calculate the start of the 59 // next compilation unit header. 60 lldb::offset_t offset = GetFirstDIEOffset(); 61 62 // We are in our compile unit, parse starting at the offset we were told to 63 // parse 64 const DWARFDataExtractor &data = GetData(); 65 if (offset < GetNextUnitOffset() && 66 m_first_die.Extract(data, *this, &offset)) { 67 AddUnitDIE(m_first_die); 68 return; 69 } 70 } 71 72 // Parses first DIE of a compile unit including DWO. 73 void DWARFUnit::ExtractUnitDIEIfNeeded() { 74 ExtractUnitDIENoDwoIfNeeded(); 75 76 if (m_has_parsed_non_skeleton_unit) 77 return; 78 79 m_has_parsed_non_skeleton_unit = true; 80 m_dwo_error.Clear(); 81 82 if (!m_dwo_id) 83 return; // No DWO file. 84 85 std::shared_ptr<SymbolFileDWARFDwo> dwo_symbol_file = 86 m_dwarf.GetDwoSymbolFileForCompileUnit(*this, m_first_die); 87 if (!dwo_symbol_file) 88 return; 89 90 DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(*m_dwo_id); 91 92 if (!dwo_cu) { 93 SetDwoError(Status::createWithFormat( 94 "unable to load .dwo file from \"{0}\" due to ID ({1:x16}) mismatch " 95 "for skeleton DIE at {2:x8}", 96 dwo_symbol_file->GetObjectFile()->GetFileSpec().GetPath().c_str(), 97 *m_dwo_id, m_first_die.GetOffset())); 98 return; // Can't fetch the compile unit from the dwo file. 99 } 100 // If the skeleton compile unit gets its unit DIE parsed first, then this 101 // will fill in the DWO file's back pointer to this skeleton compile unit. 102 // If the DWO files get parsed on their own first the skeleton back link 103 // can be done manually in DWARFUnit::GetSkeletonCompileUnit() which will 104 // do a reverse lookup and cache the result. 105 dwo_cu->SetSkeletonUnit(this); 106 107 DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly(); 108 if (!dwo_cu_die.IsValid()) { 109 // Can't fetch the compile unit DIE from the dwo file. 110 SetDwoError(Status::createWithFormat( 111 "unable to extract compile unit DIE from .dwo file for skeleton " 112 "DIE at {0:x16}", 113 m_first_die.GetOffset())); 114 return; 115 } 116 117 // Here for DWO CU we want to use the address base set in the skeleton unit 118 // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base 119 // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_* 120 // attributes which were applicable to the DWO units. The corresponding 121 // DW_AT_* attributes standardized in DWARF v5 are also applicable to the 122 // main unit in contrast. 123 if (m_addr_base) 124 dwo_cu->SetAddrBase(*m_addr_base); 125 else if (m_gnu_addr_base) 126 dwo_cu->SetAddrBase(*m_gnu_addr_base); 127 128 if (GetVersion() <= 4 && m_gnu_ranges_base) 129 dwo_cu->SetRangesBase(*m_gnu_ranges_base); 130 else if (dwo_symbol_file->GetDWARFContext() 131 .getOrLoadRngListsData() 132 .GetByteSize() > 0) 133 dwo_cu->SetRangesBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); 134 135 if (GetVersion() >= 5 && 136 dwo_symbol_file->GetDWARFContext().getOrLoadLocListsData().GetByteSize() > 137 0) 138 dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); 139 140 dwo_cu->SetBaseAddress(GetBaseAddress()); 141 142 m_dwo = std::shared_ptr<DWARFUnit>(std::move(dwo_symbol_file), dwo_cu); 143 } 144 145 // Parses a compile unit and indexes its DIEs if it hasn't already been done. 146 // It will leave this compile unit extracted forever. 147 void DWARFUnit::ExtractDIEsIfNeeded() { 148 m_cancel_scopes = true; 149 150 { 151 llvm::sys::ScopedReader lock(m_die_array_mutex); 152 if (!m_die_array.empty()) 153 return; // Already parsed 154 } 155 llvm::sys::ScopedWriter lock(m_die_array_mutex); 156 if (!m_die_array.empty()) 157 return; // Already parsed 158 159 ExtractDIEsRWLocked(); 160 } 161 162 // Parses a compile unit and indexes its DIEs if it hasn't already been done. 163 // It will clear this compile unit after returned instance gets out of scope, 164 // no other ScopedExtractDIEs instance is running for this compile unit 165 // and no ExtractDIEsIfNeeded() has been executed during this ScopedExtractDIEs 166 // lifetime. 167 DWARFUnit::ScopedExtractDIEs DWARFUnit::ExtractDIEsScoped() { 168 ScopedExtractDIEs scoped(*this); 169 170 { 171 llvm::sys::ScopedReader lock(m_die_array_mutex); 172 if (!m_die_array.empty()) 173 return scoped; // Already parsed 174 } 175 llvm::sys::ScopedWriter lock(m_die_array_mutex); 176 if (!m_die_array.empty()) 177 return scoped; // Already parsed 178 179 // Otherwise m_die_array would be already populated. 180 lldbassert(!m_cancel_scopes); 181 182 ExtractDIEsRWLocked(); 183 scoped.m_clear_dies = true; 184 return scoped; 185 } 186 187 DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(DWARFUnit &cu) : m_cu(&cu) { 188 m_cu->m_die_array_scoped_mutex.lock_shared(); 189 } 190 191 DWARFUnit::ScopedExtractDIEs::~ScopedExtractDIEs() { 192 if (!m_cu) 193 return; 194 m_cu->m_die_array_scoped_mutex.unlock_shared(); 195 if (!m_clear_dies || m_cu->m_cancel_scopes) 196 return; 197 // Be sure no other ScopedExtractDIEs is running anymore. 198 llvm::sys::ScopedWriter lock_scoped(m_cu->m_die_array_scoped_mutex); 199 llvm::sys::ScopedWriter lock(m_cu->m_die_array_mutex); 200 if (m_cu->m_cancel_scopes) 201 return; 202 m_cu->ClearDIEsRWLocked(); 203 } 204 205 DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(ScopedExtractDIEs &&rhs) 206 : m_cu(rhs.m_cu), m_clear_dies(rhs.m_clear_dies) { 207 rhs.m_cu = nullptr; 208 } 209 210 DWARFUnit::ScopedExtractDIEs & 211 DWARFUnit::ScopedExtractDIEs::operator=(DWARFUnit::ScopedExtractDIEs &&rhs) { 212 m_cu = rhs.m_cu; 213 rhs.m_cu = nullptr; 214 m_clear_dies = rhs.m_clear_dies; 215 return *this; 216 } 217 218 // Parses a compile unit and indexes its DIEs, m_die_array_mutex must be 219 // held R/W and m_die_array must be empty. 220 void DWARFUnit::ExtractDIEsRWLocked() { 221 llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex); 222 223 ElapsedTime elapsed(m_dwarf.GetDebugInfoParseTimeRef()); 224 LLDB_SCOPED_TIMERF( 225 "%s", 226 llvm::formatv("{0:x16}: DWARFUnit::ExtractDIEsIfNeeded()", GetOffset()) 227 .str() 228 .c_str()); 229 230 // Set the offset to that of the first DIE and calculate the start of the 231 // next compilation unit header. 232 lldb::offset_t offset = GetFirstDIEOffset(); 233 lldb::offset_t next_cu_offset = GetNextUnitOffset(); 234 235 DWARFDebugInfoEntry die; 236 237 uint32_t depth = 0; 238 // We are in our compile unit, parse starting at the offset we were told to 239 // parse 240 const DWARFDataExtractor &data = GetData(); 241 std::vector<uint32_t> die_index_stack; 242 die_index_stack.reserve(32); 243 die_index_stack.push_back(0); 244 bool prev_die_had_children = false; 245 while (offset < next_cu_offset && die.Extract(data, *this, &offset)) { 246 const bool null_die = die.IsNULL(); 247 if (depth == 0) { 248 assert(m_die_array.empty() && "Compile unit DIE already added"); 249 250 // The average bytes per DIE entry has been seen to be around 14-20 so 251 // lets pre-reserve half of that since we are now stripping the NULL 252 // tags. 253 254 // Only reserve the memory if we are adding children of the main 255 // compile unit DIE. The compile unit DIE is always the first entry, so 256 // if our size is 1, then we are adding the first compile unit child 257 // DIE and should reserve the memory. 258 m_die_array.reserve(GetDebugInfoSize() / 24); 259 m_die_array.push_back(die); 260 261 if (!m_first_die) 262 AddUnitDIE(m_die_array.front()); 263 264 // With -fsplit-dwarf-inlining, clang will emit non-empty skeleton compile 265 // units. We are not able to access these DIE *and* the dwo file 266 // simultaneously. We also don't need to do that as the dwo file will 267 // contain a superset of information. So, we don't even attempt to parse 268 // any remaining DIEs. 269 if (m_dwo) { 270 m_die_array.front().SetHasChildren(false); 271 break; 272 } 273 274 } else { 275 if (null_die) { 276 if (prev_die_had_children) { 277 // This will only happen if a DIE says is has children but all it 278 // contains is a NULL tag. Since we are removing the NULL DIEs from 279 // the list (saves up to 25% in C++ code), we need a way to let the 280 // DIE know that it actually doesn't have children. 281 if (!m_die_array.empty()) 282 m_die_array.back().SetHasChildren(false); 283 } 284 } else { 285 die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]); 286 287 if (die_index_stack.back()) 288 m_die_array[die_index_stack.back()].SetSiblingIndex( 289 m_die_array.size() - die_index_stack.back()); 290 291 // Only push the DIE if it isn't a NULL DIE 292 m_die_array.push_back(die); 293 } 294 } 295 296 if (null_die) { 297 // NULL DIE. 298 if (!die_index_stack.empty()) 299 die_index_stack.pop_back(); 300 301 if (depth > 0) 302 --depth; 303 prev_die_had_children = false; 304 } else { 305 die_index_stack.back() = m_die_array.size() - 1; 306 // Normal DIE 307 const bool die_has_children = die.HasChildren(); 308 if (die_has_children) { 309 die_index_stack.push_back(0); 310 ++depth; 311 } 312 prev_die_had_children = die_has_children; 313 } 314 315 if (depth == 0) 316 break; // We are done with this compile unit! 317 } 318 319 if (!m_die_array.empty()) { 320 // The last die cannot have children (if it did, it wouldn't be the last 321 // one). This only makes a difference for malformed dwarf that does not have 322 // a terminating null die. 323 m_die_array.back().SetHasChildren(false); 324 325 if (m_first_die) { 326 // Only needed for the assertion. 327 m_first_die.SetHasChildren(m_die_array.front().HasChildren()); 328 lldbassert(m_first_die == m_die_array.front()); 329 } 330 m_first_die = m_die_array.front(); 331 } 332 333 m_die_array.shrink_to_fit(); 334 335 if (m_dwo) 336 m_dwo->ExtractDIEsIfNeeded(); 337 } 338 339 // This is used when a split dwarf is enabled. 340 // A skeleton compilation unit may contain the DW_AT_str_offsets_base attribute 341 // that points to the first string offset of the CU contribution to the 342 // .debug_str_offsets. At the same time, the corresponding split debug unit also 343 // may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and 344 // for that case, we should find the offset (skip the section header). 345 void DWARFUnit::SetDwoStrOffsetsBase() { 346 lldb::offset_t baseOffset = 0; 347 348 if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) { 349 if (const auto *contribution = 350 entry->getContribution(llvm::DW_SECT_STR_OFFSETS)) 351 baseOffset = contribution->getOffset(); 352 else 353 return; 354 } 355 356 if (GetVersion() >= 5) { 357 const DWARFDataExtractor &strOffsets = 358 GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData(); 359 uint64_t length = strOffsets.GetU32(&baseOffset); 360 if (length == 0xffffffff) 361 length = strOffsets.GetU64(&baseOffset); 362 363 // Check version. 364 if (strOffsets.GetU16(&baseOffset) < 5) 365 return; 366 367 // Skip padding. 368 baseOffset += 2; 369 } 370 371 SetStrOffsetsBase(baseOffset); 372 } 373 374 std::optional<uint64_t> DWARFUnit::GetDWOId() { 375 ExtractUnitDIENoDwoIfNeeded(); 376 return m_dwo_id; 377 } 378 379 // m_die_array_mutex must be already held as read/write. 380 void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { 381 DWARFAttributes attributes = cu_die.GetAttributes(this); 382 383 // Extract DW_AT_addr_base first, as other attributes may need it. 384 for (size_t i = 0; i < attributes.Size(); ++i) { 385 if (attributes.AttributeAtIndex(i) != DW_AT_addr_base) 386 continue; 387 DWARFFormValue form_value; 388 if (attributes.ExtractFormValueAtIndex(i, form_value)) { 389 SetAddrBase(form_value.Unsigned()); 390 break; 391 } 392 } 393 394 for (size_t i = 0; i < attributes.Size(); ++i) { 395 dw_attr_t attr = attributes.AttributeAtIndex(i); 396 DWARFFormValue form_value; 397 if (!attributes.ExtractFormValueAtIndex(i, form_value)) 398 continue; 399 switch (attr) { 400 default: 401 break; 402 case DW_AT_loclists_base: 403 SetLoclistsBase(form_value.Unsigned()); 404 break; 405 case DW_AT_rnglists_base: 406 SetRangesBase(form_value.Unsigned()); 407 break; 408 case DW_AT_str_offsets_base: 409 SetStrOffsetsBase(form_value.Unsigned()); 410 break; 411 case DW_AT_low_pc: 412 SetBaseAddress(form_value.Address()); 413 break; 414 case DW_AT_entry_pc: 415 // If the value was already set by DW_AT_low_pc, don't update it. 416 if (m_base_addr == LLDB_INVALID_ADDRESS) 417 SetBaseAddress(form_value.Address()); 418 break; 419 case DW_AT_stmt_list: 420 m_line_table_offset = form_value.Unsigned(); 421 break; 422 case DW_AT_GNU_addr_base: 423 m_gnu_addr_base = form_value.Unsigned(); 424 break; 425 case DW_AT_GNU_ranges_base: 426 m_gnu_ranges_base = form_value.Unsigned(); 427 break; 428 case DW_AT_GNU_dwo_id: 429 m_dwo_id = form_value.Unsigned(); 430 break; 431 } 432 } 433 434 if (m_is_dwo) { 435 m_has_parsed_non_skeleton_unit = true; 436 SetDwoStrOffsetsBase(); 437 return; 438 } 439 } 440 441 size_t DWARFUnit::GetDebugInfoSize() const { 442 return GetLengthByteSize() + GetLength() - GetHeaderByteSize(); 443 } 444 445 const llvm::DWARFAbbreviationDeclarationSet * 446 DWARFUnit::GetAbbreviations() const { 447 return m_abbrevs; 448 } 449 450 dw_offset_t DWARFUnit::GetAbbrevOffset() const { 451 return m_abbrevs ? m_abbrevs->getOffset() : DW_INVALID_OFFSET; 452 } 453 454 dw_offset_t DWARFUnit::GetLineTableOffset() { 455 ExtractUnitDIENoDwoIfNeeded(); 456 return m_line_table_offset; 457 } 458 459 void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; } 460 461 // Parse the rangelist table header, including the optional array of offsets 462 // following it (DWARF v5 and later). 463 template <typename ListTableType> 464 static llvm::Expected<ListTableType> 465 ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset, 466 DwarfFormat format) { 467 // We are expected to be called with Offset 0 or pointing just past the table 468 // header. Correct Offset in the latter case so that it points to the start 469 // of the header. 470 if (offset == 0) { 471 // This means DW_AT_rnglists_base is missing and therefore DW_FORM_rnglistx 472 // cannot be handled. Returning a default-constructed ListTableType allows 473 // DW_FORM_sec_offset to be supported. 474 return ListTableType(); 475 } 476 477 uint64_t HeaderSize = llvm::DWARFListTableHeader::getHeaderSize(format); 478 if (offset < HeaderSize) 479 return llvm::createStringError(std::errc::invalid_argument, 480 "did not detect a valid" 481 " list table with base = 0x%" PRIx64 "\n", 482 offset); 483 offset -= HeaderSize; 484 ListTableType Table; 485 if (llvm::Error E = Table.extractHeaderAndOffsets(data, &offset)) 486 return std::move(E); 487 return Table; 488 } 489 490 void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { 491 uint64_t offset = 0; 492 if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) { 493 const auto *contribution = entry->getContribution(llvm::DW_SECT_LOCLISTS); 494 if (!contribution) { 495 GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( 496 "Failed to find location list contribution for CU with DWO Id " 497 "{0:x16}", 498 *GetDWOId()); 499 return; 500 } 501 offset += contribution->getOffset(); 502 } 503 m_loclists_base = loclists_base; 504 505 uint64_t header_size = llvm::DWARFListTableHeader::getHeaderSize(DWARF32); 506 if (loclists_base < header_size) 507 return; 508 509 m_loclist_table_header.emplace(".debug_loclists", "locations"); 510 offset += loclists_base - header_size; 511 if (llvm::Error E = m_loclist_table_header->extract( 512 m_dwarf.GetDWARFContext().getOrLoadLocListsData().GetAsLLVMDWARF(), 513 &offset)) { 514 GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( 515 "Failed to extract location list table at offset {0:x16} (location " 516 "list base: {1:x16}): {2}", 517 offset, loclists_base, toString(std::move(E)).c_str()); 518 } 519 } 520 521 std::unique_ptr<llvm::DWARFLocationTable> 522 DWARFUnit::GetLocationTable(const DataExtractor &data) const { 523 llvm::DWARFDataExtractor llvm_data( 524 data.GetData(), data.GetByteOrder() == lldb::eByteOrderLittle, 525 data.GetAddressByteSize()); 526 527 if (m_is_dwo || GetVersion() >= 5) 528 return std::make_unique<llvm::DWARFDebugLoclists>(llvm_data, GetVersion()); 529 return std::make_unique<llvm::DWARFDebugLoc>(llvm_data); 530 } 531 532 DWARFDataExtractor DWARFUnit::GetLocationData() const { 533 DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext(); 534 const DWARFDataExtractor &data = 535 GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData(); 536 if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) { 537 if (const auto *contribution = entry->getContribution( 538 GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC)) 539 return DWARFDataExtractor(data, contribution->getOffset(), 540 contribution->getLength32()); 541 return DWARFDataExtractor(); 542 } 543 return data; 544 } 545 546 DWARFDataExtractor DWARFUnit::GetRnglistData() const { 547 DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext(); 548 const DWARFDataExtractor &data = Ctx.getOrLoadRngListsData(); 549 if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) { 550 if (const auto *contribution = 551 entry->getContribution(llvm::DW_SECT_RNGLISTS)) 552 return DWARFDataExtractor(data, contribution->getOffset(), 553 contribution->getLength32()); 554 GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( 555 "Failed to find range list contribution for CU with signature {0:x16}", 556 entry->getSignature()); 557 558 return DWARFDataExtractor(); 559 } 560 return data; 561 } 562 563 void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) { 564 lldbassert(!m_rnglist_table_done); 565 566 m_ranges_base = ranges_base; 567 } 568 569 const std::optional<llvm::DWARFDebugRnglistTable> & 570 DWARFUnit::GetRnglistTable() { 571 if (GetVersion() >= 5 && !m_rnglist_table_done) { 572 m_rnglist_table_done = true; 573 if (auto table_or_error = 574 ParseListTableHeader<llvm::DWARFDebugRnglistTable>( 575 GetRnglistData().GetAsLLVMDWARF(), m_ranges_base, DWARF32)) 576 m_rnglist_table = std::move(table_or_error.get()); 577 else 578 GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( 579 "Failed to extract range list table at offset {0:x16}: {1}", 580 m_ranges_base, toString(table_or_error.takeError()).c_str()); 581 } 582 return m_rnglist_table; 583 } 584 585 // This function is called only for DW_FORM_rnglistx. 586 llvm::Expected<uint64_t> DWARFUnit::GetRnglistOffset(uint32_t Index) { 587 if (!GetRnglistTable()) 588 return llvm::createStringError(std::errc::invalid_argument, 589 "missing or invalid range list table"); 590 if (!m_ranges_base) 591 return llvm::createStringError( 592 std::errc::invalid_argument, 593 llvm::formatv("DW_FORM_rnglistx cannot be used without " 594 "DW_AT_rnglists_base for CU at {0:x16}", 595 GetOffset()) 596 .str() 597 .c_str()); 598 if (std::optional<uint64_t> off = GetRnglistTable()->getOffsetEntry( 599 GetRnglistData().GetAsLLVM(), Index)) 600 return *off + m_ranges_base; 601 return llvm::createStringError( 602 std::errc::invalid_argument, 603 "invalid range list table index %u; OffsetEntryCount is %u, " 604 "DW_AT_rnglists_base is %" PRIu64, 605 Index, GetRnglistTable()->getOffsetEntryCount(), m_ranges_base); 606 } 607 608 void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) { 609 m_str_offsets_base = str_offsets_base; 610 } 611 612 dw_addr_t DWARFUnit::ReadAddressFromDebugAddrSection(uint32_t index) const { 613 uint32_t index_size = GetAddressByteSize(); 614 dw_offset_t addr_base = GetAddrBase(); 615 dw_addr_t offset = addr_base + static_cast<dw_addr_t>(index) * index_size; 616 const DWARFDataExtractor &data = 617 m_dwarf.GetDWARFContext().getOrLoadAddrData(); 618 if (data.ValidOffsetForDataOfSize(offset, index_size)) 619 return data.GetMaxU64_unchecked(&offset, index_size); 620 return LLDB_INVALID_ADDRESS; 621 } 622 623 // It may be called only with m_die_array_mutex held R/W. 624 void DWARFUnit::ClearDIEsRWLocked() { 625 m_die_array.clear(); 626 m_die_array.shrink_to_fit(); 627 628 if (m_dwo && !m_dwo->m_cancel_scopes) 629 m_dwo->ClearDIEsRWLocked(); 630 } 631 632 lldb::ByteOrder DWARFUnit::GetByteOrder() const { 633 return m_dwarf.GetObjectFile()->GetByteOrder(); 634 } 635 636 void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; } 637 638 // Compare function DWARFDebugAranges::Range structures 639 static bool CompareDIEOffset(const DWARFDebugInfoEntry &die, 640 const dw_offset_t die_offset) { 641 return die.GetOffset() < die_offset; 642 } 643 644 // GetDIE() 645 // 646 // Get the DIE (Debug Information Entry) with the specified offset by first 647 // checking if the DIE is contained within this compile unit and grabbing the 648 // DIE from this compile unit. Otherwise we grab the DIE from the DWARF file. 649 DWARFDIE 650 DWARFUnit::GetDIE(dw_offset_t die_offset) { 651 if (die_offset == DW_INVALID_OFFSET) 652 return DWARFDIE(); // Not found 653 654 if (!ContainsDIEOffset(die_offset)) { 655 GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( 656 "GetDIE for DIE {0:x16} is outside of its CU {0:x16}", die_offset, 657 GetOffset()); 658 return DWARFDIE(); // Not found 659 } 660 661 ExtractDIEsIfNeeded(); 662 DWARFDebugInfoEntry::const_iterator end = m_die_array.cend(); 663 DWARFDebugInfoEntry::const_iterator pos = 664 lower_bound(m_die_array.cbegin(), end, die_offset, CompareDIEOffset); 665 666 if (pos != end && die_offset == (*pos).GetOffset()) 667 return DWARFDIE(this, &(*pos)); 668 return DWARFDIE(); // Not found 669 } 670 671 llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) { 672 DWARFDebugInfoEntry die; 673 if (!die.Extract(GetData(), *this, &die_offset)) 674 return llvm::StringRef(); 675 676 // Does die contain a DW_AT_Name? 677 if (const char *name = 678 die.GetAttributeValueAsString(this, DW_AT_name, nullptr)) 679 return name; 680 681 // Does its DW_AT_specification or DW_AT_abstract_origin contain an AT_Name? 682 for (auto attr : {DW_AT_specification, DW_AT_abstract_origin}) { 683 DWARFFormValue form_value; 684 if (!die.GetAttributeValue(this, attr, form_value)) 685 continue; 686 auto [unit, offset] = form_value.ReferencedUnitAndOffset(); 687 if (unit) 688 if (auto name = unit->PeekDIEName(offset); !name.empty()) 689 return name; 690 } 691 692 return llvm::StringRef(); 693 } 694 695 DWARFUnit &DWARFUnit::GetNonSkeletonUnit() { 696 ExtractUnitDIEIfNeeded(); 697 if (m_dwo) 698 return *m_dwo; 699 return *this; 700 } 701 702 uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) { 703 if (cu) 704 return cu->GetAddressByteSize(); 705 return DWARFUnit::GetDefaultAddressSize(); 706 } 707 708 uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; } 709 710 DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() { 711 if (m_skeleton_unit == nullptr && IsDWOUnit()) { 712 SymbolFileDWARFDwo *dwo = 713 llvm::dyn_cast_or_null<SymbolFileDWARFDwo>(&GetSymbolFileDWARF()); 714 // Do a reverse lookup if the skeleton compile unit wasn't set. 715 if (dwo) 716 m_skeleton_unit = dwo->GetBaseSymbolFile().GetSkeletonUnit(this); 717 } 718 return llvm::dyn_cast_or_null<DWARFCompileUnit>(m_skeleton_unit); 719 } 720 721 void DWARFUnit::SetSkeletonUnit(DWARFUnit *skeleton_unit) { 722 // If someone is re-setting the skeleton compile unit backlink, make sure 723 // it is setting it to a valid value when it wasn't valid, or if the 724 // value in m_skeleton_unit was valid, it should be the same value. 725 assert(skeleton_unit); 726 assert(m_skeleton_unit == nullptr || m_skeleton_unit == skeleton_unit); 727 m_skeleton_unit = skeleton_unit; 728 } 729 730 bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() { 731 return GetProducer() != eProducerLLVMGCC; 732 } 733 734 bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() { 735 // llvm-gcc makes completely invalid decl file attributes and won't ever be 736 // fixed, so we need to know to ignore these. 737 return GetProducer() == eProducerLLVMGCC; 738 } 739 740 bool DWARFUnit::Supports_unnamed_objc_bitfields() { 741 if (GetProducer() == eProducerClang) 742 return GetProducerVersion() >= llvm::VersionTuple(425, 0, 13); 743 // Assume all other compilers didn't have incorrect ObjC bitfield info. 744 return true; 745 } 746 747 void DWARFUnit::ParseProducerInfo() { 748 m_producer = eProducerOther; 749 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 750 if (!die) 751 return; 752 753 llvm::StringRef producer( 754 die->GetAttributeValueAsString(this, DW_AT_producer, nullptr)); 755 if (producer.empty()) 756 return; 757 758 static const RegularExpression g_swiftlang_version_regex( 759 llvm::StringRef(R"(swiftlang-([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?))")); 760 static const RegularExpression g_clang_version_regex( 761 llvm::StringRef(R"(clang-([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?))")); 762 static const RegularExpression g_llvm_gcc_regex( 763 llvm::StringRef(R"(4\.[012]\.[01] )" 764 R"(\(Based on Apple Inc\. build [0-9]+\) )" 765 R"(\(LLVM build [\.0-9]+\)$)")); 766 767 llvm::SmallVector<llvm::StringRef, 3> matches; 768 if (g_swiftlang_version_regex.Execute(producer, &matches)) { 769 m_producer_version.tryParse(matches[1]); 770 m_producer = eProducerSwift; 771 } else if (producer.contains("clang")) { 772 if (g_clang_version_regex.Execute(producer, &matches)) 773 m_producer_version.tryParse(matches[1]); 774 m_producer = eProducerClang; 775 } else if (producer.contains("GNU")) { 776 m_producer = eProducerGCC; 777 } else if (g_llvm_gcc_regex.Execute(producer)) { 778 m_producer = eProducerLLVMGCC; 779 } 780 } 781 782 DWARFProducer DWARFUnit::GetProducer() { 783 if (m_producer == eProducerInvalid) 784 ParseProducerInfo(); 785 return m_producer; 786 } 787 788 llvm::VersionTuple DWARFUnit::GetProducerVersion() { 789 if (m_producer_version.empty()) 790 ParseProducerInfo(); 791 return m_producer_version; 792 } 793 794 uint64_t DWARFUnit::GetDWARFLanguageType() { 795 if (m_language_type) 796 return *m_language_type; 797 798 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 799 if (!die) 800 m_language_type = 0; 801 else 802 m_language_type = die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0); 803 return *m_language_type; 804 } 805 806 bool DWARFUnit::GetIsOptimized() { 807 if (m_is_optimized == eLazyBoolCalculate) { 808 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 809 if (die) { 810 m_is_optimized = eLazyBoolNo; 811 if (die->GetAttributeValueAsUnsigned(this, DW_AT_APPLE_optimized, 0) == 812 1) { 813 m_is_optimized = eLazyBoolYes; 814 } 815 } 816 } 817 return m_is_optimized == eLazyBoolYes; 818 } 819 820 FileSpec::Style DWARFUnit::GetPathStyle() { 821 if (!m_comp_dir) 822 ComputeCompDirAndGuessPathStyle(); 823 return m_comp_dir->GetPathStyle(); 824 } 825 826 const FileSpec &DWARFUnit::GetCompilationDirectory() { 827 if (!m_comp_dir) 828 ComputeCompDirAndGuessPathStyle(); 829 return *m_comp_dir; 830 } 831 832 const FileSpec &DWARFUnit::GetAbsolutePath() { 833 if (!m_file_spec) 834 ComputeAbsolutePath(); 835 return *m_file_spec; 836 } 837 838 FileSpec DWARFUnit::GetFile(size_t file_idx) { 839 return m_dwarf.GetFile(*this, file_idx); 840 } 841 842 // DWARF2/3 suggests the form hostname:pathname for compilation directory. 843 // Remove the host part if present. 844 static llvm::StringRef 845 removeHostnameFromPathname(llvm::StringRef path_from_dwarf) { 846 if (!path_from_dwarf.contains(':')) 847 return path_from_dwarf; 848 llvm::StringRef host, path; 849 std::tie(host, path) = path_from_dwarf.split(':'); 850 851 if (host.contains('/')) 852 return path_from_dwarf; 853 854 // check whether we have a windows path, and so the first character is a 855 // drive-letter not a hostname. 856 if (host.size() == 1 && llvm::isAlpha(host[0]) && 857 (path.starts_with("\\") || path.starts_with("/"))) 858 return path_from_dwarf; 859 860 return path; 861 } 862 863 void DWARFUnit::ComputeCompDirAndGuessPathStyle() { 864 m_comp_dir = FileSpec(); 865 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 866 if (!die) 867 return; 868 869 llvm::StringRef comp_dir = removeHostnameFromPathname( 870 die->GetAttributeValueAsString(this, DW_AT_comp_dir, nullptr)); 871 if (!comp_dir.empty()) { 872 FileSpec::Style comp_dir_style = 873 FileSpec::GuessPathStyle(comp_dir).value_or(FileSpec::Style::native); 874 m_comp_dir = FileSpec(comp_dir, comp_dir_style); 875 } else { 876 // Try to detect the style based on the DW_AT_name attribute, but just store 877 // the detected style in the m_comp_dir field. 878 const char *name = 879 die->GetAttributeValueAsString(this, DW_AT_name, nullptr); 880 m_comp_dir = FileSpec( 881 "", FileSpec::GuessPathStyle(name).value_or(FileSpec::Style::native)); 882 } 883 } 884 885 void DWARFUnit::ComputeAbsolutePath() { 886 m_file_spec = FileSpec(); 887 const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); 888 if (!die) 889 return; 890 891 m_file_spec = 892 FileSpec(die->GetAttributeValueAsString(this, DW_AT_name, nullptr), 893 GetPathStyle()); 894 895 if (m_file_spec->IsRelative()) 896 m_file_spec->MakeAbsolute(GetCompilationDirectory()); 897 } 898 899 SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile(bool load_all_debug_info) { 900 if (load_all_debug_info) 901 ExtractUnitDIEIfNeeded(); 902 if (m_dwo) 903 return &llvm::cast<SymbolFileDWARFDwo>(m_dwo->GetSymbolFileDWARF()); 904 return nullptr; 905 } 906 907 const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { 908 if (m_func_aranges_up == nullptr) { 909 m_func_aranges_up = std::make_unique<DWARFDebugAranges>(); 910 const DWARFDebugInfoEntry *die = DIEPtr(); 911 if (die) 912 die->BuildFunctionAddressRangeTable(this, m_func_aranges_up.get()); 913 914 if (m_dwo) { 915 const DWARFDebugInfoEntry *dwo_die = m_dwo->DIEPtr(); 916 if (dwo_die) 917 dwo_die->BuildFunctionAddressRangeTable(m_dwo.get(), 918 m_func_aranges_up.get()); 919 } 920 921 const bool minimize = false; 922 m_func_aranges_up->Sort(minimize); 923 } 924 return *m_func_aranges_up; 925 } 926 927 llvm::Expected<DWARFUnitSP> 928 DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid, 929 const DWARFDataExtractor &debug_info, 930 DIERef::Section section, lldb::offset_t *offset_ptr) { 931 assert(debug_info.ValidOffset(*offset_ptr)); 932 933 DWARFContext &context = dwarf.GetDWARFContext(); 934 935 // FIXME: Either properly map between DIERef::Section and 936 // llvm::DWARFSectionKind or switch to llvm's definition entirely. 937 llvm::DWARFSectionKind section_kind_llvm = 938 section == DIERef::Section::DebugInfo 939 ? llvm::DWARFSectionKind::DW_SECT_INFO 940 : llvm::DWARFSectionKind::DW_SECT_EXT_TYPES; 941 942 llvm::DWARFDataExtractor debug_info_llvm = debug_info.GetAsLLVMDWARF(); 943 llvm::DWARFUnitHeader header; 944 if (llvm::Error extract_err = header.extract( 945 context.GetAsLLVM(), debug_info_llvm, offset_ptr, section_kind_llvm)) 946 return std::move(extract_err); 947 948 if (context.isDwo()) { 949 const llvm::DWARFUnitIndex::Entry *entry = nullptr; 950 const llvm::DWARFUnitIndex &index = header.isTypeUnit() 951 ? context.GetAsLLVM().getTUIndex() 952 : context.GetAsLLVM().getCUIndex(); 953 if (index) { 954 if (header.isTypeUnit()) 955 entry = index.getFromHash(header.getTypeHash()); 956 else if (auto dwo_id = header.getDWOId()) 957 entry = index.getFromHash(*dwo_id); 958 } 959 if (!entry) 960 entry = index.getFromOffset(header.getOffset()); 961 if (entry) 962 if (llvm::Error err = header.applyIndexEntry(entry)) 963 return std::move(err); 964 } 965 966 const llvm::DWARFDebugAbbrev *abbr = dwarf.DebugAbbrev(); 967 if (!abbr) 968 return llvm::make_error<llvm::object::GenericBinaryError>( 969 "No debug_abbrev data"); 970 971 bool abbr_offset_OK = 972 dwarf.GetDWARFContext().getOrLoadAbbrevData().ValidOffset( 973 header.getAbbrOffset()); 974 if (!abbr_offset_OK) 975 return llvm::make_error<llvm::object::GenericBinaryError>( 976 "Abbreviation offset for unit is not valid"); 977 978 llvm::Expected<const llvm::DWARFAbbreviationDeclarationSet *> abbrevs_or_err = 979 abbr->getAbbreviationDeclarationSet(header.getAbbrOffset()); 980 if (!abbrevs_or_err) 981 return abbrevs_or_err.takeError(); 982 983 const llvm::DWARFAbbreviationDeclarationSet *abbrevs = *abbrevs_or_err; 984 if (!abbrevs) 985 return llvm::make_error<llvm::object::GenericBinaryError>( 986 "No abbrev exists at the specified offset."); 987 988 bool is_dwo = dwarf.GetDWARFContext().isDwo(); 989 if (header.isTypeUnit()) 990 return DWARFUnitSP( 991 new DWARFTypeUnit(dwarf, uid, header, *abbrevs, section, is_dwo)); 992 return DWARFUnitSP( 993 new DWARFCompileUnit(dwarf, uid, header, *abbrevs, section, is_dwo)); 994 } 995 996 const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const { 997 return m_section == DIERef::Section::DebugTypes 998 ? m_dwarf.GetDWARFContext().getOrLoadDebugTypesData() 999 : m_dwarf.GetDWARFContext().getOrLoadDebugInfoData(); 1000 } 1001 1002 uint32_t DWARFUnit::GetHeaderByteSize() const { 1003 switch (m_header.getUnitType()) { 1004 case llvm::dwarf::DW_UT_compile: 1005 case llvm::dwarf::DW_UT_partial: 1006 return GetVersion() < 5 ? 11 : 12; 1007 case llvm::dwarf::DW_UT_skeleton: 1008 case llvm::dwarf::DW_UT_split_compile: 1009 return 20; 1010 case llvm::dwarf::DW_UT_type: 1011 case llvm::dwarf::DW_UT_split_type: 1012 return GetVersion() < 5 ? 23 : 24; 1013 } 1014 llvm_unreachable("invalid UnitType."); 1015 } 1016 1017 std::optional<uint64_t> 1018 DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const { 1019 offset_t offset = GetStrOffsetsBase() + index * 4; 1020 return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetU32(&offset); 1021 } 1022 1023 llvm::Expected<DWARFRangeList> 1024 DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { 1025 if (GetVersion() <= 4) { 1026 const DWARFDebugRanges *debug_ranges = m_dwarf.GetDebugRanges(); 1027 if (!debug_ranges) 1028 return llvm::make_error<llvm::object::GenericBinaryError>( 1029 "No debug_ranges section"); 1030 return debug_ranges->FindRanges(this, offset); 1031 } 1032 1033 if (!GetRnglistTable()) 1034 return llvm::createStringError(std::errc::invalid_argument, 1035 "missing or invalid range list table"); 1036 1037 llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVMDWARF(); 1038 1039 // As DW_AT_rnglists_base may be missing we need to call setAddressSize. 1040 data.setAddressSize(m_header.getAddressByteSize()); 1041 auto range_list_or_error = GetRnglistTable()->findList(data, offset); 1042 if (!range_list_or_error) 1043 return range_list_or_error.takeError(); 1044 1045 llvm::Expected<llvm::DWARFAddressRangesVector> llvm_ranges = 1046 range_list_or_error->getAbsoluteRanges( 1047 llvm::object::SectionedAddress{GetBaseAddress()}, 1048 GetAddressByteSize(), [&](uint32_t index) { 1049 uint32_t index_size = GetAddressByteSize(); 1050 dw_offset_t addr_base = GetAddrBase(); 1051 lldb::offset_t offset = 1052 addr_base + static_cast<lldb::offset_t>(index) * index_size; 1053 return llvm::object::SectionedAddress{ 1054 m_dwarf.GetDWARFContext().getOrLoadAddrData().GetMaxU64( 1055 &offset, index_size)}; 1056 }); 1057 if (!llvm_ranges) 1058 return llvm_ranges.takeError(); 1059 1060 DWARFRangeList ranges; 1061 for (const llvm::DWARFAddressRange &llvm_range : *llvm_ranges) { 1062 ranges.Append(DWARFRangeList::Entry(llvm_range.LowPC, 1063 llvm_range.HighPC - llvm_range.LowPC)); 1064 } 1065 ranges.Sort(); 1066 return ranges; 1067 } 1068 1069 llvm::Expected<DWARFRangeList> DWARFUnit::FindRnglistFromIndex(uint32_t index) { 1070 llvm::Expected<uint64_t> maybe_offset = GetRnglistOffset(index); 1071 if (!maybe_offset) 1072 return maybe_offset.takeError(); 1073 return FindRnglistFromOffset(*maybe_offset); 1074 } 1075 1076 bool DWARFUnit::HasAny(llvm::ArrayRef<dw_tag_t> tags) { 1077 ExtractUnitDIEIfNeeded(); 1078 if (m_dwo) 1079 return m_dwo->HasAny(tags); 1080 1081 for (const auto &die : m_die_array) { 1082 for (const auto tag : tags) { 1083 if (tag == die.Tag()) 1084 return true; 1085 } 1086 } 1087 return false; 1088 } 1089