summaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile/DWARF
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF')
-rw-r--r--source/Plugins/SymbolFile/DWARF/CMakeLists.txt3
-rw-r--r--source/Plugins/SymbolFile/DWARF/DIERef.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp30
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp70
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h53
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp12
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp102
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h6
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp21
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h14
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp37
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp36
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.h1
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp99
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h22
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp25
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h9
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp36
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h34
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp142
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h55
24 files changed, 577 insertions, 260 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index fb468440f9e03..05d9e66428680 100644
--- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -30,6 +30,8 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
NameToDIE.cpp
SymbolFileDWARF.cpp
SymbolFileDWARFDwo.cpp
+ SymbolFileDWARFDwoDwp.cpp
+ SymbolFileDWARFDwp.cpp
SymbolFileDWARFDebugMap.cpp
UniqueDWARFASTType.cpp
@@ -47,5 +49,6 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
lldbPluginCPlusPlusLanguage
lldbPluginExpressionParserClang
LINK_COMPONENTS
+ DebugInfoDWARF
Support
)
diff --git a/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index 5ed9c6ab72825..c05444c031e67 100644
--- a/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -65,7 +65,7 @@ lldb::user_id_t DIERef::GetUID(SymbolFileDWARF *dwarf) const {
//
// SymbolFileDWARFDwo sets the ID to the compile unit offset.
//----------------------------------------------------------------------
- if (dwarf)
+ if (dwarf && die_offset != DW_INVALID_OFFSET)
return dwarf->GetID() | die_offset;
else
return LLDB_INVALID_UID;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index f5418763d67be..6ae2b225d8696 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -786,7 +786,17 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
m_ast.ParseClassTemplateDecl(decl_ctx, accessibility,
type_name_cstr, tag_decl_kind,
template_param_infos);
-
+ if (!class_template_decl) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
+ "clang::ClassTemplateDecl failed to return a decl.",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+ }
+ return TypeSP();
+ }
+
clang::ClassTemplateSpecializationDecl
*class_specialization_decl =
m_ast.CreateClassTemplateSpecializationDecl(
@@ -927,6 +937,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// Set a bit that lets us know that we are currently parsing this
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+ bool is_scoped = false;
DWARFFormValue encoding_form;
const size_t num_attributes = die.GetAttributes(attributes);
@@ -963,6 +974,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_AT_declaration:
is_forward_declaration = form_value.Boolean();
break;
+ case DW_AT_enum_class:
+ is_scoped = form_value.Boolean();
+ break;
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_bit_stride:
@@ -1052,7 +1066,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
clang_type = m_ast.CreateEnumerationType(
type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr),
- decl, enumerator_clang_type);
+ decl, enumerator_clang_type, is_scoped);
} else {
enumerator_clang_type =
m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
@@ -2741,8 +2755,6 @@ bool DWARFASTParserClang::ParseChildMembers(
form_value.BlockData() - debug_info_data.GetDataStart();
if (DWARFExpression::Evaluate(
nullptr, // ExecutionContext *
- nullptr, // ClangExpressionVariableList *
- nullptr, // ClangExpressionDeclMap *
nullptr, // RegisterContext *
module_sp, debug_info_data, die.GetCU(), block_offset,
block_length, eRegisterKindDWARF, &initialValue,
@@ -3214,11 +3226,11 @@ bool DWARFASTParserClang::ParseChildMembers(
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(
- nullptr, nullptr, nullptr, nullptr, module_sp,
- debug_info_data, die.GetCU(), block_offset,
- block_length, eRegisterKindDWARF, &initialValue,
- nullptr, memberOffset, nullptr)) {
+ if (DWARFExpression::Evaluate(nullptr, nullptr, module_sp,
+ debug_info_data, die.GetCU(),
+ block_offset, block_length,
+ eRegisterKindDWARF, &initialValue,
+ nullptr, memberOffset, nullptr)) {
member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
} else {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
index 2507465750c7f..e04dc76d1dbe0 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -662,8 +662,6 @@ size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
form_value.BlockData() - debug_info_data.GetDataStart();
if (DWARFExpression::Evaluate(
NULL, // ExecutionContext *
- NULL, // ClangExpressionVariableList *
- NULL, // ClangExpressionDeclMap *
NULL, // RegisterContext *
module_sp, debug_info_data, die.GetCU(), block_offset,
block_length, eRegisterKindDWARF, &initialValue, NULL,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index 79b2acc4b4f38..5d7b12067263e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -39,68 +39,48 @@ using namespace std;
extern int g_verbose;
DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
- : m_dwarf2Data(dwarf2Data), m_abbrevs(NULL), m_user_data(NULL),
- m_die_array(), m_func_aranges_ap(), m_base_addr(0),
- m_offset(DW_INVALID_OFFSET), m_length(0), m_version(0),
- m_addr_size(DWARFCompileUnit::GetDefaultAddressSize()),
- m_producer(eProducerInvalid), m_producer_version_major(0),
- m_producer_version_minor(0), m_producer_version_update(0),
- m_language_type(eLanguageTypeUnknown), m_is_dwarf64(false),
- m_is_optimized(eLazyBoolCalculate), m_addr_base(0),
- m_ranges_base(0), m_base_obj_offset(DW_INVALID_OFFSET) {}
+ : m_dwarf2Data(dwarf2Data) {}
DWARFCompileUnit::~DWARFCompileUnit() {}
-void DWARFCompileUnit::Clear() {
- m_offset = DW_INVALID_OFFSET;
- m_length = 0;
- m_version = 0;
- m_abbrevs = NULL;
- m_addr_size = DWARFCompileUnit::GetDefaultAddressSize();
- m_base_addr = 0;
- m_die_array.clear();
- m_func_aranges_ap.reset();
- m_user_data = NULL;
- m_producer = eProducerInvalid;
- m_language_type = eLanguageTypeUnknown;
- m_is_dwarf64 = false;
- m_is_optimized = eLazyBoolCalculate;
- m_addr_base = 0;
- m_base_obj_offset = DW_INVALID_OFFSET;
-}
+DWARFCompileUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
+ lldb::offset_t *offset_ptr) {
+ DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(dwarf2Data));
+ // Out of memory?
+ if (cu_sp.get() == NULL)
+ return nullptr;
-bool DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info,
- lldb::offset_t *offset_ptr) {
- Clear();
+ const DWARFDataExtractor &debug_info = dwarf2Data->get_debug_info_data();
- m_offset = *offset_ptr;
+ cu_sp->m_offset = *offset_ptr;
if (debug_info.ValidOffset(*offset_ptr)) {
dw_offset_t abbr_offset;
- const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev();
- m_length = debug_info.GetDWARFInitialLength(offset_ptr);
- m_is_dwarf64 = debug_info.IsDWARF64();
- m_version = debug_info.GetU16(offset_ptr);
+ const DWARFDebugAbbrev *abbr = dwarf2Data->DebugAbbrev();
+ cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
+ cu_sp->m_is_dwarf64 = debug_info.IsDWARF64();
+ cu_sp->m_version = debug_info.GetU16(offset_ptr);
abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
- m_addr_size = debug_info.GetU8(offset_ptr);
+ cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
- bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset() - 1);
- bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
+ bool length_OK =
+ debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
+ bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version);
bool abbr_offset_OK =
- m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
- bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
+ dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
+ bool addr_size_OK = (cu_sp->m_addr_size == 4) || (cu_sp->m_addr_size == 8);
if (length_OK && version_OK && addr_size_OK && abbr_offset_OK &&
abbr != NULL) {
- m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
- return true;
+ cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
+ return cu_sp;
}
// reset the offset to where we tried to parse from if anything went wrong
- *offset_ptr = m_offset;
+ *offset_ptr = cu_sp->m_offset;
}
- return false;
+ return nullptr;
}
void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) {
@@ -620,6 +600,10 @@ void DWARFCompileUnit::Index(NameToDIE &func_basenames,
NameToDIE &objc_class_selectors,
NameToDIE &globals, NameToDIE &types,
NameToDIE &namespaces) {
+ assert(!m_dwarf2Data->GetBaseCompileUnit() &&
+ "DWARFCompileUnit associated with .dwo or .dwp "
+ "should not be indexed directly");
+
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index 430251337575a..8ea0d6465adf4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -18,6 +18,8 @@ class NameToDIE;
class SymbolFileDWARF;
class SymbolFileDWARFDwo;
+typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
+
class DWARFCompileUnit {
public:
enum Producer {
@@ -28,39 +30,35 @@ public:
eProcucerOther
};
- DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
+ static DWARFCompileUnitSP Extract(SymbolFileDWARF *dwarf2Data,
+ lldb::offset_t *offset_ptr);
~DWARFCompileUnit();
- bool Extract(const lldb_private::DWARFDataExtractor &debug_info,
- lldb::offset_t *offset_ptr);
size_t ExtractDIEsIfNeeded(bool cu_die_only);
DWARFDIE LookupAddress(const dw_addr_t address);
size_t AppendDIEsWithTag(const dw_tag_t tag,
DWARFDIECollection &matching_dies,
uint32_t depth = UINT32_MAX) const;
- void Clear();
bool Verify(lldb_private::Stream *s) const;
void Dump(lldb_private::Stream *s) const;
+ // Offset of the initial length field.
dw_offset_t GetOffset() const { return m_offset; }
lldb::user_id_t GetID() const;
- uint32_t Size() const {
- return m_is_dwarf64 ? 23
- : 11; /* Size in bytes of the compile unit header */
- }
+ // Size in bytes of the initial length + compile unit header.
+ uint32_t Size() const { return m_is_dwarf64 ? 23 : 11; }
bool ContainsDIEOffset(dw_offset_t die_offset) const {
return die_offset >= GetFirstDIEOffset() &&
die_offset < GetNextCompileUnitOffset();
}
dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
dw_offset_t GetNextCompileUnitOffset() const {
- return m_offset + m_length + (m_is_dwarf64 ? 12 : 4);
+ return m_offset + (m_is_dwarf64 ? 12 : 4) + m_length;
}
+ // Size of the CU data (without initial length and without header).
size_t GetDebugInfoSize() const {
- return m_length + (m_is_dwarf64 ? 12 : 4) - Size(); /* Size in bytes of the
- .debug_info data
- associated with this
- compile unit. */
+ return (m_is_dwarf64 ? 12 : 4) + m_length - Size();
}
+ // Size of the CU data incl. header but without initial length.
uint32_t GetLength() const { return m_length; }
uint16_t GetVersion() const { return m_version; }
const DWARFAbbreviationDeclarationSet *GetAbbreviations() const {
@@ -165,7 +163,7 @@ protected:
SymbolFileDWARF *m_dwarf2Data;
std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
const DWARFAbbreviationDeclarationSet *m_abbrevs;
- void *m_user_data;
+ void *m_user_data = nullptr;
DWARFDebugInfoEntry::collection
m_die_array; // The compile unit debug information entry item
std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to
@@ -174,23 +172,24 @@ protected:
// points to the exact
// DW_TAG_subprogram
// DIEs
- dw_addr_t m_base_addr;
+ dw_addr_t m_base_addr = 0;
+ // Offset of the initial length field.
dw_offset_t m_offset;
dw_offset_t m_length;
uint16_t m_version;
uint8_t m_addr_size;
- Producer m_producer;
- uint32_t m_producer_version_major;
- uint32_t m_producer_version_minor;
- uint32_t m_producer_version_update;
- lldb::LanguageType m_language_type;
+ Producer m_producer = eProducerInvalid;
+ uint32_t m_producer_version_major = 0;
+ uint32_t m_producer_version_minor = 0;
+ uint32_t m_producer_version_update = 0;
+ lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
bool m_is_dwarf64;
- lldb_private::LazyBool m_is_optimized;
- dw_addr_t m_addr_base; // Value of DW_AT_addr_base
- dw_addr_t m_ranges_base; // Value of DW_AT_ranges_base
- dw_offset_t m_base_obj_offset; // If this is a dwo compile unit this is the
- // offset of the base compile unit in the main
- // object file
+ lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
+ dw_addr_t m_addr_base = 0; // Value of DW_AT_addr_base
+ dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base
+ // If this is a dwo compile unit this is the offset of the base compile unit
+ // in the main object file
+ dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
void ParseProducerInfo();
@@ -203,6 +202,8 @@ protected:
NameToDIE &globals, NameToDIE &types, NameToDIE &namespaces);
private:
+ DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
+
const DWARFDebugInfoEntry *GetCompileUnitDIEPtrOnly() {
ExtractDIEsIfNeeded(true);
if (m_die_array.empty())
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 5222419d3233e..4ef2e772ea5d3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -392,17 +392,11 @@ lldb::ModuleSP DWARFDIE::GetContainingDWOModule() const {
}
bool DWARFDIE::HasChildren() const {
- if (m_die)
- return m_die->HasChildren();
- else
- return false;
+ return m_die && m_die->HasChildren();
}
bool DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
- if (IsValid())
- return GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
- else
- return false;
+ return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
}
size_t DWARFDIE::GetAttributes(DWARFAttributes &attributes,
@@ -464,5 +458,5 @@ bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs) {
}
bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) {
- return lhs.GetDIE() != rhs.GetDIE() || lhs.GetCU() != rhs.GetCU();
+ return !(lhs == rhs);
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
index d681925daeacc..1cf0e7eeeb600 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -98,6 +98,21 @@ dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(
}
//----------------------------------------------------------------------
+// DWARFAbbreviationDeclarationSet::GetUnsupportedForms()
+//----------------------------------------------------------------------
+void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
+ std::set<dw_form_t> &invalid_forms) const {
+ for (const auto &abbr_decl : m_decls) {
+ const size_t num_attrs = abbr_decl.NumAttributes();
+ for (size_t i=0; i<num_attrs; ++i) {
+ dw_form_t form = abbr_decl.GetFormByIndex(i);
+ if (!DWARFFormValue::FormIsSupported(form))
+ invalid_forms.insert(form);
+ }
+ }
+}
+
+//----------------------------------------------------------------------
// Encode
//
// Encode the abbreviation table onto the end of the buffer provided
@@ -175,3 +190,12 @@ DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
return &(pos->second);
return NULL;
}
+
+//----------------------------------------------------------------------
+// DWARFDebugAbbrev::GetUnsupportedForms()
+//----------------------------------------------------------------------
+void DWARFDebugAbbrev::GetUnsupportedForms(
+ std::set<dw_form_t> &invalid_forms) const {
+ for (const auto &pair : m_abbrevCollMap)
+ pair.second.GetUnsupportedForms(invalid_forms);
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
index 137c81780513c..2bacb6349b6fc 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -41,6 +41,7 @@ public:
// void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
dw_uleb128_t
AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration &abbrevDecl);
+ void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
const DWARFAbbreviationDeclaration *
GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const;
@@ -65,6 +66,7 @@ public:
GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
void Dump(lldb_private::Stream *s) const;
void Parse(const lldb_private::DWARFDataExtractor &data);
+ void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
protected:
DWARFAbbreviationDeclarationCollMap m_abbrevCollMap;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index eff9850d435dd..9c0f1d3c89056 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -97,17 +97,8 @@ void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() {
if (m_compile_units.empty()) {
if (m_dwarf2Data != NULL) {
lldb::offset_t offset = 0;
- const DWARFDataExtractor &debug_info_data =
- m_dwarf2Data->get_debug_info_data();
- while (debug_info_data.ValidOffset(offset)) {
- DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(m_dwarf2Data));
- // Out of memory?
- if (cu_sp.get() == NULL)
- break;
-
- if (cu_sp->Extract(debug_info_data, &offset) == false)
- break;
-
+ DWARFCompileUnitSP cu_sp;
+ while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, &offset))) {
m_compile_units.push_back(cu_sp);
offset = cu_sp->GetNextCompileUnitOffset();
@@ -248,12 +239,10 @@ void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
if (dwarf2Data) {
lldb::offset_t offset = 0;
uint32_t depth = 0;
- DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data));
- if (cu.get() == NULL)
- return;
DWARFDebugInfoEntry die;
- while (cu->Extract(dwarf2Data->get_debug_info_data(), &offset)) {
+ DWARFCompileUnitSP cu;
+ while ((cu = DWARFCompileUnit::Extract(dwarf2Data, &offset))) {
const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();
depth = 0;
@@ -288,12 +277,6 @@ void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
break;
- // See if during the callback anyone retained a copy of the compile
- // unit other than ourselves and if so, let whomever did own the object
- // and create a new one for our own use!
- if (!cu.unique())
- cu.reset(new DWARFCompileUnit(dwarf2Data));
-
// Make sure we start on a proper
offset = next_cu_offset;
}
@@ -507,80 +490,3 @@ void DWARFDebugInfo::Dump(Stream *s, const uint32_t die_offset,
die.Dump(s, recurse_depth);
}
}
-
-//----------------------------------------------------------------------
-// FindCallbackString
-//
-// A callback function for the static DWARFDebugInfo::Parse() function
-// that gets called each time a compile unit header or debug information
-// entry is successfully parsed.
-//
-// This function will find the die_offset of any items whose DW_AT_name
-// matches the given string
-//----------------------------------------------------------------------
-typedef struct FindCallbackStringInfoTag {
- const char *name;
- bool ignore_case;
- RegularExpression *regex;
- vector<dw_offset_t> &die_offsets;
-} FindCallbackStringInfo;
-
-static dw_offset_t
-FindCallbackString(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
- DWARFDebugInfoEntry *die, const dw_offset_t next_offset,
- const uint32_t curr_depth, void *userData) {
- FindCallbackStringInfo *info = (FindCallbackStringInfo *)userData;
-
- if (!die)
- return next_offset;
-
- const char *die_name = die->GetName(dwarf2Data, cu);
- if (!die_name)
- return next_offset;
-
- if (info->regex) {
- if (info->regex->Execute(llvm::StringRef(die_name)))
- info->die_offsets.push_back(die->GetOffset());
- } else {
- if ((info->ignore_case ? strcasecmp(die_name, info->name)
- : strcmp(die_name, info->name)) == 0)
- info->die_offsets.push_back(die->GetOffset());
- }
-
- // Just return the current offset to parse the next CU or DIE entry
- return next_offset;
-}
-
-//----------------------------------------------------------------------
-// Find
-//
-// Finds all DIE that have a specific DW_AT_name attribute by manually
-// searching through the debug information (not using the
-// .debug_pubnames section). The string must match the entire name
-// and case sensitive searches are an option.
-//----------------------------------------------------------------------
-bool DWARFDebugInfo::Find(const char *name, bool ignore_case,
- vector<dw_offset_t> &die_offsets) const {
- die_offsets.clear();
- if (name && name[0]) {
- FindCallbackStringInfo info = {name, ignore_case, NULL, die_offsets};
- DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
- }
- return !die_offsets.empty();
-}
-
-//----------------------------------------------------------------------
-// Find
-//
-// Finds all DIE that have a specific DW_AT_name attribute by manually
-// searching through the debug information (not using the
-// .debug_pubnames section). The string must match the supplied regular
-// expression.
-//----------------------------------------------------------------------
-bool DWARFDebugInfo::Find(RegularExpression &re,
- vector<dw_offset_t> &die_offsets) const {
- die_offsets.clear();
- FindCallbackStringInfo info = {NULL, false, &re, die_offsets};
- DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
- return !die_offsets.empty();
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index be4e18b12be0b..14c7d767d05b4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -50,10 +50,6 @@ public:
static void Verify(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data);
static void Dump(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data,
const uint32_t die_offset, const uint32_t recurse_depth);
- bool Find(const char *name, bool ignore_case,
- std::vector<dw_offset_t> &die_offsets) const;
- bool Find(lldb_private::RegularExpression &re,
- std::vector<dw_offset_t> &die_offsets) const;
enum {
eDumpFlag_Verbose = (1 << 0), // Verbose dumping
@@ -65,8 +61,6 @@ public:
DWARFDebugAranges &GetCompileUnitAranges();
protected:
- typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
-
static bool OffsetLessThanCompileUnitOffset(dw_offset_t offset,
const DWARFCompileUnitSP &cu_sp);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 8d87c201eceb2..f595bd83d8469 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -161,9 +161,9 @@ bool DWARFDebugInfoEntry::FastExtract(
case DW_FORM_strp:
case DW_FORM_sec_offset:
if (cu->IsDWARF64())
- debug_info_data.GetU64(offset_ptr);
+ debug_info_data.GetU64(&offset);
else
- debug_info_data.GetU32(offset_ptr);
+ debug_info_data.GetU32(&offset);
break;
default:
@@ -325,9 +325,9 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
case DW_FORM_strp:
case DW_FORM_sec_offset:
if (cu->IsDWARF64())
- debug_info_data.GetU64(offset_ptr);
+ debug_info_data.GetU64(&offset);
else
- debug_info_data.GetU32(offset_ptr);
+ debug_info_data.GetU32(&offset);
break;
default:
@@ -1314,19 +1314,6 @@ bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
return false;
}
-bool DWARFDebugInfoEntry::Contains(const DWARFDebugInfoEntry *die) const {
- if (die) {
- const dw_offset_t die_offset = die->GetOffset();
- if (die_offset > GetOffset()) {
- const DWARFDebugInfoEntry *sibling = GetSibling();
- assert(sibling); // TODO: take this out
- if (sibling)
- return die_offset < sibling->GetOffset();
- }
- }
- return false;
-}
-
//----------------------------------------------------------------------
// BuildAddressRangeTable
//----------------------------------------------------------------------
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 15abac77a475d..89450d327adfd 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -60,18 +60,6 @@ public:
m_empty_children(false), m_abbr_idx(0), m_has_children(false),
m_tag(0) {}
- void Clear() {
- m_offset = DW_INVALID_OFFSET;
- m_parent_idx = 0;
- m_sibling_idx = 0;
- m_empty_children = false;
- m_abbr_idx = 0;
- m_has_children = false;
- m_tag = 0;
- }
-
- bool Contains(const DWARFDebugInfoEntry *die) const;
-
void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
const DWARFCompileUnit *cu,
DWARFDebugAranges *debug_aranges) const;
@@ -211,8 +199,6 @@ public:
dw_offset_t GetOffset() const { return m_offset; }
- void SetOffset(dw_offset_t offset) { m_offset = offset; }
-
bool HasChildren() const { return m_has_children; }
void SetHasChildren(bool b) { m_has_children = b; }
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 515c083fedb08..a8c48b7f2f849 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -15,6 +15,18 @@
using namespace lldb_private;
using namespace std;
+static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) {
+ switch(addr_size) {
+ case 2:
+ return 0xffff;
+ case 4:
+ return 0xffffffff;
+ case 8:
+ return 0xffffffffffffffff;
+ }
+ llvm_unreachable("GetBaseAddressMarker unsupported address size.");
+}
+
DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
DWARFDebugRanges::~DWARFDebugRanges() {}
@@ -39,38 +51,27 @@ bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data,
const DWARFDataExtractor &debug_ranges_data =
dwarf2Data->get_debug_ranges_data();
uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
+ dw_addr_t base_addr = 0;
+ dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size);
while (
debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+
if (!begin && !end) {
// End of range list
break;
}
- // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
- // of ones
- switch (addr_size) {
- case 2:
- if (begin == 0xFFFFull)
- begin = LLDB_INVALID_ADDRESS;
- break;
-
- case 4:
- if (begin == 0xFFFFFFFFull)
- begin = LLDB_INVALID_ADDRESS;
- break;
- case 8:
- break;
-
- default:
- llvm_unreachable("DWARFRangeList::Extract() unsupported address size.");
+ if (begin == base_addr_marker) {
+ base_addr = end;
+ continue;
}
// Filter out empty ranges
if (begin < end)
- range_list.Append(DWARFRangeList::Entry(begin, end - begin));
+ range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin));
}
// Make sure we consumed at least something
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index 0853671ee8749..a21e313c2f811 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -725,3 +725,39 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,
}
return -1;
}
+
+bool DWARFFormValue::FormIsSupported(dw_form_t form) {
+ switch (form) {
+ case DW_FORM_addr:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_string:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_sdata:
+ case DW_FORM_strp:
+ case DW_FORM_udata:
+ case DW_FORM_ref_addr:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ case DW_FORM_indirect:
+ case DW_FORM_sec_offset:
+ case DW_FORM_exprloc:
+ case DW_FORM_flag_present:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_addr_index:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 8d6af3d65b331..2aa7460c49109 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -86,6 +86,7 @@ public:
bool is_dwarf64);
static int Compare(const DWARFFormValue &a, const DWARFFormValue &b);
void Clear();
+ static bool FormIsSupported(dw_form_t form);
protected:
const DWARFCompileUnit *m_cu; // Compile unit for this form
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ef18c2b5d3bab..f149ec354f08c 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -13,7 +13,6 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -22,6 +21,7 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
@@ -30,6 +30,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueProperties.h"
@@ -53,7 +54,7 @@
#include "lldb/Target/Language.h"
-#include "lldb/Utility/TaskPool.h"
+#include "lldb/Host/TaskPool.h"
#include "DWARFASTParser.h"
#include "DWARFASTParserClang.h"
@@ -71,6 +72,7 @@
#include "LogChannelDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
#include "SymbolFileDWARFDwo.h"
+#include "SymbolFileDWARFDwp.h"
#include "llvm/Support/FileSystem.h"
@@ -207,6 +209,10 @@ static const char *resolveCompDir(const char *path_from_dwarf) {
return nullptr;
}
+DWARFCompileUnit *SymbolFileDWARF::GetBaseCompileUnit() {
+ return nullptr;
+}
+
void SymbolFileDWARF::Initialize() {
LogChannelDWARF::Initialize();
PluginManager::RegisterPlugin(GetPluginNameStatic(),
@@ -435,13 +441,11 @@ void SymbolFileDWARF::InitializeObject() {
ModuleSP module_sp(m_obj_file->GetModule());
if (module_sp) {
const SectionList *section_list = module_sp->GetSectionList();
- const Section *section =
+ Section *section =
section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
- // Memory map the DWARF mach-o segment so we have everything mmap'ed
- // to keep our heap memory usage down.
if (section)
- m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
+ m_obj_file->ReadSectionData(section, m_dwarf_data);
}
get_apple_names_data();
@@ -497,6 +501,21 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
if (section_list == NULL)
return 0;
+ // On non Apple platforms we might have .debug_types debug info that
+ // is created by using "-fdebug-types-section". LLDB currently will try
+ // to load this debug info, but it causes crashes during debugging when
+ // types are missing since it doesn't know how to parse the info in
+ // the .debug_types type units. This causes all complex debug info
+ // types to be unresolved. Because this causes LLDB to crash and since
+ // it really doesn't provide a solid debuggiung experience, we should
+ // disable trying to debug this kind of DWARF until support gets
+ // added or deprecated.
+ if (section_list->FindSectionByName(ConstString(".debug_types"))) {
+ m_obj_file->GetModule()->ReportWarning(
+ "lldb doesn’t support .debug_types debug info");
+ return 0;
+ }
+
uint64_t debug_abbrev_file_size = 0;
uint64_t debug_info_file_size = 0;
uint64_t debug_line_file_size = 0;
@@ -517,6 +536,20 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
if (section)
debug_abbrev_file_size = section->GetFileSize();
+ DWARFDebugAbbrev *abbrev = DebugAbbrev();
+ if (abbrev) {
+ std::set<dw_form_t> invalid_forms;
+ abbrev->GetUnsupportedForms(invalid_forms);
+ if (!invalid_forms.empty()) {
+ StreamString error;
+ error.Printf("unsupported DW_FORM value%s:", invalid_forms.size() > 1 ? "s" : "");
+ for (auto form : invalid_forms)
+ error.Printf(" %#x", form);
+ m_obj_file->GetModule()->ReportWarning("%s", error.GetString().str().c_str());
+ return 0;
+ }
+ }
+
section =
section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true)
.get();
@@ -1539,6 +1572,16 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (!dwo_name)
return nullptr;
+ SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile();
+ if (dwp_symfile) {
+ uint64_t dwo_id = cu_die.GetAttributeValueAsUnsigned(this, &dwarf_cu,
+ DW_AT_GNU_dwo_id, 0);
+ std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile =
+ dwp_symfile->GetSymbolFileForDwoId(&dwarf_cu, dwo_id);
+ if (dwo_symfile)
+ return dwo_symfile;
+ }
+
FileSpec dwo_file(dwo_name, true);
if (dwo_file.IsRelative()) {
const char *comp_dir = cu_die.GetAttributeValueAsString(
@@ -1600,7 +1643,29 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
}
dwo_module_spec.GetArchitecture() =
m_obj_file->GetModule()->GetArchitecture();
- // printf ("Loading dwo = '%s'\n", dwo_path);
+
+ // When LLDB loads "external" modules it looks at the
+ // presence of DW_AT_GNU_dwo_name.
+ // However, when the already created module
+ // (corresponding to .dwo itself) is being processed,
+ // it will see the presence of DW_AT_GNU_dwo_name
+ // (which contains the name of dwo file) and
+ // will try to call ModuleList::GetSharedModule again.
+ // In some cases (i.e. for empty files) Clang 4.0
+ // generates a *.dwo file which has DW_AT_GNU_dwo_name,
+ // but no DW_AT_comp_dir. In this case the method
+ // ModuleList::GetSharedModule will fail and
+ // the warning will be printed. However, as one can notice
+ // in this case we don't actually need to try to load the already
+ // loaded module (corresponding to .dwo) so we simply skip it.
+ if (m_obj_file->GetFileSpec()
+ .GetFileNameExtension()
+ .GetStringRef() == "dwo" &&
+ llvm::StringRef(m_obj_file->GetFileSpec().GetPath())
+ .endswith(dwo_module_spec.GetFileSpec().GetPath())) {
+ continue;
+ }
+
Status error = ModuleList::GetSharedModule(
dwo_module_spec, module_sp, NULL, NULL, NULL);
if (!module_sp) {
@@ -1640,9 +1705,8 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
const DWARFExpression &location = var_sp->LocationExpression();
Value location_result;
Status error;
- if (location.Evaluate(nullptr, nullptr, nullptr,
- LLDB_INVALID_ADDRESS, nullptr, nullptr,
- location_result, &error)) {
+ if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr,
+ nullptr, location_result, &error)) {
if (location_result.GetValueType() ==
Value::eValueTypeFileAddress) {
lldb::addr_t file_addr =
@@ -4288,3 +4352,18 @@ DWARFExpression::LocationListFormat
SymbolFileDWARF::GetLocationListFormat() const {
return DWARFExpression::RegularLocationList;
}
+
+SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
+ llvm::call_once(m_dwp_symfile_once_flag, [this]() {
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec() = m_obj_file->GetFileSpec();
+ module_spec.GetSymbolFileSpec() =
+ FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp", false);
+ FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec);
+ if (dwp_filespec.Exists()) {
+ m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(),
+ dwp_filespec);
+ }
+ });
+ return m_dwp_symfile.get();
+}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 9b1eb1d76fea9..6902dc0333d2f 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -61,6 +61,7 @@ class DWARFDIECollection;
class DWARFFormValue;
class SymbolFileDWARFDebugMap;
class SymbolFileDWARFDwo;
+class SymbolFileDWARFDwp;
#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1)
@@ -275,8 +276,8 @@ public:
GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
uint32_t cu_idx = UINT32_MAX);
- size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
- DIEArray &method_die_offsets);
+ virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
+ DIEArray &method_die_offsets);
bool Supports_DW_AT_APPLE_objc_complete_type(DWARFCompileUnit *cu);
@@ -298,6 +299,11 @@ public:
GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu,
const DWARFDebugInfoEntry &cu_die);
+ // For regular SymbolFileDWARF instances the method returns nullptr,
+ // for the instances of the subclass SymbolFileDWARFDwo
+ // the method returns a pointer to the base compile unit.
+ virtual DWARFCompileUnit *GetBaseCompileUnit();
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@@ -391,14 +397,10 @@ protected:
virtual lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
- lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
const DWARFDIE &die, const lldb_private::ConstString &type_name,
bool must_be_implementation);
- lldb::TypeSP
- FindCompleteObjCDefinitionType(const lldb_private::ConstString &type_name,
- bool header_definition_ok);
-
lldb_private::Symbol *
GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name);
@@ -464,8 +466,14 @@ protected:
return m_forward_decl_clang_type_to_die;
}
+ SymbolFileDWARFDwp *GetDwpSymbolFile();
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap *m_debug_map_symfile;
+
+ llvm::once_flag m_dwp_symfile_once_flag;
+ std::unique_ptr<SymbolFileDWARFDwp> m_dwp_symfile;
+
lldb_private::DWARFDataExtractor m_dwarf_data;
DWARFDataSegment m_data_debug_abbrev;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index c14ebd1628be6..17c188a41a773 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -61,6 +61,14 @@ SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
}
DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() {
+ // A clang module is found via a skeleton CU, but is not a proper DWO.
+ // Clang modules have a .debug_info section instead of the *_dwo variant.
+ if (auto *section_list = m_obj_file->GetSectionList(false))
+ if (auto section_sp =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true))
+ if (!section_sp->GetName().GetStringRef().endswith("dwo"))
+ return nullptr;
+
// Only dwo files with 1 compile unit is supported
if (GetNumCompileUnits() == 1)
return DebugInfo()->GetCompileUnitAtIndex(0);
@@ -91,6 +99,12 @@ 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();
}
@@ -101,6 +115,17 @@ lldb::TypeSP SymbolFileDWARFDwo::FindDefinitionTypeForDWARFDeclContext(
die_decl_ctx);
}
+lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ bool must_be_implementation) {
+ return GetBaseSymbolFile()->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name, must_be_implementation);
+}
+
+DWARFCompileUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() {
+ return m_base_dwarf_cu;
+}
+
SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() {
return m_base_dwarf_cu->GetSymbolFileDWARF();
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 8cd67a2b24247..b67967aafab26 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -33,6 +33,9 @@ public:
lldb_private::DWARFExpression::LocationListFormat
GetLocationListFormat() const override;
+ size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
+ DIEArray &method_die_offsets) override;
+
lldb_private::TypeSystem *
GetTypeSystemForLanguage(lldb::LanguageType language) override;
@@ -45,6 +48,8 @@ public:
return nullptr;
}
+ DWARFCompileUnit *GetBaseCompileUnit() override;
+
protected:
void LoadSectionData(lldb::SectionType sect_type,
lldb_private::DWARFDataExtractor &data) override;
@@ -62,6 +67,10 @@ protected:
lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(
const DWARFDeclContext &die_decl_ctx) override;
+ lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ bool must_be_implementation) override;
+
SymbolFileDWARF *GetBaseSymbolFile();
lldb::ObjectFileSP m_obj_file_sp;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
new file mode 100644
index 0000000000000..f6de1818eae08
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
@@ -0,0 +1,36 @@
+//===-- SymbolFileDWARFDwoDwp.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileDWARFDwoDwp.h"
+
+#include "lldb/Core/Section.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
+ ObjectFileSP objfile,
+ DWARFCompileUnit *dwarf_cu,
+ uint64_t dwo_id)
+ : SymbolFileDWARFDwo(objfile, dwarf_cu), m_dwp_symfile(dwp_symfile),
+ m_dwo_id(dwo_id) {}
+
+void SymbolFileDWARFDwoDwp::LoadSectionData(lldb::SectionType sect_type,
+ DWARFDataExtractor &data) {
+ if (m_dwp_symfile->LoadSectionData(m_dwo_id, sect_type, data))
+ return;
+
+ SymbolFileDWARF::LoadSectionData(sect_type, data);
+}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
new file mode 100644
index 0000000000000..00ad7aafd96b0
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
@@ -0,0 +1,34 @@
+//===-- SymbolFileDWARFDwoDwp.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
+#define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "SymbolFileDWARFDwo.h"
+#include "SymbolFileDWARFDwp.h"
+
+class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo {
+public:
+ SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
+ lldb::ObjectFileSP objfile, DWARFCompileUnit *dwarf_cu,
+ uint64_t dwo_id);
+
+protected:
+ void LoadSectionData(lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data) override;
+
+ SymbolFileDWARFDwp *m_dwp_symfile;
+ uint64_t m_dwo_id;
+};
+
+#endif // SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
new file mode 100644
index 0000000000000..1dc1dab34a5c4
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
@@ -0,0 +1,142 @@
+//===-- 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(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;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
new file mode 100644
index 0000000000000..a7372b9358b16
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
@@ -0,0 +1,55 @@
+//===-- SymbolFileDWARFDwp.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
+#define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
+
+// C Includes
+// C++ Includes
+#include <memory>
+
+// Other libraries and framework includes
+#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+
+// Project includes
+#include "lldb/Core/Module.h"
+
+#include "DWARFDataExtractor.h"
+#include "SymbolFileDWARFDwo.h"
+
+class SymbolFileDWARFDwp {
+public:
+ static std::unique_ptr<SymbolFileDWARFDwp>
+ Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec);
+
+ std::unique_ptr<SymbolFileDWARFDwo>
+ GetSymbolFileForDwoId(DWARFCompileUnit *dwarf_cu, uint64_t dwo_id);
+
+ bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data);
+
+private:
+ explicit SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
+ lldb::ObjectFileSP obj_file);
+
+ bool LoadRawSectionData(lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data);
+
+ void InitDebugCUIndexMap();
+
+ lldb::ObjectFileSP m_obj_file;
+
+ std::mutex m_sections_mutex;
+ std::map<lldb::SectionType, lldb_private::DWARFDataExtractor> m_sections;
+
+ llvm::DWARFUnitIndex m_debug_cu_index;
+ std::map<uint64_t, const llvm::DWARFUnitIndex::Entry *> m_debug_cu_index_map;
+};
+
+#endif // SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_