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