17#include "llvm/Support/LEB128.h"
35#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
48 auto report_error = [&](
const char *fmt,
const auto &...vals) {
50 "[{0:x16}]: {1}, please file a bug and "
51 "attach the file at the start of this error message",
52 static_cast<uint64_t
>(
m_offset), llvm::formatv(fmt, vals...));
53 *offset_ptr = std::numeric_limits<lldb::offset_t>::max();
59 const uint64_t abbr_idx = data.
GetULEB128(offset_ptr);
60 if (abbr_idx > std::numeric_limits<uint16_t>::max())
61 return report_error(
"abbreviation code {0} too big", abbr_idx);
65 m_tag = llvm::dwarf::DW_TAG_null;
71 if (abbrevDecl ==
nullptr)
72 return report_error(
"invalid abbreviation code {0}", abbr_idx);
74 m_tag = abbrevDecl->getTag();
77 for (
const auto &attribute : abbrevDecl->attributes()) {
81 return report_error(
"Unsupported DW_FORM_{1:x}", attribute.Form);
89 llvm::Expected<DWARFRangeList> expected_ranges =
90 (value.
Form() == DW_FORM_rnglistx)
94 return std::move(*expected_ranges);
97 "[{0:x16}]: DIE has DW_AT_ranges({1} {2:x16}) attribute, but "
98 "range extraction failed ({3}), please file a bug "
99 "and attach the file at the start of this error message",
101 llvm::dwarf::FormEncodingString(value.
Form()).str().c_str(),
107 const llvm::DWARFAbbreviationDeclaration::AttributeSpec &attr_spec,
109 attr = attr_spec.Attr;
110 form_value.
FormRef() = attr_spec.Form;
111 if (attr_spec.isImplicitConst())
112 form_value.
SetSigned(attr_spec.getImplicitConstValue());
120 DWARFUnit *cu,
const char *&name,
const char *&mangled,
122 std::optional<int> &decl_line, std::optional<int> &decl_column,
123 std::optional<int> &call_file, std::optional<int> &call_line,
127 std::vector<DWARFDIE> dies;
128 bool set_frame_base_loclist_addr =
false;
140 bool do_offset =
false;
142 for (
const auto &attribute : abbrevDecl->attributes()) {
162 if (form_value.
Form() == DW_FORM_addr ||
163 form_value.
Form() == DW_FORM_addrx ||
164 form_value.
Form() == DW_FORM_GNU_addr_index) {
185 case DW_AT_MIPS_linkage_name:
186 case DW_AT_linkage_name:
187 if (mangled ==
nullptr)
191 case DW_AT_abstract_origin:
195 case DW_AT_specification:
199 case DW_AT_decl_file:
204 case DW_AT_decl_line:
209 case DW_AT_decl_column:
211 decl_column = form_value.
Unsigned();
214 case DW_AT_call_file:
219 case DW_AT_call_line:
224 case DW_AT_call_column:
226 call_column = form_value.
Unsigned();
229 case DW_AT_frame_base:
232 uint32_t block_offset =
234 uint32_t block_length = form_value.
Unsigned();
238 data, block_offset, block_length)),
250 set_frame_base_loclist_addr =
true;
272 if (set_frame_base_loclist_addr) {
278 if (ranges.
IsEmpty() || name ==
nullptr || mangled ==
nullptr) {
281 die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
282 decl_file, decl_line, decl_column,
283 call_file, call_line, call_column);
297 uint32_t curr_depth)
const {
307 for (
const auto &attribute : abbrevDecl->attributes()) {
317 case DW_AT_declaration:
318 if (curr_depth > 0) {
326 attributes.
Append(form_value, offset, attr);
330 if (recurse == Recurse::yes &&
331 ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) {
336 recurse, curr_depth + 1);
340 std::optional<uint8_t> fixed_skip_size =
343 offset += *fixed_skip_size;
359 bool check_specification_or_abstract_origin)
const {
361 std::optional<uint32_t> attr_idx = abbrevDecl->findAttributeIndex(attr);
368 while (idx < *attr_idx)
374 form_value.
SetForm(abbrevDecl->getFormByIndex(idx));
376 if (end_attr_offset_ptr)
377 *end_attr_offset_ptr = offset;
383 if (check_specification_or_abstract_origin) {
388 die.
GetCU(), attr, form_value, end_attr_offset_ptr,
false);
398 die.
GetCU(), attr, form_value, end_attr_offset_ptr,
false);
415 bool check_specification_or_abstract_origin)
const {
418 check_specification_or_abstract_origin))
428 bool check_specification_or_abstract_origin)
const {
431 check_specification_or_abstract_origin))
436std::optional<uint64_t>
439 bool check_specification_or_abstract_origin)
const {
442 check_specification_or_abstract_origin))
453 bool check_specification_or_abstract_origin)
const {
456 check_specification_or_abstract_origin))
463 bool check_specification_or_abstract_origin)
const {
466 check_specification_or_abstract_origin))
479 bool check_specification_or_abstract_origin)
const {
482 check_specification_or_abstract_origin)) {
484 if (form == DW_FORM_addr || form == DW_FORM_addrx ||
485 form == DW_FORM_GNU_addr_index)
489 return lo_pc + form_value.
Unsigned();
502 uint64_t fail_value,
bool check_specification_or_abstract_origin)
const {
504 check_specification_or_abstract_origin);
505 if (lo_pc != fail_value) {
507 check_specification_or_abstract_origin);
508 if (hi_pc != fail_value)
518 bool check_specification_or_abstract_origin)
const {
525 if (check_hi_lo_pc) {
529 check_specification_or_abstract_origin)) {
551 bool substitute_name_allowed)
const {
552 const char *name =
nullptr;
562 if (!substitute_name_allowed)
574 const char *name =
nullptr;
596 if (
m_tag == DW_TAG_subprogram) {
599 for (
const auto &r : ranges) {
617const llvm::DWARFAbbreviationDeclaration *
622 const llvm::DWARFAbbreviationDeclarationSet *abbrev_set =
627 return abbrev_set->getAbbreviationDeclaration(
m_abbr_idx);
631 if (
Tag() != DW_TAG_variable)
634 while (parent_die !=
nullptr) {
635 switch (parent_die->
Tag()) {
636 case DW_TAG_subprogram:
637 case DW_TAG_lexical_block:
638 case DW_TAG_inlined_subroutine:
641 case DW_TAG_compile_unit:
642 case DW_TAG_partial_unit:
661 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
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 GetDIE(dw_offset_t die_offset) 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 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
bool Extract(const DWARFDataExtractor &data, const DWARFUnit &cu, lldb::offset_t *offset_ptr)
uint64_t GetAttributeValueAsAddress(const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, bool check_specification_or_abstract_origin=false) const
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
DWARFDebugInfoEntry * GetFirstChild()
DWARFRangeList GetAttributeAddressRanges(DWARFUnit *cu, bool check_hi_lo_pc, bool check_specification_or_abstract_origin=false) const
lldb::offset_t GetFirstAttributeOffset() const
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::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