//===-- DWARFASTParser.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "DWARFASTParser.h" #include "DWARFAttribute.h" #include "DWARFDIE.h" #include "SymbolFileDWARF.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Target/StackFrame.h" #include using namespace lldb; using namespace lldb_private; using namespace lldb_private::dwarf; using namespace lldb_private::plugin::dwarf; std::optional DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, const ExecutionContext *exe_ctx) { SymbolFile::ArrayInfo array_info; if (!parent_die) return std::nullopt; for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); if (tag != DW_TAG_subrange_type) continue; DWARFAttributes attributes = die.GetAttributes(); if (attributes.Size() == 0) continue; uint64_t num_elements = 0; uint64_t lower_bound = 0; uint64_t upper_bound = 0; bool upper_bound_valid = false; for (size_t i = 0; i < attributes.Size(); ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_name: break; case DW_AT_count: if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { if (var_die.Tag() == DW_TAG_variable) if (exe_ctx) { if (auto frame = exe_ctx->GetFrameSP()) { Status error; lldb::VariableSP var_sp; auto valobj_sp = frame->GetValueForVariableExpressionPath( var_die.GetName(), eNoDynamicValues, 0, var_sp, error); if (valobj_sp) { num_elements = valobj_sp->GetValueAsUnsigned(0); break; } } } } else num_elements = form_value.Unsigned(); break; case DW_AT_bit_stride: array_info.bit_stride = form_value.Unsigned(); break; case DW_AT_byte_stride: array_info.byte_stride = form_value.Unsigned(); break; case DW_AT_lower_bound: lower_bound = form_value.Unsigned(); break; case DW_AT_upper_bound: upper_bound_valid = true; upper_bound = form_value.Unsigned(); break; default: break; } } } if (num_elements == 0) { if (upper_bound_valid && upper_bound >= lower_bound) num_elements = upper_bound - lower_bound + 1; } array_info.element_orders.push_back(num_elements); } return array_info; } Type *DWARFASTParser::GetTypeForDIE(const DWARFDIE &die) { if (!die) return nullptr; SymbolFileDWARF *dwarf = die.GetDWARF(); if (!dwarf) return nullptr; DWARFAttributes attributes = die.GetAttributes(); if (attributes.Size() == 0) return nullptr; DWARFFormValue type_die_form; for (size_t i = 0; i < attributes.Size(); ++i) { dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value)) return dwarf->ResolveTypeUID(form_value.Reference(), true); } return nullptr; } AccessType DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) { switch (dwarf_accessibility) { case DW_ACCESS_public: return eAccessPublic; case DW_ACCESS_private: return eAccessPrivate; case DW_ACCESS_protected: return eAccessProtected; default: break; } return eAccessNone; }