//===-- SymbolFileDWARFDwp.cpp ----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "SymbolFileDWARFDwp.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" #include "SymbolFileDWARFDwoDwp.h" static llvm::DWARFSectionKind lldbSectTypeToLlvmSectionKind(lldb::SectionType type) { switch (type) { case lldb::eSectionTypeDWARFDebugInfo: return llvm::DW_SECT_INFO; // case lldb::eSectionTypeDWARFDebugTypes: // return llvm::DW_SECT_TYPES; case lldb::eSectionTypeDWARFDebugAbbrev: return llvm::DW_SECT_ABBREV; case lldb::eSectionTypeDWARFDebugLine: return llvm::DW_SECT_LINE; case lldb::eSectionTypeDWARFDebugLoc: return llvm::DW_SECT_LOC; case lldb::eSectionTypeDWARFDebugStrOffsets: return llvm::DW_SECT_STR_OFFSETS; // case lldb::eSectionTypeDWARFDebugMacinfo: // return llvm::DW_SECT_MACINFO; case lldb::eSectionTypeDWARFDebugMacro: return llvm::DW_SECT_MACRO; default: // Note: 0 is an invalid dwarf section kind. return llvm::DWARFSectionKind(0); } } std::unique_ptr SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec) { const lldb::offset_t file_offset = 0; lldb::DataBufferSP file_data_sp; lldb::offset_t file_data_offset = 0; lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin( module_sp, &file_spec, file_offset, lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp, file_data_offset); if (obj_file == nullptr) return nullptr; std::unique_ptr dwp_symfile( new SymbolFileDWARFDwp(module_sp, obj_file)); lldb_private::DWARFDataExtractor debug_cu_index; if (!dwp_symfile->LoadRawSectionData(lldb::eSectionTypeDWARFDebugCuIndex, debug_cu_index)) return nullptr; llvm::DataExtractor llvm_debug_cu_index( llvm::StringRef(debug_cu_index.PeekCStr(0), debug_cu_index.GetByteSize()), debug_cu_index.GetByteOrder() == lldb::eByteOrderLittle, debug_cu_index.GetAddressByteSize()); if (!dwp_symfile->m_debug_cu_index.parse(llvm_debug_cu_index)) return nullptr; dwp_symfile->InitDebugCUIndexMap(); return dwp_symfile; } void SymbolFileDWARFDwp::InitDebugCUIndexMap() { m_debug_cu_index_map.clear(); for (const auto &entry : m_debug_cu_index.getRows()) m_debug_cu_index_map.emplace(entry.getSignature(), &entry); } SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp, lldb::ObjectFileSP obj_file) : m_obj_file(std::move(obj_file)), m_debug_cu_index(llvm::DW_SECT_INFO) {} std::unique_ptr SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, uint64_t dwo_id) { return std::unique_ptr( new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id)); } bool SymbolFileDWARFDwp::LoadSectionData( uint64_t dwo_id, lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) { lldb_private::DWARFDataExtractor section_data; if (!LoadRawSectionData(sect_type, section_data)) return false; auto it = m_debug_cu_index_map.find(dwo_id); if (it == m_debug_cu_index_map.end()) return false; auto *offsets = it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type)); if (offsets) { data.SetData(section_data, offsets->Offset, offsets->Length); } else { data.SetData(section_data, 0, section_data.GetByteSize()); } return true; } bool SymbolFileDWARFDwp::LoadRawSectionData( lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) { std::lock_guard lock(m_sections_mutex); auto it = m_sections.find(sect_type); if (it != m_sections.end()) { if (it->second.GetByteSize() == 0) return false; data = it->second; return true; } const lldb_private::SectionList *section_list = m_obj_file->GetSectionList(false /* update_module_section_list */); if (section_list) { lldb::SectionSP section_sp( section_list->FindSectionByType(sect_type, true)); if (section_sp) { if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) { m_sections[sect_type] = data; return true; } } } m_sections[sect_type].Clear(); return false; }