blob: ae10e7179e3393edc7840fcf9b39ed1d471cab60 [file] [log] [blame]
//===-- SymbolFileDWARFDwp.cpp ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "SymbolFileDWARFDwp.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#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, file_spec.GetByteSize(), 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(DWARFUnit *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;
}