DIERef::DIERef(const DWARFFormValue &form_value)
: cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) {
if (form_value.IsValid()) {
- if (const DWARFUnit *unit = form_value.GetUnit()) {
- if (unit->GetBaseObjOffset() != DW_INVALID_OFFSET)
- cu_offset = unit->GetBaseObjOffset();
+ DWARFDIE die = form_value.Reference();
+ die_offset = die.GetOffset();
+ if (die) {
+ if (die.GetCU()->GetBaseObjOffset() != DW_INVALID_OFFSET)
+ cu_offset = die.GetCU()->GetBaseObjOffset();
else
- cu_offset = unit->GetOffset();
+ cu_offset = die.GetCU()->GetOffset();
}
- die_offset = form_value.Reference();
}
}
// will have a hard time tracking down an unnammed structure type in
// the module DWO file, so we make sure we don't get into this
// situation by always resolving typedefs from the DWO file.
- const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
+ const DWARFDIE encoding_die = encoding_uid.Reference();
// First make sure that the die that this is typedef'ed to _is_ just
// a declaration (DW_AT_declaration == 1), not a full definition
// Clang sometimes erroneously emits id as objc_object*. In that
// case we fix up the type to "id".
- const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
+ const DWARFDIE encoding_die = encoding_uid.Reference();
if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
if (const char *struct_name = encoding_die.GetName()) {
bool has_template_params = false;
DWARFFormValue specification_die_form;
DWARFFormValue abstract_origin_die_form;
- dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
+ DWARFDIE object_pointer_die;
unsigned type_quals = 0;
clang::StorageClass storage =
break;
case DW_AT_object_pointer:
- object_pointer_die_offset = form_value.Reference();
+ object_pointer_die = form_value.Reference();
break;
case DW_AT_allocated:
}
std::string object_pointer_name;
- if (object_pointer_die_offset != DW_INVALID_OFFSET) {
- DWARFDIE object_pointer_die = die.GetDIE(object_pointer_die_offset);
- if (object_pointer_die) {
- const char *object_pointer_name_cstr = object_pointer_die.GetName();
- if (object_pointer_name_cstr)
- object_pointer_name = object_pointer_name_cstr;
- }
+ if (object_pointer_die) {
+ const char *object_pointer_name_cstr = object_pointer_die.GetName();
+ if (object_pointer_name_cstr)
+ object_pointer_name = object_pointer_name_cstr;
}
DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
LinkDeclContextToDIE(spec_clang_decl_ctx, die);
} else {
dwarf->GetObjectFile()->GetModule()->ReportWarning(
- "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64
+ "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x"
") has no decl\n",
- die.GetID(), specification_die_form.Reference());
+ die.GetID(),
+ specification_die_form.Reference().GetOffset());
}
type_handled = true;
} else if (abstract_origin_die_form.IsValid()) {
LinkDeclContextToDIE(abs_clang_decl_ctx, die);
} else {
dwarf->GetObjectFile()->GetModule()->ReportWarning(
- "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64
+ "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x"
") has no decl\n",
- die.GetID(), abstract_origin_die_form.Reference());
+ die.GetID(),
+ abstract_origin_die_form.Reference().GetOffset());
}
type_handled = true;
} else {
clang::FunctionDecl *template_function_decl = nullptr;
if (abstract_origin_die_form.IsValid()) {
- DWARFDIE abs_die =
- dwarf->DebugInfo()->GetDIE(DIERef(abstract_origin_die_form));
+ DWARFDIE abs_die = abstract_origin_die_form.Reference();
SymbolContext sc;
member_byte_offset > parent_byte_size)) {
module_sp->ReportError(
"0x%8.8" PRIx64
- ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64
+ ": DW_TAG_member '%s' refers to type 0x%8.8x"
" which extends beyond the bounds of 0x%8.8" PRIx64,
- die.GetID(), name, encoding_form.Reference(),
+ die.GetID(), name,
+ encoding_form.Reference().GetOffset(),
parent_die.GetID());
}
if (name)
module_sp->ReportError(
"0x%8.8" PRIx64
- ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64
+ ": DW_TAG_member '%s' refers to type 0x%8.8x"
" which was unable to be parsed",
- die.GetID(), name, encoding_form.Reference());
+ die.GetID(), name, encoding_form.Reference().GetOffset());
else
module_sp->ReportError(
- "0x%8.8" PRIx64
- ": DW_TAG_member refers to type 0x%8.8" PRIx64
+ "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x"
" which was unable to be parsed",
- die.GetID(), encoding_form.Reference());
+ die.GetID(), encoding_form.Reference().GetOffset());
}
}
Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form));
if (base_class_type == NULL) {
module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to "
- "resolve the base class at 0x%8.8" PRIx64
+ "resolve the base class at 0x%8.8x"
" from enclosing type 0x%8.8x. \nPlease file "
"a bug and attach the file at the start of "
"this error message",
- die.GetOffset(), encoding_form.Reference(),
+ die.GetOffset(),
+ encoding_form.Reference().GetOffset(),
parent_die.GetOffset());
break;
}
if (attr == DW_AT_type &&
attributes.ExtractFormValueAtIndex(i, form_value))
- return dwarf->ResolveTypeUID(dwarf->GetDIE(DIERef(form_value)), true);
+ return dwarf->ResolveTypeUID(form_value.Reference(), true);
}
}
}
return form_value.ExtractValue(cu->GetData(), &offset);
}
-uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr,
- uint64_t fail_value) const {
+DWARFDIE
+DWARFAttributes::FormValueAsReference(dw_attr_t attr) const {
const uint32_t attr_idx = FindAttributeIndex(attr);
if (attr_idx != UINT32_MAX)
- return FormValueAsUnsignedAtIndex(attr_idx, fail_value);
- return fail_value;
+ return FormValueAsReferenceAtIndex(attr_idx);
+ return {};
}
-uint64_t
-DWARFAttributes::FormValueAsUnsignedAtIndex(uint32_t i,
- uint64_t fail_value) const {
+DWARFDIE
+DWARFAttributes::FormValueAsReferenceAtIndex(uint32_t i) const {
DWARFFormValue form_value;
if (ExtractFormValueAtIndex(i, form_value))
return form_value.Reference();
- return fail_value;
+ return {};
}
}
dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); }
bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const;
- uint64_t FormValueAsUnsignedAtIndex(uint32_t i, uint64_t fail_value) const;
- uint64_t FormValueAsUnsigned(dw_attr_t attr, uint64_t fail_value) const;
+ DWARFDIE FormValueAsReferenceAtIndex(uint32_t i) const;
+ DWARFDIE FormValueAsReference(dw_attr_t attr) const;
uint32_t FindAttributeIndex(dw_attr_t attr) const;
void Clear() { m_infos.clear(); }
size_t Size() const { return m_infos.size(); }
return fail_value;
}
-uint64_t DWARFBaseDIE::GetAttributeValueAsReference(const dw_attr_t attr,
- uint64_t fail_value) const {
- if (IsValid())
- return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr,
- fail_value);
- else
- return fail_value;
-}
-
uint64_t DWARFBaseDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
uint64_t fail_value) const {
if (IsValid())
class DWARFDebugInfoEntry;
class DWARFDeclContext;
class SymbolFileDWARF;
+class DWARFDIE;
class DWARFBaseDIE {
public:
uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr,
uint64_t fail_value) const;
- uint64_t GetAttributeValueAsReference(const dw_attr_t attr,
- uint64_t fail_value) const;
-
uint64_t GetAttributeValueAsAddress(const dw_attr_t attr,
uint64_t fail_value) const;
DWARFDIE
DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
- const dw_offset_t die_offset =
- GetAttributeValueAsReference(attr, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- return GetDIE(die_offset);
+ if (IsValid())
+ return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr);
else
- return DWARFDIE();
+ return {};
}
DWARFDIE
DWARFFormValue form_value;
if (m_die->GetAttributeValue(dwarf, cu, attr, form_value, nullptr,
check_specification_or_abstract_origin))
- return dwarf->GetDIE(DIERef(form_value));
+ return form_value.Reference();
}
return DWARFDIE();
}
case DW_AT_abstract_origin:
case DW_AT_specification: {
- uint64_t abstract_die_offset = form_value.Reference();
+ DWARFDIE abstract_die = form_value.Reference();
form_value.Dump(s);
- // *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
- GetName(dwarf2Data, cu, abstract_die_offset, s);
+ // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( ";
+ GetName(dwarf2Data, abstract_die.GetCU(), abstract_die.GetOffset(), s);
} break;
case DW_AT_type: {
- uint64_t type_die_offset = form_value.Reference();
+ DWARFDIE type_die = form_value.Reference();
s.PutCString(" ( ");
- AppendTypeName(dwarf2Data, cu, type_die_offset, s);
+ AppendTypeName(dwarf2Data, type_die.GetCU(), type_die.GetOffset(), s);
s.PutCString(" )");
} break;
const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
lldb::offset_t offset = 0;
if (cu) {
- if (m_tag != DW_TAG_compile_unit && m_tag != DW_TAG_partial_unit) {
- SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file)
- return GetAttributes(dwo_symbol_file->GetCompileUnit(),
- fixed_form_sizes, attributes, curr_depth);
- }
-
dwarf2Data = cu->GetSymbolFileDWARF();
abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
}
if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
if (form_value.ExtractValue(debug_info_data, &offset)) {
- dw_offset_t die_offset = form_value.Reference();
- DWARFDIE spec_die =
- const_cast<DWARFUnit *>(cu)->GetDIE(die_offset);
+ DWARFDIE spec_die = form_value.Reference();
if (spec_die)
spec_die.GetAttributes(attributes, curr_depth + 1);
}
if (check_specification_or_abstract_origin) {
if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) {
- DWARFDIE die =
- const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
+ DWARFDIE die = form_value.Reference();
if (die) {
dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
}
if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) {
- DWARFDIE die =
- const_cast<DWARFUnit *>(cu)->GetDIE(form_value.Reference());
+ DWARFDIE die = form_value.Reference();
if (die) {
dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
//
// Get the value of an attribute as reference and fix up and compile unit
// relative offsets as needed.
-uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, uint64_t fail_value,
+DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr,
bool check_specification_or_abstract_origin) const {
DWARFFormValue form_value;
if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
check_specification_or_abstract_origin))
return form_value.Reference();
- return fail_value;
+ return {};
}
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
// Follow the DW_AT_type if possible
DWARFFormValue form_value;
if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) {
- uint64_t next_die_offset = form_value.Reference();
- result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
+ DWARFDIE next_die = form_value.Reference();
+ result = AppendTypeName(dwarf2Data, next_die.GetCU(),
+ next_die.GetOffset(), s);
}
switch (abbrevDecl->Tag()) {
}
}
- dw_offset_t die_offset;
-
- die_offset =
- attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET) {
- DWARFDIE spec_die = cu->GetDIE(die_offset);
- if (spec_die) {
- DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
- if (decl_ctx_die)
- return decl_ctx_die;
- }
+ DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
+ if (spec_die) {
+ DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
+ if (decl_ctx_die)
+ return decl_ctx_die;
}
- die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin,
- DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET) {
- DWARFDIE abs_die = cu->GetDIE(die_offset);
- if (abs_die) {
- DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
- if (decl_ctx_die)
- return decl_ctx_die;
- }
+ DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
+ if (abs_die) {
+ DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
+ if (decl_ctx_die)
+ return decl_ctx_die;
}
die = die.GetParent();
const dw_attr_t attr, uint64_t fail_value,
bool check_specification_or_abstract_origin = false) const;
- uint64_t GetAttributeValueAsReference(
- SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
- const dw_attr_t attr, uint64_t fail_value,
+ DWARFDIE GetAttributeValueAsReference(
+ SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const dw_attr_t attr,
bool check_specification_or_abstract_origin = false) const;
uint64_t GetAttributeValueAsAddress(
#include "lldb/Core/dwarf.h"
#include "lldb/Utility/Stream.h"
-#include "DWARFUnit.h"
+#include "DWARFDebugInfo.h"
#include "DWARFFormValue.h"
+#include "DWARFUnit.h"
class DWARFUnit;
return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
}
-uint64_t DWARFFormValue::Reference() const {
+DWARFDIE DWARFFormValue::Reference() const {
uint64_t value = m_value.value.uval;
switch (m_form) {
case DW_FORM_ref1:
case DW_FORM_ref_udata:
assert(m_unit); // Unit must be valid for DW_FORM_ref forms that are compile
// unit relative or we will get this wrong
- return value + m_unit->GetOffset();
+ value += m_unit->GetOffset();
+ if (!m_unit->ContainsDIEOffset(value)) {
+ m_unit->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
+ "DW_FORM_ref* DIE reference 0x%" PRIx64 " is outside of its CU",
+ value);
+ return {};
+ }
+ return const_cast<DWARFUnit *>(m_unit)->GetDIE(value);
- case DW_FORM_ref_addr:
- case DW_FORM_ref_sig8:
- case DW_FORM_GNU_ref_alt:
- return value;
+ case DW_FORM_ref_addr: {
+ DWARFUnit *ref_cu =
+ m_unit->GetSymbolFileDWARF()->DebugInfo()->GetUnitContainingDIEOffset(
+ value);
+ if (!ref_cu) {
+ m_unit->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
+ "DW_FORM_ref_addr DIE reference 0x%" PRIx64 " has no matching CU",
+ value);
+ return {};
+ }
+ return ref_cu->GetDIE(value);
+ }
default:
- return DW_INVALID_OFFSET;
+ return {};
}
}
case DW_FORM_ref4:
case DW_FORM_ref8:
case DW_FORM_ref_udata: {
- uint64_t a = a_value.Reference();
- uint64_t b = b_value.Reference();
+ uint64_t a = a_value.m_value.value.uval;
+ uint64_t b = b_value.m_value.value.uval;
if (a < b)
return -1;
if (a > b)
class DWARFUnit;
class SymbolFileDWARF;
+class DWARFDIE;
class DWARFFormValue {
public:
DWARFFormValue(const DWARFUnit *unit) : m_unit(unit) {}
DWARFFormValue(const DWARFUnit *unit, dw_form_t form)
: m_unit(unit), m_form(form) {}
- const DWARFUnit *GetUnit() const { return m_unit; }
void SetUnit(const DWARFUnit *unit) { m_unit = unit; }
dw_form_t Form() const { return m_form; }
dw_form_t& FormRef() { return m_form; }
bool ExtractValue(const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr);
const uint8_t *BlockData() const;
- uint64_t Reference() const;
+ DWARFDIE Reference() const;
uint64_t Reference(dw_offset_t offset) const;
bool Boolean() const { return m_value.value.uval != 0; }
uint64_t Unsigned() const { return m_value.value.uval; }
static bool FormIsSupported(dw_form_t form);
protected:
+ // Compile unit where m_value was located.
+ // It may be different from compile unit where m_value refers to.
const DWARFUnit *m_unit = nullptr; // Unit for this form
dw_form_t m_form = 0; // Form for this value
ValueType m_value; // Contains all data for the form
if (die_offset == (*pos).GetOffset())
return DWARFDIE(this, &(*pos));
}
- } else {
- // Don't specify the compile unit offset as we don't know it because the
- // DIE belongs to
- // a different compile unit in the same symbol file.
- return m_dwarf->DebugInfo()->GetDIEForDIEOffset(die_offset);
- }
+ } else
+ GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
+ "GetDIE for DIE 0x%" PRIx32 " is outside of its CU 0x%" PRIx32,
+ die_offset, GetOffset());
}
return DWARFDIE(); // Not found
}
}
} break;
case DW_AT_specification:
- spec_die = GetDIE(DIERef(form_value));
+ spec_die = form_value.Reference();
break;
case DW_AT_start_scope: {
if (form_value.Form() == DW_FORM_sec_offset) {
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
case DW_TAG_lexical_block: {
- if (die.GetAttributeValueAsReference(
- DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
+ if (die.GetReferencedDIE(DW_AT_specification).GetOffset() ==
+ spec_block_die_offset)
return die;
- if (die.GetAttributeValueAsReference(DW_AT_abstract_origin,
- DW_INVALID_OFFSET) ==
+ if (die.GetReferencedDIE(DW_AT_abstract_origin).GetOffset() ==
spec_block_die_offset)
return die;
} break;