16#include "llvm/Support/LEB128.h"
47 const uint64_t abbr_idx = data.
GetULEB128(offset_ptr);
55 m_tag = llvm::dwarf::DW_TAG_null;
62 if (abbrevDecl ==
nullptr) {
64 "[{0:x16}]: invalid abbreviation code {1}, "
65 "please file a bug and "
66 "attach the file at the start of this error message",
67 (uint64_t)
m_offset, (
unsigned)abbr_idx);
72 m_tag = abbrevDecl->Tag();
75 const uint32_t numAttributes = abbrevDecl->NumAttributes();
78 for (i = 0; i < numAttributes; ++i) {
79 form = abbrevDecl->GetFormByIndexUnchecked(i);
80 std::optional<uint8_t> fixed_skip_size =
83 offset += *fixed_skip_size;
85 bool form_is_indirect =
false;
87 form_is_indirect =
false;
115 case DW_FORM_ref_addr:
123 case DW_FORM_flag_present:
161 case DW_FORM_ref_sig8:
167 case DW_FORM_loclistx:
168 case DW_FORM_rnglistx:
171 case DW_FORM_ref_udata:
172 case DW_FORM_GNU_addr_index:
173 case DW_FORM_GNU_str_index:
178 case DW_FORM_indirect:
179 form_is_indirect =
true;
184 case DW_FORM_line_strp:
185 case DW_FORM_sec_offset:
189 case DW_FORM_implicit_const:
195 "[{0:x16}]: Unsupported DW_FORM_{1:x}, please file a bug "
197 "attach the file at the start of this error message",
198 (uint64_t)
m_offset, (
unsigned)form);
204 }
while (form_is_indirect);
207 *offset_ptr = offset;
214 llvm::Expected<DWARFRangeList> expected_ranges =
215 (value.
Form() == DW_FORM_rnglistx)
219 return std::move(*expected_ranges);
222 "[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
223 "range extraction failed ({3}), please file a bug "
224 "and attach the file at the start of this error message",
226 llvm::dwarf::FormEncodingString(value.
Form()).str().c_str(),
236 DWARFUnit *cu,
const char *&name,
const char *&mangled,
238 std::optional<int> &decl_line, std::optional<int> &decl_column,
239 std::optional<int> &call_file, std::optional<int> &call_line,
243 std::vector<DWARFDIE> dies;
244 bool set_frame_base_loclist_addr =
false;
249 lldb::ModuleSP module =
dwarf.GetObjectFile()->GetModule();
258 const uint32_t numAttributes = abbrevDecl->NumAttributes();
259 bool do_offset =
false;
261 for (
uint32_t i = 0; i < numAttributes; ++i) {
264 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
281 if (form_value.
Form() == DW_FORM_addr ||
282 form_value.
Form() == DW_FORM_addrx ||
283 form_value.
Form() == DW_FORM_GNU_addr_index) {
304 case DW_AT_MIPS_linkage_name:
305 case DW_AT_linkage_name:
306 if (mangled ==
nullptr)
310 case DW_AT_abstract_origin:
314 case DW_AT_specification:
318 case DW_AT_decl_file:
323 case DW_AT_decl_line:
328 case DW_AT_decl_column:
330 decl_column = form_value.
Unsigned();
333 case DW_AT_call_file:
338 case DW_AT_call_line:
343 case DW_AT_call_column:
345 call_column = form_value.
Unsigned();
348 case DW_AT_frame_base:
357 data, block_offset, block_length)),
369 set_frame_base_loclist_addr =
true;
391 if (set_frame_base_loclist_addr) {
397 if (ranges.
IsEmpty() || name ==
nullptr || mangled ==
nullptr) {
400 die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
401 decl_file, decl_line, decl_column,
402 call_file, call_line, call_column);
422 const uint32_t num_attributes = abbrevDecl->NumAttributes();
423 for (
uint32_t i = 0; i < num_attributes; ++i) {
426 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
434 case DW_AT_declaration:
435 if (curr_depth > 0) {
443 attributes.
Append(form_value, offset, attr);
447 if (recurse == Recurse::yes &&
448 ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) {
453 recurse, curr_depth + 1);
456 std::optional<uint8_t> fixed_skip_size =
459 offset += *fixed_skip_size;
467 return attributes.
Size();
479 bool check_specification_or_abstract_origin)
const {
481 uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
488 while (idx < attr_idx)
494 form_value.
SetForm(abbrevDecl->GetFormByIndex(idx));
496 if (end_attr_offset_ptr)
497 *end_attr_offset_ptr = offset;
503 if (check_specification_or_abstract_origin) {
508 die.
GetCU(), attr, form_value, end_attr_offset_ptr,
false);
518 die.
GetCU(), attr, form_value, end_attr_offset_ptr,
false);
535 bool check_specification_or_abstract_origin)
const {
538 check_specification_or_abstract_origin))
548 bool check_specification_or_abstract_origin)
const {
551 check_specification_or_abstract_origin))
556std::optional<uint64_t>
559 bool check_specification_or_abstract_origin)
const {
562 check_specification_or_abstract_origin))
573 bool check_specification_or_abstract_origin)
const {
576 check_specification_or_abstract_origin))
583 bool check_specification_or_abstract_origin)
const {
586 check_specification_or_abstract_origin))
599 bool check_specification_or_abstract_origin)
const {
602 check_specification_or_abstract_origin)) {
604 if (form == DW_FORM_addr || form == DW_FORM_addrx ||
605 form == DW_FORM_GNU_addr_index)
609 return lo_pc + form_value.
Unsigned();
622 uint64_t fail_value,
bool check_specification_or_abstract_origin)
const {
624 check_specification_or_abstract_origin);
625 if (lo_pc != fail_value) {
627 check_specification_or_abstract_origin);
628 if (hi_pc != fail_value)
638 bool check_specification_or_abstract_origin)
const {
644 }
else if (check_hi_lo_pc) {
648 check_specification_or_abstract_origin)) {
670 bool substitute_name_allowed)
const {
671 const char *name =
nullptr;
681 if (!substitute_name_allowed)
693 const char *name =
nullptr;
715 if (
m_tag == DW_TAG_subprogram) {
719 for (
const auto &r : ranges) {
739 if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
740 return dwarf_decl_ctx;
743 if (!parent_decl_ctx_die || parent_decl_ctx_die.
GetDIE() == die)
744 return dwarf_decl_ctx;
745 if (parent_decl_ctx_die.
Tag() == DW_TAG_compile_unit ||
746 parent_decl_ctx_die.
Tag() == DW_TAG_partial_unit)
747 return dwarf_decl_ctx;
748 die = parent_decl_ctx_die.
GetDIE();
749 cu = parent_decl_ctx_die.
GetCU();
773 if (die.
GetDIE() !=
this) {
775 case DW_TAG_compile_unit:
776 case DW_TAG_partial_unit:
777 case DW_TAG_namespace:
778 case DW_TAG_structure_type:
779 case DW_TAG_union_type:
780 case DW_TAG_class_type:
822 if (
Tag() != DW_TAG_variable)
825 while (parent_die !=
nullptr) {
826 switch (parent_die->
Tag()) {
827 case DW_TAG_subprogram:
828 case DW_TAG_lexical_block:
829 case DW_TAG_inlined_subroutine:
832 case DW_TAG_compile_unit:
833 case DW_TAG_partial_unit:
852 return !(*
this == rhs);
static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit, const DWARFDebugInfoEntry &die, const DWARFFormValue &value)
const DWARFAbbreviationDeclaration * GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
DWARFDIE FormValueAsReference(dw_attr_t attr) const
void Append(const DWARFFormValue &form_value, dw_offset_t attr_die_offset, dw_attr_t attr)
size_t GetAttributes(DWARFAttributes &attributes, Recurse recurse=Recurse::yes) const
DWARFUnit * GetCU() const
DWARFDIE GetParent() const
DWARFDIE GetDIE(dw_offset_t die_offset) const
DWARFDIE GetParentDeclContextDIE() const
void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc)
DWARFDebugInfoEntry objects assume that they are living in one big vector and do pointer arithmetic o...
bool operator==(const DWARFDebugInfoEntry &rhs) const
std::optional< uint64_t > GetAttributeValueAsOptionalUnsigned(const DWARFUnit *cu, const dw_attr_t attr, bool check_specification_or_abstract_origin=false) const
size_t GetAttributeAddressRanges(DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, bool check_specification_or_abstract_origin=false) const
dw_offset_t GetOffset() const
size_t GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, Recurse recurse=Recurse::yes) const
dw_tag_t m_tag
A copy of the DW_TAG value so we don't have to go through the compile unit abbrev table.
const char * GetAttributeValueAsString(const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, bool check_specification_or_abstract_origin=false) const
dw_offset_t GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &formValue, dw_offset_t *end_attr_offset_ptr=nullptr, bool check_specification_or_abstract_origin=false) const
bool operator!=(const DWARFDebugInfoEntry &rhs) const
bool Extract(const lldb_private::DWARFDataExtractor &data, const DWARFUnit *cu, lldb::offset_t *offset_ptr)
DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const
DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const
bool GetAttributeAddressRange(const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
bool IsGlobalOrStaticScopeVariable() const
bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name, const char *&mangled, DWARFRangeList &rangeList, std::optional< int > &decl_file, std::optional< int > &decl_line, std::optional< int > &decl_column, std::optional< int > &call_file, std::optional< int > &call_line, std::optional< int > &call_column, lldb_private::DWARFExpressionList *frame_base=nullptr) const
const char * GetMangledName(const DWARFUnit *cu, bool substitute_name_allowed=true) const
dw_addr_t GetAttributeHighPC(const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
void BuildFunctionAddressRangeTable(DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const
This function is builds a table very similar to the standard .debug_aranges table,...
DWARFDIE GetAttributeValueAsReference(const DWARFUnit *cu, const dw_attr_t attr, bool check_specification_or_abstract_origin=false) const
uint64_t GetAttributeValueAsUnsigned(const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
const char * GetPubname(const DWARFUnit *cu) const
const DWARFAbbreviationDeclaration * GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const
uint64_t GetAttributeValueAsAddress(const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
DWARFDebugInfoEntry * GetFirstChild()
const char * GetName(const DWARFUnit *cu) const
DWARFDebugInfoEntry * GetSibling()
static DWARFDeclContext GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu)
lldb::offset_t GetFirstAttributeOffset() const
DWARFDebugInfoEntry * GetParent()
void AppendDeclContext(dw_tag_t tag, const char *name)
SymbolFileDWARF & GetSymbolFileDWARF() const
const lldb_private::DWARFDataExtractor & GetData() const
Get the data that contains the DIE information for this unit.
uint16_t GetVersion() const
lldb_private::DWARFDataExtractor GetLocationData() const
uint8_t GetAddressByteSize() const
llvm::Expected< DWARFRangeList > FindRnglistFromIndex(uint32_t index)
Return a list of address ranges retrieved from an encoded range list whose offset is found via a tabl...
const DWARFAbbreviationDeclarationSet * GetAbbreviations() const
dw_addr_t GetBaseAddress() const
llvm::Expected< DWARFRangeList > FindRnglistFromOffset(dw_offset_t offset)
Return a list of address ranges resulting from a (possibly encoded) range list starting at a given of...
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
void SetFuncFileAddress(lldb::addr_t func_file_addr)
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
static bool ParseDWARFLocationList(const DWARFUnit *dwarf_cu, const DataExtractor &data, DWARFExpressionList *loc_list)
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
void Append(const Entry &entry)
BaseType GetMinRangeBase(BaseType fail_value) const
ObjectFile * GetObjectFile() override
lldb_private::RangeVector< dw_addr_t, dw_addr_t, 2 > DWARFRangeList
llvm::dwarf::Tag dw_tag_t
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
const char * toString(AppleArm64ExceptionClass EC)