jankratochvil created this revision.
jankratochvil added a reviewer: clayborg.
jankratochvil added a project: LLDB.
Herald added a subscriber: teemperor.
I cannot update the patch of https://reviews.llvm.org/D32167 so I have created
this new revision for that.
Repository:
rLLDB LLDB
https://reviews.llvm.org/D54670
Files:
packages/Python/lldbsuite/test/lldbtest.py
packages/Python/lldbsuite/test/make/Makefile.rules
packages/Python/lldbsuite/test/plugins/builder_base.py
packages/Python/lldbsuite/test/test_categories.py
source/Plugins/SymbolFile/DWARF/CMakeLists.txt
source/Plugins/SymbolFile/DWARF/DIERef.cpp
source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFUnit.h
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -505,20 +505,6 @@
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;
@@ -900,7 +886,7 @@
cu_sp.reset(new CompileUnit(
module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(),
cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo));
- if (cu_sp) {
+ if (dwarf_cu->GetAsCompileUnit() && cu_sp) {
// If we just created a compile unit with an invalid file spec,
// try and get the first entry in the supports files from the
// line table as that should be the compile unit.
@@ -913,16 +899,16 @@
cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
}
}
+ }
- dwarf_cu->SetUserData(cu_sp.get());
+ dwarf_cu->SetUserData(cu_sp.get());
- // Figure out the compile unit index if we weren't given one
- if (cu_idx == UINT32_MAX)
- DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
+ // Figure out the compile unit index if we weren't given one
+ if (cu_idx == UINT32_MAX)
+ DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cu_idx, cu_sp);
- }
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+ cu_idx, cu_sp);
}
}
}
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -17,12 +17,15 @@
#include <atomic>
class DWARFUnit;
+class DWARFTypeUnit;
class DWARFCompileUnit;
class NameToDIE;
class SymbolFileDWARF;
class SymbolFileDWARFDwo;
typedef std::shared_ptr<DWARFUnit> DWARFUnitSP;
+typedef std::shared_ptr<DWARFTypeUnit> DWARFTypeUnitSP;
+typedef std::shared_ptr<DWARFCompileUnit> DWARFCompileUnitSP;
enum DWARFProducer {
eProducerInvalid = 0,
@@ -39,6 +42,12 @@
public:
virtual ~DWARFUnit();
+ bool ExtractHeader(SymbolFileDWARF *dwarf,
+ const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
+
+ DWARFTypeUnit *GetAsTypeUnit();
+ DWARFCompileUnit *GetAsCompileUnit();
void ExtractUnitDIEIfNeeded();
void ExtractDIEsIfNeeded();
@@ -176,6 +185,10 @@
return die_iterator_range(m_die_array.begin(), m_die_array.end());
}
+ DWARFDIE FindTypeSignatureDIE(uint64_t type_sig) const;
+
+ dw_offset_t FindTypeSignatureDIEOffset(uint64_t type_sig) const;
+
protected:
DWARFUnit(SymbolFileDWARF *dwarf);
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -18,9 +18,11 @@
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
+#include "DWARFCompileUnit.h"
#include "DWARFDIECollection.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
+#include "DWARFTypeUnit.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
#include "SymbolFileDWARFDwo.h"
@@ -429,6 +431,10 @@
void DWARFUnit::BuildAddressRangeTable(SymbolFileDWARF *dwarf,
DWARFDebugAranges *debug_aranges) {
+ // No addresses in a type unit
+ if (GetAsTypeUnit())
+ return;
+
// This function is usually called if there in no .debug_aranges section in
// order to produce a compile unit level set of address ranges that is
// accurate.
@@ -768,6 +774,72 @@
return *m_func_aranges_ap.get();
}
+DWARFDIE DWARFUnit::FindTypeSignatureDIE(uint64_t type_sig) const {
+ if (auto cu = m_dwarf->DebugInfo()->GetTypeUnitForSignature(type_sig))
+ return cu->GetTypeUnitDIE();
+ return DWARFDIE();
+}
+
+dw_offset_t
+DWARFUnit::FindTypeSignatureDIEOffset(uint64_t type_sig) const {
+ if (auto cu = m_dwarf->DebugInfo()->GetTypeUnitForSignature(type_sig))
+ return cu->GetTypeUnitDIEOffset();
+ return DW_INVALID_OFFSET;
+}
+
+DWARFTypeUnit *DWARFUnit::GetAsTypeUnit() {
+ if (GetUnitDIEOnly().Tag() == DW_TAG_type_unit)
+ return static_cast<DWARFTypeUnit *>(this);
+ return nullptr;
+}
+
+DWARFCompileUnit *DWARFUnit::GetAsCompileUnit() {
+ if (GetUnitDIEOnly().Tag() == DW_TAG_compile_unit)
+ return static_cast<DWARFCompileUnit *>(this);
+ return nullptr;
+}
+
+bool
+DWARFUnit::ExtractHeader(SymbolFileDWARF *dwarf,
+ const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ m_offset = *offset_ptr;
+
+ if (data.ValidOffset(*offset_ptr)) {
+ dw_offset_t abbr_offset;
+ const DWARFDebugAbbrev *abbr = dwarf->DebugAbbrev();
+ m_length = data.GetDWARFInitialLength(offset_ptr);
+ m_is_dwarf64 = data.IsDWARF64();
+ m_version = data.GetU16(offset_ptr);
+ if (m_version == 5) {
+ m_unit_type = data.GetU8(offset_ptr);
+ m_addr_size = data.GetU8(offset_ptr);
+ abbr_offset = data.GetDWARFOffset(offset_ptr);
+
+ if (m_unit_type == llvm::dwarf::DW_UT_skeleton)
+ m_dwo_id = data.GetU64(offset_ptr);
+ } else {
+ abbr_offset = data.GetDWARFOffset(offset_ptr);
+ m_addr_size = data.GetU8(offset_ptr);
+ }
+
+ bool length_OK = data.ValidOffset(GetNextCompileUnitOffset() - 1);
+ bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
+ bool abbr_offset_OK =
+ dwarf->get_debug_abbrev_data().ValidOffset(abbr_offset);
+ bool addr_size_OK = (m_addr_size == 4) || (m_addr_size == 8);
+
+ if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr) {
+ m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
+ return m_abbrevs != nullptr;
+ }
+
+ // reset the offset to where we tried to parse from if anything went wrong
+ *offset_ptr = m_offset;
+ }
+ return false;
+}
+
const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const {
return m_dwarf->get_debug_info_data();
}
Index: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
===================================================================
--- /dev/null
+++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
@@ -0,0 +1,85 @@
+//===-- DWARFTypeUnit.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARF_DWARFTypeUnit_h_
+#define SymbolFileDWARF_DWARFTypeUnit_h_
+
+#include "DWARFUnit.h"
+
+class DWARFTypeUnit : public DWARFUnit {
+ friend class DWARFUnit;
+
+public:
+ virtual ~DWARFTypeUnit();
+
+ static DWARFTypeUnitSP Extract(SymbolFileDWARF *dwarf2Data,
+ const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
+
+ void Dump(lldb_private::Stream *s) const override;
+
+ //------------------------------------------------------------------
+ /// Get the size in bytes of the header.
+ ///
+ /// @return
+ /// Byte size of the type unit header
+ //------------------------------------------------------------------
+ uint32_t GetHeaderByteSize() const override {
+ return m_is_dwarf64 ? 39 : 23;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the type DIE offset if this is a type unit.
+ ///
+ /// If this unit is a type unit, return type DIE offset for the type
+ /// in this unit.
+ ///
+ /// @return
+ /// The DIE offset that points to the type unit type if this is
+ /// a type unit, otherwise return DW_INVALID_OFFSET.
+ //------------------------------------------------------------------
+ dw_offset_t GetTypeUnitDIEOffset() {
+ return m_offset + m_type_offset;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the type signature for the type contained in this unit.
+ ///
+ /// @return
+ /// The 64 bit type signature for the type contained in this type
+ /// unit. This value will not be valid if this compile unit is not
+ /// a type unit.
+ //------------------------------------------------------------------
+ uint64_t GetTypeSignature() const { return m_type_signature; }
+
+ //------------------------------------------------------------------
+ /// Get the type DIE if this is a type unit.
+ ///
+ /// If this unit is a type unit, return type contained within it as
+ /// a DWARFDIE object.
+ ///
+ /// @return
+ /// The DIE representing the type if this is a type unit, or an
+ /// invalid DWARFDIE if this is not a type unit.
+ //------------------------------------------------------------------
+ DWARFDIE GetTypeUnitDIE();
+
+protected:
+ // Type signature contained in a type unit which will be valid (non-zero)
+ // for type units only.
+ uint64_t m_type_signature = 0;
+ // Compile unit relative type offset for type units only.
+ dw_offset_t m_type_offset = DW_INVALID_OFFSET;
+
+private:
+ DWARFTypeUnit(SymbolFileDWARF *dwarf2Data);
+ DISALLOW_COPY_AND_ASSIGN(DWARFTypeUnit);
+};
+
+#endif // SymbolFileDWARF_DWARFTypeUnit_h_
Index: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
===================================================================
--- /dev/null
+++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
@@ -0,0 +1,53 @@
+//===-- DWARFTypeUnit.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFTypeUnit.h"
+#include "DWARFDataExtractor.h"
+#include "SymbolFileDWARF.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+DWARFTypeUnit::DWARFTypeUnit(SymbolFileDWARF *dwarf2Data)
+ : DWARFUnit(dwarf2Data) {}
+
+DWARFTypeUnit::~DWARFTypeUnit() {}
+
+void DWARFTypeUnit::Dump(Stream *s) const {
+ s->Printf("0x%8.8x: Type Unit: length = 0x%8.8x, version = 0x%4.4x, "
+ "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x, "
+ "type_signature = 0x%16.16" PRIx64 ", type_offset = 0x%8.8x "
+ "(next CU at {0x%8.8x})\n",
+ m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size,
+ m_type_signature, m_type_offset, GetNextCompileUnitOffset());
+}
+
+DWARFTypeUnitSP DWARFTypeUnit::Extract(SymbolFileDWARF *dwarf,
+ const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr) {
+ // std::make_shared would require the ctor to be public.
+ std::shared_ptr<DWARFTypeUnit> cu_sp(new DWARFTypeUnit(dwarf));
+ // Out of memory?
+ if (!cu_sp)
+ return nullptr;
+ if (cu_sp->ExtractHeader(dwarf, data, offset_ptr)) {
+ cu_sp->m_type_signature = data.GetU64(offset_ptr);
+ cu_sp->m_type_offset = data.GetDWARFOffset(offset_ptr);
+ return cu_sp;
+ }
+ // reset the offset to where we tried to parse from if anything went wrong
+ *offset_ptr = cu_sp->m_offset;
+ return nullptr;
+}
+
+DWARFDIE DWARFTypeUnit::GetTypeUnitDIE() {
+ // The type offset is compile unit relative, so we need to add the compile
+ // unit offset to ensure we get the correct DIE.
+ return GetDIE(GetTypeUnitDIEOffset());
+}
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -10,6 +10,7 @@
#ifndef SymbolFileDWARF_DWARFFormValue_h_
#define SymbolFileDWARF_DWARFFormValue_h_
+#include "DWARFDIE.h"
#include "DWARFDataExtractor.h"
#include <stddef.h>
@@ -73,6 +74,7 @@
const uint8_t *BlockData() const;
uint64_t Reference() const;
uint64_t Reference(dw_offset_t offset) const;
+ DWARFDIE GetTypeSignatureDIE() const;
bool Boolean() const { return m_value.value.uval != 0; }
uint64_t Unsigned() const { return m_value.value.uval; }
void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -629,6 +629,13 @@
die_offset += m_cu->GetOffset();
break;
+ case DW_FORM_ref_sig8:
+ // CU must be valid since we will need to back up into the debug info and
+ // find the DIE offset of the type in the type unit.
+ assert(m_cu);
+ die_offset = m_cu->FindTypeSignatureDIEOffset(m_value.value.uval);
+ break;
+
default:
break;
}
@@ -647,13 +654,32 @@
die_offset += base_offset;
break;
+ case DW_FORM_ref_sig8:
+ // CU must be valid since we will need to back up into the debug info and
+ // find the DIE offset of the type in the type unit.
+ assert(m_cu);
+ die_offset =
+ m_cu->FindTypeSignatureDIEOffset(m_value.value.uval) + base_offset;
+ break;
+
default:
break;
}
return die_offset;
}
+DWARFDIE DWARFFormValue::GetTypeSignatureDIE() const {
+ if (m_form == DW_FORM_ref_sig8) {
+ // CU must be valid since we will need to back up into the debug info and
+ // find the DIE offset of the type in the type unit.
+ assert(m_cu);
+ return m_cu->FindTypeSignatureDIE(m_value.value.uval);
+ }
+
+ return DWARFDIE();
+}
+
const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -11,14 +11,17 @@
#define SymbolFileDWARF_DWARFDebugInfo_h_
#include <map>
+#include <unordered_map>
#include <vector>
#include "DWARFUnit.h"
#include "DWARFDIE.h"
#include "SymbolFileDWARF.h"
#include "lldb/Core/STLUtils.h"
#include "lldb/lldb-private.h"
+class DWARFTypeUnit;
+
typedef std::multimap<const char *, dw_offset_t, CStringCompareFunctionObject>
CStringToDIEMap;
typedef CStringToDIEMap::iterator CStringToDIEMapIter;
@@ -38,6 +41,7 @@
size_t GetNumCompileUnits();
bool ContainsCompileUnit(const DWARFUnit *cu) const;
DWARFUnit *GetCompileUnitAtIndex(uint32_t idx);
+ DWARFTypeUnit *GetTypeUnitForSignature(uint64_t type_sig);
DWARFUnit *GetCompileUnit(dw_offset_t cu_offset, uint32_t *idx_ptr = NULL);
DWARFUnit *GetCompileUnitContainingDIEOffset(dw_offset_t die_offset);
DWARFUnit *GetCompileUnit(const DIERef &die_ref);
@@ -58,12 +62,14 @@
const DWARFUnitSP &cu_sp);
typedef std::vector<DWARFUnitSP> CompileUnitColl;
+ typedef llvm::DenseMap<uint64_t, uint32_t> TypeSignatureMap;
//----------------------------------------------------------------------
// Member variables
//----------------------------------------------------------------------
SymbolFileDWARF *m_dwarf2Data;
CompileUnitColl m_compile_units;
+ TypeSignatureMap m_type_sig_to_cu_index;
std::unique_ptr<DWARFDebugAranges>
m_cu_aranges_ap; // A quick address to compile unit table
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -23,6 +23,7 @@
#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFFormValue.h"
+#include "DWARFTypeUnit.h"
#include "LogChannelDWARF.h"
using namespace lldb;
@@ -94,18 +95,37 @@
}
void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() {
- if (m_compile_units.empty()) {
- if (m_dwarf2Data != NULL) {
- lldb::offset_t offset = 0;
- DWARFUnitSP cu_sp;
- const auto &debug_info_data = m_dwarf2Data->get_raw_debug_info_data();
- while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
- &offset))) {
- m_compile_units.push_back(cu_sp);
-
- offset = cu_sp->GetNextCompileUnitOffset();
- }
- }
+ if (!m_compile_units.empty())
+ return;
+
+ if (m_dwarf2Data == nullptr)
+ return;
+
+ lldb::offset_t offset = 0;
+ DWARFCompileUnitSP cu_sp;
+ const auto &raw_debug_info_data = m_dwarf2Data->get_raw_debug_info_data();
+ while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, raw_debug_info_data,
+ &offset))) {
+ m_compile_units.push_back(cu_sp);
+ offset = cu_sp->GetNextCompileUnitOffset();
+ }
+
+ // If we have a separate .debug_types section, it means we are using DWARF4
+ // or earlier where type units are a separate section. All data in the
+ // .debug_types section doesn't refer directly to any other DIEs, all
+ // references are done via type signatures. With this in mind, we can support
+ // parsing .debug_types by pretending that the data in .debug_types
+ // follows all data in the .debug_info section. This allows all
+ // types in the .debug_types to have a unique DIE offset that is:
+ // offset = sizeof(.debug_info) + (possible gap) + debug_type_offset
+ const auto &debug_info_data = m_dwarf2Data->get_debug_info_data();
+ offset = m_dwarf2Data->get_debug_types_offset();
+ DWARFTypeUnitSP tu_sp;
+ while ((tu_sp = DWARFTypeUnit::Extract(m_dwarf2Data, debug_info_data,
+ &offset))) {
+ m_type_sig_to_cu_index[tu_sp->GetTypeSignature()] = m_compile_units.size();
+ m_compile_units.push_back(tu_sp);
+ offset = tu_sp->GetNextCompileUnitOffset();
}
}
@@ -226,3 +246,9 @@
return DWARFDIE(); // Not found
}
+DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForSignature(uint64_t type_sig) {
+ auto pos = m_type_sig_to_cu_index.find(type_sig);
+ if (pos != m_type_sig_to_cu_index.end())
+ return GetCompileUnitAtIndex(pos->second)->GetAsTypeUnit();
+ return nullptr;
+}
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -14,9 +14,9 @@
class DWARFCompileUnit : public DWARFUnit {
public:
- static DWARFUnitSP Extract(SymbolFileDWARF *dwarf2Data,
- const lldb_private::DWARFDataExtractor &debug_info,
- lldb::offset_t *offset_ptr);
+ static DWARFCompileUnitSP Extract(SymbolFileDWARF *dwarf2Data,
+ const lldb_private::DWARFDataExtractor &debug_info,
+ lldb::offset_t *offset_ptr);
void Dump(lldb_private::Stream *s) const override;
//------------------------------------------------------------------
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -15,56 +15,17 @@
using namespace lldb;
using namespace lldb_private;
-extern int g_verbose;
-
DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
: DWARFUnit(dwarf2Data) {}
-DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
+DWARFCompileUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
const DWARFDataExtractor &debug_info,
lldb::offset_t *offset_ptr) {
// std::make_shared would require the ctor to be public.
- std::shared_ptr<DWARFCompileUnit> cu_sp(new DWARFCompileUnit(dwarf2Data));
-
- cu_sp->m_offset = *offset_ptr;
-
- if (debug_info.ValidOffset(*offset_ptr)) {
- dw_offset_t abbr_offset;
- 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);
-
- if (cu_sp->m_version == 5) {
- cu_sp->m_unit_type = debug_info.GetU8(offset_ptr);
- cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
- abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
-
- if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton)
- cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr);
- } else {
- abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
- cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
- }
-
- bool length_OK =
- debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
- bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version);
- bool abbr_offset_OK =
- 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) {
- 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 = cu_sp->m_offset;
- }
-
- return nullptr;
+ DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(dwarf2Data));
+ if (cu_sp->ExtractHeader(dwarf2Data, debug_info, offset_ptr))
+ return cu_sp;
+ return DWARFCompileUnitSP();
}
void DWARFCompileUnit::Dump(Stream *s) const {
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -251,8 +251,25 @@
context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
}
Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
- TypeList *type_list = dwarf->GetTypeList();
if (type_ptr == NULL) {
+
+ // If we have .debug_types defer to the complete version in the
+ // .debug_types section, not the broken incomplete definition in real
+ // compile units that are only there so addresses can be assigned to
+ // static values.
+ auto signature_die = die.GetAttributeValueAsReferenceDIE(DW_AT_signature);
+ if (signature_die) {
+ type_sp = ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr);
+ if (type_sp) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *decl_ctx =
+ GetCachedClangDeclContextForDIE(signature_die);
+ if (decl_ctx)
+ LinkDeclContextToDIE(decl_ctx, die);
+ return type_sp;
+ }
+ }
+
if (type_is_new_ptr)
*type_is_new_ptr = true;
@@ -1891,7 +1908,7 @@
// We are ready to put this type into the uniqued list up at the module
// level
- type_list->Insert(type_sp);
+ dwarf->GetTypeList()->Insert(type_sp);
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
}
Index: source/Plugins/SymbolFile/DWARF/DIERef.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -9,6 +9,7 @@
#include "DIERef.h"
#include "DWARFUnit.h"
+#include "DWARFTypeUnit.h"
#include "DWARFDebugInfo.h"
#include "DWARFFormValue.h"
#include "SymbolFileDWARF.h"
@@ -42,10 +43,24 @@
if (form_value.IsValid()) {
const DWARFUnit *dwarf_cu = form_value.GetCompileUnit();
if (dwarf_cu) {
- if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
- cu_offset = dwarf_cu->GetBaseObjOffset();
- else
- cu_offset = dwarf_cu->GetOffset();
+ // Replace the compile unit with the type signature compile unit
+ // and DIE for the type signature. When a type is referred to by a
+ // DW_FORM_ref_sig8 form, the real information for the type in
+ // contained in a DW_TAG_type_unit.
+ if (form_value.Form() == DW_FORM_ref_sig8) {
+ uint64_t type_sig = form_value.Unsigned();
+ auto debug_info = dwarf_cu->GetSymbolFileDWARF()->DebugInfo();
+ auto tu = debug_info->GetTypeUnitForSignature(type_sig);
+ if (tu) {
+ cu_offset = tu->GetOffset();
+ die_offset = tu->GetTypeUnitDIEOffset();
+ }
+ } else {
+ if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
+ cu_offset = dwarf_cu->GetBaseObjOffset();
+ else
+ cu_offset = dwarf_cu->GetOffset();
+ }
}
die_offset = form_value.Reference();
}
Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt
===================================================================
--- source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -25,6 +25,7 @@
DWARFFormValue.cpp
DWARFIndex.cpp
DWARFUnit.cpp
+ DWARFTypeUnit.cpp
HashedNameToDIE.cpp
LogChannelDWARF.cpp
ManualDWARFIndex.cpp
Index: packages/Python/lldbsuite/test/test_categories.py
===================================================================
--- packages/Python/lldbsuite/test/test_categories.py
+++ packages/Python/lldbsuite/test/test_categories.py
@@ -15,15 +15,16 @@
debug_info_categories = [
- 'dwarf', 'dwo', 'dsym', 'gmodules'
+ 'dwarf', 'dwo', 'dsym', 'gmodules', 'dwarf_type_units'
]
all_categories = {
'dataformatters': 'Tests related to the type command and the data formatters subsystem',
'dwarf': 'Tests that can be run with DWARF debug information',
'dwo': 'Tests that can be run with DWO debug information',
'dsym': 'Tests that can be run with DSYM debug information',
'gmodules': 'Tests that can be run with -gmodules debug information',
+ 'dwarf_type_units' : 'Tests that can be run with DWARF type units',
'expression': 'Tests related to the expression parser',
'libc++': 'Test for libc++ data formatters',
'libstdcxx': 'Test for libstdcxx data formatters',
@@ -62,6 +63,8 @@
if platform not in ["freebsd", "darwin", "macosx", "ios", "watchos", "tvos", "bridgeos"]:
return False
return gmodules.is_compiler_clang_with_gmodules(compiler_path)
+ elif category == "dwarf_type_units":
+ return platform in ["linux"]
return True
Index: packages/Python/lldbsuite/test/plugins/builder_base.py
===================================================================
--- packages/Python/lldbsuite/test/plugins/builder_base.py
+++ packages/Python/lldbsuite/test/plugins/builder_base.py
@@ -212,6 +212,27 @@
return True
+def buildDwarfTypeUnits(
+ sender=None,
+ architecture=None,
+ compiler=None,
+ dictionary=None,
+ testdir=None,
+ testname=None):
+ """Build the binaries with type units (type in a .debug_types section)."""
+ commands = []
+ commands.append(getMake(testdir, testname) +
+ ["MAKE_DSYM=NO",
+ "DWARF_TYPE_UNITS=YES",
+ getArchSpec(architecture),
+ getCCSpec(compiler),
+ getCmdLine(dictionary)])
+
+ lldbtest.system(commands, sender=sender)
+ # True signifies that we can handle building with type units.
+ return True
+
+
def cleanup(sender=None, dictionary=None):
"""Perform a platform-specific cleanup after the test."""
return True
Index: packages/Python/lldbsuite/test/make/Makefile.rules
===================================================================
--- packages/Python/lldbsuite/test/make/Makefile.rules
+++ packages/Python/lldbsuite/test/make/Makefile.rules
@@ -275,6 +275,12 @@
endif
endif
+MANDATORY_DWARF_TYPE_UNITS_CFLAGS := -fdebug-types-section
+
+ifeq "$(DWARF_TYPE_UNITS)" "YES"
+ CFLAGS += $(MANDATORY_DWARF_TYPE_UNITS_CFLAGS)
+endif
+
CXXFLAGS += -std=c++11 $(CFLAGS) $(ARCH_CXXFLAGS)
LD = $(CC)
LDFLAGS ?= $(CFLAGS)
Index: packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- packages/Python/lldbsuite/test/lldbtest.py
+++ packages/Python/lldbsuite/test/lldbtest.py
@@ -1575,6 +1575,23 @@
dictionary, testdir, testname):
raise Exception("Don't know how to build binary with gmodules")
+ def buildDwarfTypeUnits(
+ self,
+ architecture=None,
+ compiler=None,
+ dictionary=None):
+ """Platform specific way to build binaries with DWARF type units."""
+ testdir = self.mydir
+ testname = self.getBuildDirBasename()
+ if self.getDebugInfo() != "dwarf_type_units":
+ raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
+
+ module = builder_module()
+ dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
+ if not module.buildDwarfTypeUnits(self, architecture, compiler,
+ dictionary, testdir, testname):
+ raise Exception("Don't know how to build binary with DWARF type units")
+
def signBinary(self, binary_path):
if sys.platform.startswith("darwin"):
codesign_cmd = "codesign --force --sign \"%s\" %s" % (
@@ -2397,6 +2414,8 @@
return self.buildDwo(architecture, compiler, dictionary)
elif self.getDebugInfo() == "gmodules":
return self.buildGModules(architecture, compiler, dictionary)
+ elif self.getDebugInfo() == "dwarf_type_units":
+ return self.buildDwarfTypeUnits(architecture, compiler, dictionary)
else:
self.fail("Can't build for debug info: %s" % self.getDebugInfo())
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits