1//===-- SymbolFileDWARFDwp.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 "SymbolFileDWARFDwp.h" 10 11#include "lldb/Core/Section.h" 12#include "lldb/Symbol/ObjectFile.h" 13 14#include "SymbolFileDWARFDwoDwp.h" 15 16static llvm::DWARFSectionKind 17lldbSectTypeToLlvmSectionKind(lldb::SectionType type) { 18 switch (type) { 19 case lldb::eSectionTypeDWARFDebugInfo: 20 return llvm::DW_SECT_INFO; 21 // case lldb::eSectionTypeDWARFDebugTypes: 22 // return llvm::DW_SECT_TYPES; 23 case lldb::eSectionTypeDWARFDebugAbbrev: 24 return llvm::DW_SECT_ABBREV; 25 case lldb::eSectionTypeDWARFDebugLine: 26 return llvm::DW_SECT_LINE; 27 case lldb::eSectionTypeDWARFDebugLoc: 28 return llvm::DW_SECT_LOC; 29 case lldb::eSectionTypeDWARFDebugStrOffsets: 30 return llvm::DW_SECT_STR_OFFSETS; 31 // case lldb::eSectionTypeDWARFDebugMacinfo: 32 // return llvm::DW_SECT_MACINFO; 33 case lldb::eSectionTypeDWARFDebugMacro: 34 return llvm::DW_SECT_MACRO; 35 default: 36 // Note: 0 is an invalid dwarf section kind. 37 return llvm::DWARFSectionKind(0); 38 } 39} 40 41std::unique_ptr<SymbolFileDWARFDwp> 42SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp, 43 const lldb_private::FileSpec &file_spec) { 44 const lldb::offset_t file_offset = 0; 45 lldb::DataBufferSP file_data_sp; 46 lldb::offset_t file_data_offset = 0; 47 lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin( 48 module_sp, &file_spec, file_offset, 49 lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp, 50 file_data_offset); 51 if (obj_file == nullptr) 52 return nullptr; 53 54 std::unique_ptr<SymbolFileDWARFDwp> dwp_symfile( 55 new SymbolFileDWARFDwp(module_sp, obj_file)); 56 57 lldb_private::DWARFDataExtractor debug_cu_index; 58 if (!dwp_symfile->LoadRawSectionData(lldb::eSectionTypeDWARFDebugCuIndex, 59 debug_cu_index)) 60 return nullptr; 61 62 llvm::DataExtractor llvm_debug_cu_index( 63 llvm::StringRef(debug_cu_index.PeekCStr(0), debug_cu_index.GetByteSize()), 64 debug_cu_index.GetByteOrder() == lldb::eByteOrderLittle, 65 debug_cu_index.GetAddressByteSize()); 66 if (!dwp_symfile->m_debug_cu_index.parse(llvm_debug_cu_index)) 67 return nullptr; 68 dwp_symfile->InitDebugCUIndexMap(); 69 return dwp_symfile; 70} 71 72void SymbolFileDWARFDwp::InitDebugCUIndexMap() { 73 m_debug_cu_index_map.clear(); 74 for (const auto &entry : m_debug_cu_index.getRows()) 75 m_debug_cu_index_map.emplace(entry.getSignature(), &entry); 76} 77 78SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp, 79 lldb::ObjectFileSP obj_file) 80 : m_obj_file(std::move(obj_file)), m_debug_cu_index(llvm::DW_SECT_INFO) 81{} 82 83std::unique_ptr<SymbolFileDWARFDwo> 84SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, 85 uint64_t dwo_id) { 86 return std::unique_ptr<SymbolFileDWARFDwo>( 87 new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id)); 88} 89 90bool SymbolFileDWARFDwp::LoadSectionData( 91 uint64_t dwo_id, lldb::SectionType sect_type, 92 lldb_private::DWARFDataExtractor &data) { 93 lldb_private::DWARFDataExtractor section_data; 94 if (!LoadRawSectionData(sect_type, section_data)) 95 return false; 96 97 auto it = m_debug_cu_index_map.find(dwo_id); 98 if (it == m_debug_cu_index_map.end()) 99 return false; 100 101 auto *offsets = 102 it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type)); 103 if (offsets) { 104 data.SetData(section_data, offsets->Offset, offsets->Length); 105 } else { 106 data.SetData(section_data, 0, section_data.GetByteSize()); 107 } 108 return true; 109} 110 111bool SymbolFileDWARFDwp::LoadRawSectionData( 112 lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) { 113 std::lock_guard<std::mutex> lock(m_sections_mutex); 114 115 auto it = m_sections.find(sect_type); 116 if (it != m_sections.end()) { 117 if (it->second.GetByteSize() == 0) 118 return false; 119 120 data = it->second; 121 return true; 122 } 123 124 const lldb_private::SectionList *section_list = 125 m_obj_file->GetSectionList(false /* update_module_section_list */); 126 if (section_list) { 127 lldb::SectionSP section_sp( 128 section_list->FindSectionByType(sect_type, true)); 129 if (section_sp) { 130 if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) { 131 m_sections[sect_type] = data; 132 return true; 133 } 134 } 135 } 136 m_sections[sect_type].Clear(); 137 return false; 138} 139