16#include "llvm/Support/LEB128.h"
34#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
49 const uint64_t abbr_idx = data.
GetULEB128(offset_ptr);
54 m_tag = llvm::dwarf::DW_TAG_null;
60 if (abbrevDecl ==
nullptr) {
62 "[{0:x16}]: invalid abbreviation code {1}, "
63 "please file a bug and "
64 "attach the file at the start of this error message",
65 (uint64_t)
m_offset, (
unsigned)abbr_idx);
70 m_tag = abbrevDecl->getTag();
73 for (
const auto &attribute : abbrevDecl->attributes()) {
78 "[{0:x16}]: Unsupported DW_FORM_{1:x}, please file a bug "
80 "attach the file at the start of this error message",
81 (uint64_t)
m_offset, (
unsigned)attribute.Form);
91 llvm::Expected<DWARFRangeList> expected_ranges =
92 (value.
Form() == DW_FORM_rnglistx)
96 return std::move(*expected_ranges);
99 "[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
100 "range extraction failed ({3}), please file a bug "
101 "and attach the file at the start of this error message",
103 llvm::dwarf::FormEncodingString(value.
Form()).str().c_str(),
109 const llvm::DWARFAbbreviationDeclaration::AttributeSpec &attr_spec,
111 attr = attr_spec.Attr;
112 form_value.
FormRef() = attr_spec.Form;
113 if (attr_spec.isImplicitConst())
114 form_value.
SetSigned(attr_spec.getImplicitConstValue());
122 DWARFUnit *cu,
const char *&name,
const char *&mangled,
124 std::optional<int> &decl_line, std::optional<int> &decl_column,
125 std::optional<int> &call_file, std::optional<int> &call_line,
129 std::vector<DWARFDIE> dies;
130 bool set_frame_base_loclist_addr =
false;
142 bool do_offset =
false;
144 for (
const auto &attribute : abbrevDecl->attributes()) {
164 if (form_value.
Form() == DW_FORM_addr ||
165 form_value.
Form() == DW_FORM_addrx ||
166 form_value.
Form() == DW_FORM_GNU_addr_index) {
187 case DW_AT_MIPS_linkage_name:
188 case DW_AT_linkage_name:
189 if (mangled ==
nullptr)
193 case DW_AT_abstract_origin:
197 case DW_AT_specification:
201 case DW_AT_decl_file:
206 case DW_AT_decl_line:
211 case DW_AT_decl_column:
213 decl_column = form_value.
Unsigned();
216 case DW_AT_call_file:
221 case DW_AT_call_line:
226 case DW_AT_call_column:
228 call_column = form_value.
Unsigned();
231 case DW_AT_frame_base:
234 uint32_t block_offset =
236 uint32_t block_length = form_value.
Unsigned();
240 data, block_offset, block_length)),
252 set_frame_base_loclist_addr =
true;
274 if (set_frame_base_loclist_addr) {
280 if (ranges.
IsEmpty() || name ==
nullptr || mangled ==
nullptr) {
283 die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
284 decl_file, decl_line, decl_column,
285 call_file, call_line, call_column);
299 uint32_t curr_depth)
const {
309 for (
const auto &attribute : abbrevDecl->attributes()) {
319 case DW_AT_declaration:
320 if (curr_depth > 0) {
328 attributes.
Append(form_value, offset, attr);
332 if (recurse == Recurse::yes &&
333 ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) {
338 recurse, curr_depth + 1);
342 std::optional<uint8_t> fixed_skip_size =
345 offset += *fixed_skip_size;
361 bool check_specification_or_abstract_origin)
const {
363 std::optional<uint32_t> attr_idx = abbrevDecl->findAttributeIndex(attr);
370 while (idx < *attr_idx)
376 form_value.
SetForm(abbrevDecl->getFormByIndex(idx));
378 if (end_attr_offset_ptr)
379 *end_attr_offset_ptr = offset;
385 if (check_specification_or_abstract_origin) {
390 die.
GetCU(), attr, form_value, end_attr_offset_ptr,
false);
400 die.
GetCU(), attr, form_value, end_attr_offset_ptr,
false);
417 bool check_specification_or_abstract_origin)
const {
420 check_specification_or_abstract_origin))
430 bool check_specification_or_abstract_origin)
const {
433 check_specification_or_abstract_origin))
438std::optional<uint64_t>
441 bool check_specification_or_abstract_origin)
const {
444 check_specification_or_abstract_origin))
455 bool check_specification_or_abstract_origin)
const {
458 check_specification_or_abstract_origin))
465 bool check_specification_or_abstract_origin)
const {
468 check_specification_or_abstract_origin))
481 bool check_specification_or_abstract_origin)
const {
484 check_specification_or_abstract_origin)) {
486 if (form == DW_FORM_addr || form == DW_FORM_addrx ||
487 form == DW_FORM_GNU_addr_index)
491 return lo_pc + form_value.
Unsigned();
504 uint64_t fail_value,
bool check_specification_or_abstract_origin)
const {
506 check_specification_or_abstract_origin);
507 if (lo_pc != fail_value) {
509 check_specification_or_abstract_origin);
510 if (hi_pc != fail_value)
520 bool check_specification_or_abstract_origin)
const {
527 if (check_hi_lo_pc) {
531 check_specification_or_abstract_origin)) {
553 bool substitute_name_allowed)
const {
554 const char *name =
nullptr;
564 if (!substitute_name_allowed)
576 const char *name =
nullptr;
598 if (
m_tag == DW_TAG_subprogram) {
601 for (
const auto &r : ranges) {
621 if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
622 return dwarf_decl_ctx;
625 if (!parent_decl_ctx_die || parent_decl_ctx_die.
GetDIE() == die)
626 return dwarf_decl_ctx;
627 if (parent_decl_ctx_die.
Tag() == DW_TAG_compile_unit ||
628 parent_decl_ctx_die.
Tag() == DW_TAG_partial_unit)
629 return dwarf_decl_ctx;
630 die = parent_decl_ctx_die.
GetDIE();
631 cu = parent_decl_ctx_die.
GetCU();
654 if (die.
GetDIE() !=
this) {
656 case DW_TAG_compile_unit:
657 case DW_TAG_partial_unit:
658 case DW_TAG_namespace:
659 case DW_TAG_structure_type:
660 case DW_TAG_union_type:
661 case DW_TAG_class_type:
692const llvm::DWARFAbbreviationDeclaration *
697 const llvm::DWARFAbbreviationDeclarationSet *abbrev_set =
702 return abbrev_set->getAbbreviationDeclaration(
m_abbr_idx);
706 if (
Tag() != DW_TAG_variable)
709 while (parent_die !=
nullptr) {
710 switch (parent_die->
Tag()) {
711 case DW_TAG_subprogram:
712 case DW_TAG_lexical_block:
713 case DW_TAG_inlined_subroutine:
716 case DW_TAG_compile_unit:
717 case DW_TAG_partial_unit:
736 return !(*
this == rhs);
static void ExtractAttrAndFormValue(const llvm::DWARFAbbreviationDeclaration::AttributeSpec &attr_spec, dw_attr_t &attr, DWARFFormValue &form_value)
static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit, const DWARFDebugInfoEntry &die, const DWARFFormValue &value)
"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 plugin::dwarf::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
DWARFDIE FormValueAsReference(dw_attr_t attr) const
void Append(const DWARFFormValue &form_value, dw_offset_t attr_die_offset, dw_attr_t attr)
DWARFAttributes GetAttributes(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
dw_offset_t GetOffset() 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
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
DWARFAttributes GetAttributes(DWARFUnit *cu, Recurse recurse=Recurse::yes) const
const char * GetMangledName(const DWARFUnit *cu, bool substitute_name_allowed=true) const
const llvm::DWARFAbbreviationDeclaration * GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const
DWARFDebugInfoEntry * GetSibling()
dw_addr_t GetAttributeHighPC(const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
DWARFDebugInfoEntry * GetParent()
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
uint64_t GetAttributeValueAsAddress(const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
bool Extract(const DWARFDataExtractor &data, const DWARFUnit *cu, lldb::offset_t *offset_ptr)
const char * GetName(const DWARFUnit *cu) 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, DWARFExpressionList *frame_base=nullptr) const
static DWARFDeclContext GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu)
DWARFDebugInfoEntry * GetFirstChild()
DWARFRangeList GetAttributeAddressRanges(DWARFUnit *cu, bool check_hi_lo_pc, bool check_specification_or_abstract_origin=false) const
lldb::offset_t GetFirstAttributeOffset() const
void AppendDeclContext(dw_tag_t tag, const char *name)
dw_addr_t GetBaseAddress() const
SymbolFileDWARF & GetSymbolFileDWARF() const
const DWARFDataExtractor & GetData() const
Get the data that contains the DIE information for this unit.
DWARFDataExtractor GetLocationData() 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 llvm::DWARFAbbreviationDeclarationSet * GetAbbreviations() 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_private::RangeVector< dw_addr_t, dw_addr_t, 2 > DWARFRangeList
llvm::dwarf::Tag dw_tag_t
llvm::dwarf::Attribute dw_attr_t
llvm::dwarf::Form dw_form_t
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
const char * toString(AppleArm64ExceptionClass EC)
std::shared_ptr< lldb_private::Module > ModuleSP