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->getTag();
76 for (
const auto &attribute : abbrevDecl->attributes()) {
77 form = attribute.Form;
78 std::optional<uint8_t> fixed_skip_size =
81 offset += *fixed_skip_size;
83 bool form_is_indirect =
false;
85 form_is_indirect =
false;
86 uint32_t form_size = 0;
113 case DW_FORM_ref_addr:
121 case DW_FORM_flag_present:
159 case DW_FORM_ref_sig8:
165 case DW_FORM_loclistx:
166 case DW_FORM_rnglistx:
169 case DW_FORM_ref_udata:
170 case DW_FORM_GNU_addr_index:
171 case DW_FORM_GNU_str_index:
176 case DW_FORM_indirect:
177 form_is_indirect =
true;
182 case DW_FORM_line_strp:
183 case DW_FORM_sec_offset:
187 case DW_FORM_implicit_const:
193 "[{0:x16}]: Unsupported DW_FORM_{1:x}, please file a bug "
195 "attach the file at the start of this error message",
196 (uint64_t)
m_offset, (unsigned)form);
202 }
while (form_is_indirect);
205 *offset_ptr = offset;
212 llvm::Expected<DWARFRangeList> expected_ranges =
213 (value.
Form() == DW_FORM_rnglistx)
217 return std::move(*expected_ranges);
220 "[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
221 "range extraction failed ({3}), please file a bug "
222 "and attach the file at the start of this error message",
224 llvm::dwarf::FormEncodingString(value.
Form()).str().c_str(),
230 const llvm::DWARFAbbreviationDeclaration::AttributeSpec &attr_spec,
232 attr = attr_spec.Attr;
233 form_value.
FormRef() = attr_spec.Form;
234 if (attr_spec.isImplicitConst())
235 form_value.
SetSigned(attr_spec.getImplicitConstValue());
243 DWARFUnit *cu,
const char *&name,
const char *&mangled,
245 std::optional<int> &decl_line, std::optional<int> &decl_column,
246 std::optional<int> &call_file, std::optional<int> &call_line,
250 std::vector<DWARFDIE> dies;
251 bool set_frame_base_loclist_addr =
false;
263 bool do_offset =
false;
265 for (
const auto &attribute : abbrevDecl->attributes()) {
285 if (form_value.
Form() == DW_FORM_addr ||
286 form_value.
Form() == DW_FORM_addrx ||
287 form_value.
Form() == DW_FORM_GNU_addr_index) {
308 case DW_AT_MIPS_linkage_name:
309 case DW_AT_linkage_name:
310 if (mangled ==
nullptr)
314 case DW_AT_abstract_origin:
318 case DW_AT_specification:
322 case DW_AT_decl_file:
327 case DW_AT_decl_line:
332 case DW_AT_decl_column:
334 decl_column = form_value.
Unsigned();
337 case DW_AT_call_file:
342 case DW_AT_call_line:
347 case DW_AT_call_column:
349 call_column = form_value.
Unsigned();
352 case DW_AT_frame_base:
355 uint32_t block_offset =
357 uint32_t block_length = form_value.
Unsigned();
361 data, block_offset, block_length)),
373 set_frame_base_loclist_addr =
true;
395 if (set_frame_base_loclist_addr) {
401 if (ranges.
IsEmpty() || name ==
nullptr || mangled ==
nullptr) {
404 die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
405 decl_file, decl_line, decl_column,
406 call_file, call_line, call_column);
420 uint32_t curr_depth)
const {
430 for (
const auto &attribute : abbrevDecl->attributes()) {
440 case DW_AT_declaration:
441 if (curr_depth > 0) {
449 attributes.
Append(form_value, offset, attr);
453 if (recurse == Recurse::yes &&
454 ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) {
459 recurse, curr_depth + 1);
463 std::optional<uint8_t> fixed_skip_size =
466 offset += *fixed_skip_size;
482 bool check_specification_or_abstract_origin)
const {
484 std::optional<uint32_t> attr_idx = abbrevDecl->findAttributeIndex(attr);
491 while (idx < *attr_idx)
497 form_value.
SetForm(abbrevDecl->getFormByIndex(idx));
499 if (end_attr_offset_ptr)
500 *end_attr_offset_ptr = offset;
506 if (check_specification_or_abstract_origin) {
511 die.
GetCU(), attr, form_value, end_attr_offset_ptr,
false);
521 die.
GetCU(), attr, form_value, end_attr_offset_ptr,
false);
538 bool check_specification_or_abstract_origin)
const {
541 check_specification_or_abstract_origin))
551 bool check_specification_or_abstract_origin)
const {
554 check_specification_or_abstract_origin))
559std::optional<uint64_t>
562 bool check_specification_or_abstract_origin)
const {
565 check_specification_or_abstract_origin))
576 bool check_specification_or_abstract_origin)
const {
579 check_specification_or_abstract_origin))
586 bool check_specification_or_abstract_origin)
const {
589 check_specification_or_abstract_origin))
602 bool check_specification_or_abstract_origin)
const {
605 check_specification_or_abstract_origin)) {
607 if (form == DW_FORM_addr || form == DW_FORM_addrx ||
608 form == DW_FORM_GNU_addr_index)
612 return lo_pc + form_value.
Unsigned();
625 uint64_t fail_value,
bool check_specification_or_abstract_origin)
const {
627 check_specification_or_abstract_origin);
628 if (lo_pc != fail_value) {
630 check_specification_or_abstract_origin);
631 if (hi_pc != fail_value)
641 bool check_specification_or_abstract_origin)
const {
648 if (check_hi_lo_pc) {
652 check_specification_or_abstract_origin)) {
674 bool substitute_name_allowed)
const {
675 const char *name =
nullptr;
685 if (!substitute_name_allowed)
697 const char *name =
nullptr;
719 if (
m_tag == DW_TAG_subprogram) {
722 for (
const auto &r : ranges) {
742 if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
743 return dwarf_decl_ctx;
746 if (!parent_decl_ctx_die || parent_decl_ctx_die.
GetDIE() == die)
747 return dwarf_decl_ctx;
748 if (parent_decl_ctx_die.
Tag() == DW_TAG_compile_unit ||
749 parent_decl_ctx_die.
Tag() == DW_TAG_partial_unit)
750 return dwarf_decl_ctx;
751 die = parent_decl_ctx_die.
GetDIE();
752 cu = parent_decl_ctx_die.
GetCU();
775 if (die.
GetDIE() !=
this) {
777 case DW_TAG_compile_unit:
778 case DW_TAG_partial_unit:
779 case DW_TAG_namespace:
780 case DW_TAG_structure_type:
781 case DW_TAG_union_type:
782 case DW_TAG_class_type:
822 return abbrev_set->getAbbreviationDeclaration(
m_abbr_idx);
826 if (
Tag() != DW_TAG_variable)
829 while (parent_die !=
nullptr) {
830 switch (parent_die->
Tag()) {
831 case DW_TAG_subprogram:
832 case DW_TAG_lexical_block:
833 case DW_TAG_inlined_subroutine:
836 case DW_TAG_compile_unit:
837 case DW_TAG_partial_unit:
856 return !(*
this == rhs);
llvm::DWARFAbbreviationDeclarationSet DWARFAbbreviationDeclarationSet
llvm::DWARFAbbreviationDeclaration DWARFAbbreviationDeclaration
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)
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
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 llvm::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
DWARFAttributes GetAttributes(DWARFUnit *cu, Recurse recurse=Recurse::yes) const
DWARFDebugInfoEntry * GetSibling()
static DWARFDeclContext GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu)
DWARFRangeList GetAttributeAddressRanges(DWARFUnit *cu, bool check_hi_lo_pc, bool check_specification_or_abstract_origin=false) const
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
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