llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
Pavel Labath cd5da94d80 [lldb/DWARF] Fix mixed v4+v5 location lists
Summary:
Our code was expecting that a single (symbol) file contains only one
kind of location lists. This is not correct (on non-apple platforms, at
least) as a file can compile units with different dwarf versions.

This patch moves the deteremination of location list flavour down to the
compile unit level, fixing this problem. I have also tried to rougly
align the code with the llvm DWARFUnit. Fully matching the API is not
possible because of how lldb's DWARFExpression lives separately from the
rest of the DWARF code, but this is at least a step in the right
direction.

Reviewers: JDevlieghere, aprantl, clayborg

Subscribers: dblaikie, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D71751
2020-01-09 13:19:29 +01:00

151 lines
4.8 KiB
C++

//===-- SymbolFileDWARFDwo.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 "SymbolFileDWARFDwo.h"
#include "lldb/Core/Section.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/LLDBAssert.h"
#include "llvm/Support/Casting.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugInfo.h"
#include "DWARFUnit.h"
using namespace lldb;
using namespace lldb_private;
char SymbolFileDWARFDwo::ID;
SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
DWARFCompileUnit &dwarf_cu)
: SymbolFileDWARF(objfile, objfile->GetSectionList(
/*update_module_section_list*/ false)),
m_base_dwarf_cu(dwarf_cu) {
SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32);
}
void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
DWARFDataExtractor &data) {
const SectionList *section_list =
m_objfile_sp->GetSectionList(false /* update_module_section_list */);
if (section_list) {
SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
if (section_sp) {
if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0)
return;
data.Clear();
}
}
SymbolFileDWARF::LoadSectionData(sect_type, data);
}
lldb::CompUnitSP
SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
assert(GetCompileUnit() == &dwarf_cu &&
"SymbolFileDWARFDwo::ParseCompileUnit called with incompatible "
"compile unit");
return GetBaseSymbolFile().ParseCompileUnit(m_base_dwarf_cu);
}
DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() {
if (!m_cu)
m_cu = ComputeCompileUnit();
return m_cu;
}
DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() {
DWARFDebugInfo *debug_info = DebugInfo();
if (!debug_info)
return nullptr;
// Right now we only support dwo files with one compile unit. If we don't have
// type units, we can just check for the unit count.
if (!debug_info->ContainsTypeUnits() && debug_info->GetNumUnits() == 1)
return llvm::cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(0));
// Otherwise, we have to run through all units, and find the compile unit that
// way.
DWARFCompileUnit *cu = nullptr;
for (size_t i = 0; i < debug_info->GetNumUnits(); ++i) {
if (auto *candidate =
llvm::dyn_cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(i))) {
if (cu)
return nullptr; // More that one CU found.
cu = candidate;
}
}
return cu;
}
DWARFUnit *
SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
return GetCompileUnit();
}
SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() {
return GetBaseSymbolFile().GetDIEToType();
}
SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() {
return GetBaseSymbolFile().GetDIEToVariable();
}
SymbolFileDWARF::DIEToClangType &
SymbolFileDWARFDwo::GetForwardDeclDieToClangType() {
return GetBaseSymbolFile().GetForwardDeclDieToClangType();
}
SymbolFileDWARF::ClangTypeToDIE &
SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() {
return GetBaseSymbolFile().GetForwardDeclClangTypeToDie();
}
size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets(
lldb_private::ConstString class_name, DIEArray &method_die_offsets) {
return GetBaseSymbolFile().GetObjCMethodDIEOffsets(class_name,
method_die_offsets);
}
UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
return GetBaseSymbolFile().GetUniqueDWARFASTTypeMap();
}
lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(
const DWARFDeclContext &die_decl_ctx) {
return GetBaseSymbolFile().FindDefinitionTypeForDWARFDeclContext(
die_decl_ctx);
}
lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
const DWARFDIE &die, lldb_private::ConstString type_name,
bool must_be_implementation) {
return GetBaseSymbolFile().FindCompleteObjCDefinitionTypeForDIE(
die, type_name, must_be_implementation);
}
SymbolFileDWARF &SymbolFileDWARFDwo::GetBaseSymbolFile() {
return m_base_dwarf_cu.GetSymbolFileDWARF();
}
llvm::Expected<TypeSystem &>
SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
return GetBaseSymbolFile().GetTypeSystemForLanguage(language);
}
DWARFDIE
SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
if (*die_ref.dwo_num() == GetDwoNum())
return DebugInfo()->GetDIE(die_ref);
return GetBaseSymbolFile().GetDIE(die_ref);
}