diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp')
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp | 138 | 
1 files changed, 138 insertions, 0 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp new file mode 100644 index 000000000000..08e6e1c8c2f3 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp @@ -0,0 +1,138 @@ +//===-- 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> +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<SymbolFileDWARFDwp> 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<SymbolFileDWARFDwo> +SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, +                                          uint64_t dwo_id) { +  return std::unique_ptr<SymbolFileDWARFDwo>( +      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<std::mutex> 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; +}  | 
