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