forked from OSchip/llvm-project
DWARF: Implement DW_AT_signature lookup for type unit support
Summary: This patch implements the main feature of type units. When completing a type, if we encounter a DW_AT_signature attribute, we use it's value to lookup the complete definition of the type in the relevant type unit. To enable this lookup, we build up a map of all type units in a symbol file when parsing the units. Then we consult this map when resolving the DW_AT_signature attribute. I include add a couple of tests which exercise the type lookup feature, including one that ensure we do something reasonable in case we fail to lookup the type. A lot of the ideas in this patch have been taken from D32167 and D61505. Reviewers: clayborg, JDevlieghere, aprantl, alexshap Subscribers: mgrang, lldb-commits Differential Revision: https://reviews.llvm.org/D62246 llvm-svn: 361603
This commit is contained in:
parent
8ac0bc9832
commit
f750842c8b
|
@ -1,13 +1,15 @@
|
|||
enum E { e1, e2, e3 };
|
||||
enum class EC { e1, e2, e3 };
|
||||
|
||||
struct A {
|
||||
int i;
|
||||
long l;
|
||||
float f;
|
||||
double d;
|
||||
E e;
|
||||
EC ec;
|
||||
};
|
||||
|
||||
enum E { e1, e2, e3 };
|
||||
enum class EC { e1, e2, e3 };
|
||||
|
||||
extern constexpr A a{42, 47l, 4.2f, 4.7};
|
||||
extern constexpr A a{42, 47l, 4.2f, 4.7, e1, EC::e3};
|
||||
extern constexpr E e(e2);
|
||||
extern constexpr EC ec(EC::e2);
|
||||
|
|
|
@ -11,11 +11,19 @@ struct B: public A {
|
|||
namespace ns {
|
||||
struct A {
|
||||
int i = 147;
|
||||
::A getA();
|
||||
A();
|
||||
};
|
||||
A::A() = default;
|
||||
|
||||
::A A::getA() {
|
||||
::A a;
|
||||
a.i = i - 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
} // namespace ns
|
||||
|
||||
int foo(A *a) {
|
||||
return a->f();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ type lookup A
|
|||
# CHECK-NEXT: long l;
|
||||
# CHECK-NEXT: float f;
|
||||
# CHECK-NEXT: double d;
|
||||
# CHECK-NEXT: E e;
|
||||
# CHECK-NEXT: EC ec;
|
||||
# CHECK-NEXT: }
|
||||
|
||||
type lookup E
|
||||
|
@ -44,3 +46,9 @@ print (E) 1
|
|||
print (EC) 1
|
||||
# CHECK-LABEL: print (EC) 1
|
||||
# CHECK: (EC) $1 = e2
|
||||
|
||||
target variable a e ec
|
||||
# CHECK-LABEL: target variable a e ec
|
||||
# CHECK: (const A) a = (i = 42, l = 47, f = 4.{{[12].*}}, d = 4.{{[67].*}}, e = e1, ec = e3)
|
||||
# CHECK: (const E) e = e2
|
||||
# CHECK: (const EC) ec = e2
|
||||
|
|
|
@ -19,6 +19,13 @@ frame variable a
|
|||
# CHECK-LABEL: frame variable a
|
||||
# CHECK: (B *) a =
|
||||
|
||||
frame variable *a
|
||||
# CHECK-LABEL: frame variable *a
|
||||
# CHECK: (B) *a = {
|
||||
# CHECK-NEXT: A = (i = 47)
|
||||
# CHECK-NEXT: j = 42
|
||||
# CHECK-NEXT: }
|
||||
|
||||
print a->f()
|
||||
# CHECK-LABEL: print a->f()
|
||||
# CHECK: (int) $0 = 47
|
||||
|
@ -26,3 +33,11 @@ print a->f()
|
|||
print ns::A()
|
||||
# CHECK-LABEL: print ns::A()
|
||||
# CHECK: (ns::A) $1 = (i = 147)
|
||||
|
||||
print ns::A().i + a->i
|
||||
# CHECK-LABEL: print ns::A().i + a->i
|
||||
# CHECK: (int) $2 = 194
|
||||
|
||||
print ns::A().getA()
|
||||
# CHECK-LABEL: ns::A().getA()
|
||||
# CHECK: (A) $3 = (i = 146)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
Create a dangling DW_AT_signature reference by stripping the debug_types
|
||||
section, and make sure lldb does something reasonable.
|
||||
RUN: %clangxx -target x86_64-pc-linux %S/Inputs/debug-types-basic.cpp \
|
||||
RUN: -g -gdwarf-4 -fdebug-types-section -c -o %t.o
|
||||
RUN: llvm-objcopy --remove-section=.debug_types %t.o %t
|
||||
|
||||
|
||||
RUN: %lldb %t -b -o "type lookup A" | FileCheck --check-prefix=LOOKUPA %s
|
||||
LOOKUPA: no type was found matching 'A'
|
||||
|
||||
RUN: %lldb %t -b -o "type lookup E" | FileCheck --check-prefix=LOOKUPE %s
|
||||
LOOKUPE: no type was found matching 'E'
|
||||
|
||||
RUN: %lldb %t -b -o "type lookup EC" | FileCheck --check-prefix=LOOKUPEC %s
|
||||
LOOKUPEC: no type was found matching 'EC'
|
||||
|
||||
RUN: %lldb %t -b -o "print (E) 1" 2>&1 | FileCheck --check-prefix=PRINTE %s
|
||||
PRINTE: use of undeclared identifier 'E'
|
||||
|
||||
RUN: %lldb %t -b -o "print (EC) 1" 2>&1 | FileCheck --check-prefix=PRINTEC %s
|
||||
PRINTEC: use of undeclared identifier 'EC'
|
||||
|
||||
RUN: %lldb %t -b -o "target variable a e ec" | FileCheck --check-prefix=VARS %s
|
||||
VARS: (const (anonymous struct)) a = {}
|
||||
VARS: (const (anonymous enum)) e = 1
|
||||
VARS: (const (anonymous enum)) ec = 1
|
|
@ -0,0 +1,115 @@
|
|||
# REQUIRES: lld
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux -o %t.o %s
|
||||
# RUN: ld.lld %t.o -o %t
|
||||
# RUN: %lldb %t -o "target variable e" -b | FileCheck %s
|
||||
|
||||
# CHECK: e = <could not resolve type>
|
||||
|
||||
.type e,@object # @e
|
||||
.section .rodata,"a",@progbits
|
||||
.globl e
|
||||
.p2align 2
|
||||
e:
|
||||
.long 0 # 0x0
|
||||
.size e, 4
|
||||
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "Hand-written DWARF"
|
||||
.Linfo_string1:
|
||||
.asciz "a.cpp"
|
||||
.Linfo_string3:
|
||||
.asciz "e"
|
||||
.Linfo_string4:
|
||||
.asciz "unsigned int"
|
||||
.Linfo_string5:
|
||||
.asciz "e1"
|
||||
.Linfo_string6:
|
||||
.asciz "E"
|
||||
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 65 # DW_TAG_type_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 14 # DW_FORM_strp
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 8 # Abbreviation Code
|
||||
.byte 4 # DW_TAG_enumeration_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 60 # DW_AT_declaration
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 105 # DW_AT_signature
|
||||
.byte 32 # DW_FORM_ref_sig8
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
|
||||
.section .debug_info,"",@progbits
|
||||
.Ltu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 2 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.quad 5390450678491038984 # Type Signature
|
||||
.long .LE-.Ltu_begin0 # Type DIE Offset
|
||||
.byte 1 # Abbrev [1] 0x18:0x1d DW_TAG_type_unit
|
||||
.short 4 # DW_AT_language
|
||||
.LE:
|
||||
.byte 8 # Abbrev [8] 0x23:0xd DW_TAG_enumeration_type
|
||||
# DW_AT_declaration
|
||||
.quad 5390450678491038984 # DW_AT_signature
|
||||
.Lbase:
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
|
||||
.Ldebug_info_start1:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 5 # Abbrev [5] 0xc:0x2c DW_TAG_compile_unit
|
||||
.long .Linfo_string0 # DW_AT_producer
|
||||
.short 4 # DW_AT_language
|
||||
.long .Linfo_string1 # DW_AT_name
|
||||
.byte 6 # Abbrev [6] 0x1e:0xb DW_TAG_variable
|
||||
.long .Linfo_string3 # DW_AT_name
|
||||
.long .LE_sig-.Lcu_begin0 # DW_AT_type
|
||||
.byte 9 # DW_AT_location
|
||||
.byte 3
|
||||
.quad e
|
||||
.LE_sig:
|
||||
.byte 8 # Abbrev [8] 0x2e:0x9 DW_TAG_enumeration_type
|
||||
# DW_AT_declaration
|
||||
.quad 5390450678491038984 # DW_AT_signature
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end1:
|
|
@ -237,7 +237,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
AccessType accessibility = eAccessNone;
|
||||
if (!die)
|
||||
return nullptr;
|
||||
|
||||
SymbolFileDWARF *dwarf = die.GetDWARF();
|
||||
if (log) {
|
||||
DWARFDIE context_die;
|
||||
|
@ -252,11 +251,27 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
die.GetTagAsCString(), die.GetName());
|
||||
}
|
||||
|
||||
|
||||
Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
|
||||
if (type_ptr == DIE_IS_BEING_PARSED)
|
||||
return nullptr;
|
||||
if (type_ptr)
|
||||
return type_ptr->shared_from_this();
|
||||
// Set a bit that lets us know that we are currently parsing this
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
|
||||
|
||||
if (DWARFDIE signature_die =
|
||||
die.GetAttributeValueAsReferenceDIE(DW_AT_signature)) {
|
||||
if (TypeSP type_sp =
|
||||
ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr)) {
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
|
||||
if (clang::DeclContext *decl_ctx =
|
||||
GetCachedClangDeclContextForDIE(signature_die))
|
||||
LinkDeclContextToDIE(decl_ctx, die);
|
||||
return type_sp;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TypeList *type_list = dwarf->GetTypeList();
|
||||
if (type_is_new_ptr)
|
||||
|
@ -289,9 +304,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
case DW_TAG_restrict_type:
|
||||
case DW_TAG_volatile_type:
|
||||
case DW_TAG_unspecified_type: {
|
||||
// Set a bit that lets us know that we are currently parsing this
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
|
||||
|
||||
const size_t num_attributes = die.GetAttributes(attributes);
|
||||
uint32_t encoding = 0;
|
||||
DWARFFormValue encoding_uid;
|
||||
|
@ -540,9 +552,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
case DW_TAG_structure_type:
|
||||
case DW_TAG_union_type:
|
||||
case DW_TAG_class_type: {
|
||||
// Set a bit that lets us know that we are currently parsing this
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
|
||||
|
||||
LanguageType class_language = eLanguageTypeUnknown;
|
||||
bool is_complete_objc_class = false;
|
||||
size_t calling_convention = llvm::dwarf::CallingConvention::DW_CC_normal;
|
||||
|
@ -974,9 +983,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
} break;
|
||||
|
||||
case DW_TAG_enumeration_type: {
|
||||
// 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;
|
||||
|
||||
|
@ -1136,9 +1142,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
case DW_TAG_inlined_subroutine:
|
||||
case DW_TAG_subprogram:
|
||||
case DW_TAG_subroutine_type: {
|
||||
// Set a bit that lets us know that we are currently parsing this
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
|
||||
|
||||
DWARFFormValue type_die_form;
|
||||
bool is_variadic = false;
|
||||
bool is_inline = false;
|
||||
|
@ -1658,9 +1661,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
|
|||
} break;
|
||||
|
||||
case DW_TAG_array_type: {
|
||||
// Set a bit that lets us know that we are currently parsing this
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
|
||||
|
||||
DWARFFormValue type_die_form;
|
||||
uint32_t byte_stride = 0;
|
||||
uint32_t bit_stride = 0;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Utility/RegularExpression.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
#include "DWARFCompileUnit.h"
|
||||
#include "DWARFContext.h"
|
||||
|
@ -74,12 +75,14 @@ llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
|
|||
return *m_cu_aranges_up;
|
||||
}
|
||||
|
||||
void Parse(SymbolFileDWARF *dwarf, const DWARFDataExtractor &data,
|
||||
DIERef::Section section, std::vector<DWARFUnitSP> &units) {
|
||||
void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
|
||||
DWARFDataExtractor data = section == DIERef::Section::DebugTypes
|
||||
? m_context.getOrLoadDebugTypesData()
|
||||
: m_context.getOrLoadDebugInfoData();
|
||||
lldb::offset_t offset = 0;
|
||||
while (data.ValidOffset(offset)) {
|
||||
llvm::Expected<DWARFUnitSP> unit_sp =
|
||||
DWARFUnit::extract(dwarf, units.size(), data, section, &offset);
|
||||
llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
|
||||
m_dwarf2Data, m_units.size(), data, section, &offset);
|
||||
|
||||
if (!unit_sp) {
|
||||
// FIXME: Propagate this error up.
|
||||
|
@ -89,10 +92,13 @@ void Parse(SymbolFileDWARF *dwarf, const DWARFDataExtractor &data,
|
|||
|
||||
// If it didn't return an error, then it should be returning a valid Unit.
|
||||
assert(*unit_sp);
|
||||
|
||||
units.push_back(*unit_sp);
|
||||
|
||||
m_units.push_back(*unit_sp);
|
||||
offset = (*unit_sp)->GetNextUnitOffset();
|
||||
|
||||
if (auto *type_unit = llvm::dyn_cast<DWARFTypeUnit>(unit_sp->get())) {
|
||||
m_type_hash_to_unit_index.emplace_back(type_unit->GetTypeHash(),
|
||||
unit_sp.get()->GetID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,10 +108,9 @@ void DWARFDebugInfo::ParseUnitHeadersIfNeeded() {
|
|||
if (!m_dwarf2Data)
|
||||
return;
|
||||
|
||||
Parse(m_dwarf2Data, m_context.getOrLoadDebugInfoData(),
|
||||
DIERef::Section::DebugInfo, m_units);
|
||||
Parse(m_dwarf2Data, m_context.getOrLoadDebugTypesData(),
|
||||
DIERef::Section::DebugTypes, m_units);
|
||||
ParseUnitsFor(DIERef::Section::DebugInfo);
|
||||
ParseUnitsFor(DIERef::Section::DebugTypes);
|
||||
llvm::sort(m_type_hash_to_unit_index, llvm::less_first());
|
||||
}
|
||||
|
||||
size_t DWARFDebugInfo::GetNumUnits() {
|
||||
|
@ -169,6 +174,14 @@ DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section,
|
|||
return result;
|
||||
}
|
||||
|
||||
DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) {
|
||||
auto pos = llvm::lower_bound(m_type_hash_to_unit_index,
|
||||
std::make_pair(hash, 0u), llvm::less_first());
|
||||
if (pos == m_type_hash_to_unit_index.end() || pos->first != hash)
|
||||
return nullptr;
|
||||
return llvm::cast<DWARFTypeUnit>(GetUnitAtIndex(pos->second));
|
||||
}
|
||||
|
||||
DWARFDIE
|
||||
DWARFDebugInfo::GetDIEForDIEOffset(DIERef::Section section,
|
||||
dw_offset_t die_offset) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "DWARFDIE.h"
|
||||
#include "DWARFTypeUnit.h"
|
||||
#include "DWARFUnit.h"
|
||||
#include "SymbolFileDWARF.h"
|
||||
#include "lldb/Core/STLUtils.h"
|
||||
|
@ -46,6 +47,7 @@ public:
|
|||
DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section,
|
||||
dw_offset_t die_offset);
|
||||
DWARFUnit *GetUnit(const DIERef &die_ref);
|
||||
DWARFTypeUnit *GetTypeUnitForHash(uint64_t hash);
|
||||
DWARFDIE GetDIEForDIEOffset(DIERef::Section section,
|
||||
dw_offset_t die_offset);
|
||||
DWARFDIE GetDIE(const DIERef &die_ref);
|
||||
|
@ -69,11 +71,15 @@ protected:
|
|||
std::unique_ptr<DWARFDebugAranges>
|
||||
m_cu_aranges_up; // A quick address to compile unit table
|
||||
|
||||
std::vector<std::pair<uint64_t, uint32_t>> m_type_hash_to_unit_index;
|
||||
|
||||
private:
|
||||
// All parsing needs to be done partially any managed by this class as
|
||||
// accessors are called.
|
||||
void ParseUnitHeadersIfNeeded();
|
||||
|
||||
void ParseUnitsFor(DIERef::Section section);
|
||||
|
||||
uint32_t FindUnitIndex(DIERef::Section section, dw_offset_t offset);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo);
|
||||
|
|
|
@ -585,6 +585,14 @@ DWARFDIE DWARFFormValue::Reference() const {
|
|||
return ref_cu->GetDIE(value);
|
||||
}
|
||||
|
||||
case DW_FORM_ref_sig8: {
|
||||
DWARFTypeUnit *tu =
|
||||
m_unit->GetSymbolFileDWARF()->DebugInfo()->GetTypeUnitForHash(value);
|
||||
if (!tu)
|
||||
return {};
|
||||
return tu->GetDIE(tu->GetTypeOffset());
|
||||
}
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
||||
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 (next CU at "
|
||||
|
|
|
@ -18,6 +18,14 @@ public:
|
|||
|
||||
void Dump(lldb_private::Stream *s) const override;
|
||||
|
||||
uint64_t GetTypeHash() { return m_header.GetTypeHash(); }
|
||||
|
||||
dw_offset_t GetTypeOffset() { return GetOffset() + m_header.GetTypeOffset(); }
|
||||
|
||||
static bool classof(const DWARFUnit *unit) {
|
||||
return unit->GetUnitType() == DW_UT_type;
|
||||
}
|
||||
|
||||
private:
|
||||
DWARFTypeUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
|
||||
const DWARFUnitHeader &header,
|
||||
|
|
|
@ -715,9 +715,16 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section
|
|||
section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
|
||||
}
|
||||
|
||||
if (header.IsTypeUnit()) {
|
||||
header.m_type_hash = data.GetU64(offset_ptr);
|
||||
header.m_type_offset = data.GetDWARFOffset(offset_ptr);
|
||||
}
|
||||
|
||||
bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
|
||||
bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version);
|
||||
bool addr_size_OK = (header.m_addr_size == 4) || (header.m_addr_size == 8);
|
||||
bool type_offset_OK =
|
||||
!header.IsTypeUnit() || (header.m_type_offset <= header.GetLength());
|
||||
|
||||
if (!length_OK)
|
||||
return llvm::make_error<llvm::object::GenericBinaryError>(
|
||||
|
@ -728,6 +735,9 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section
|
|||
if (!addr_size_OK)
|
||||
return llvm::make_error<llvm::object::GenericBinaryError>(
|
||||
"Invalid unit address size");
|
||||
if (!type_offset_OK)
|
||||
return llvm::make_error<llvm::object::GenericBinaryError>(
|
||||
"Type offset out of range");
|
||||
|
||||
return header;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@ class DWARFUnitHeader {
|
|||
dw_offset_t m_abbr_offset = 0;
|
||||
uint8_t m_unit_type = 0;
|
||||
uint8_t m_addr_size = 0;
|
||||
|
||||
uint64_t m_type_hash = 0;
|
||||
uint32_t m_type_offset = 0;
|
||||
|
||||
uint64_t m_dwo_id = 0;
|
||||
|
||||
DWARFUnitHeader() = default;
|
||||
|
@ -52,6 +56,8 @@ public:
|
|||
dw_offset_t GetLength() const { return m_length; }
|
||||
dw_offset_t GetAbbrOffset() const { return m_abbr_offset; }
|
||||
uint8_t GetUnitType() const { return m_unit_type; }
|
||||
uint64_t GetTypeHash() const { return m_type_hash; }
|
||||
dw_offset_t GetTypeOffset() const { return m_type_offset; }
|
||||
bool IsTypeUnit() const {
|
||||
return m_unit_type == DW_UT_type || m_unit_type == DW_UT_split_type;
|
||||
}
|
||||
|
@ -205,6 +211,8 @@ public:
|
|||
|
||||
DIERef::Section GetDebugSection() const { return m_section; }
|
||||
|
||||
uint8_t GetUnitType() const { return m_header.GetUnitType(); }
|
||||
|
||||
protected:
|
||||
DWARFUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
|
||||
const DWARFUnitHeader &header,
|
||||
|
|
Loading…
Reference in New Issue