1*f6aab3d8Srobert //===-- DWARFASTParser.cpp ------------------------------------------------===// 2*f6aab3d8Srobert // 3*f6aab3d8Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*f6aab3d8Srobert // See https://llvm.org/LICENSE.txt for license information. 5*f6aab3d8Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*f6aab3d8Srobert // 7*f6aab3d8Srobert //===----------------------------------------------------------------------===// 8*f6aab3d8Srobert 9*f6aab3d8Srobert #include "DWARFASTParser.h" 10*f6aab3d8Srobert #include "DWARFAttribute.h" 11*f6aab3d8Srobert #include "DWARFDIE.h" 12*f6aab3d8Srobert 13*f6aab3d8Srobert #include "lldb/Core/ValueObject.h" 14*f6aab3d8Srobert #include "lldb/Symbol/SymbolFile.h" 15*f6aab3d8Srobert #include "lldb/Target/StackFrame.h" 16*f6aab3d8Srobert #include <optional> 17*f6aab3d8Srobert 18*f6aab3d8Srobert using namespace lldb; 19*f6aab3d8Srobert using namespace lldb_private; 20*f6aab3d8Srobert using namespace lldb_private::dwarf; 21*f6aab3d8Srobert 22*f6aab3d8Srobert std::optional<SymbolFile::ArrayInfo> ParseChildArrayInfo(const DWARFDIE & parent_die,const ExecutionContext * exe_ctx)23*f6aab3d8SrobertDWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, 24*f6aab3d8Srobert const ExecutionContext *exe_ctx) { 25*f6aab3d8Srobert SymbolFile::ArrayInfo array_info; 26*f6aab3d8Srobert if (!parent_die) 27*f6aab3d8Srobert return std::nullopt; 28*f6aab3d8Srobert 29*f6aab3d8Srobert for (DWARFDIE die : parent_die.children()) { 30*f6aab3d8Srobert const dw_tag_t tag = die.Tag(); 31*f6aab3d8Srobert if (tag != DW_TAG_subrange_type) 32*f6aab3d8Srobert continue; 33*f6aab3d8Srobert 34*f6aab3d8Srobert DWARFAttributes attributes; 35*f6aab3d8Srobert const size_t num_child_attributes = die.GetAttributes(attributes); 36*f6aab3d8Srobert if (num_child_attributes > 0) { 37*f6aab3d8Srobert uint64_t num_elements = 0; 38*f6aab3d8Srobert uint64_t lower_bound = 0; 39*f6aab3d8Srobert uint64_t upper_bound = 0; 40*f6aab3d8Srobert bool upper_bound_valid = false; 41*f6aab3d8Srobert uint32_t i; 42*f6aab3d8Srobert for (i = 0; i < num_child_attributes; ++i) { 43*f6aab3d8Srobert const dw_attr_t attr = attributes.AttributeAtIndex(i); 44*f6aab3d8Srobert DWARFFormValue form_value; 45*f6aab3d8Srobert if (attributes.ExtractFormValueAtIndex(i, form_value)) { 46*f6aab3d8Srobert switch (attr) { 47*f6aab3d8Srobert case DW_AT_name: 48*f6aab3d8Srobert break; 49*f6aab3d8Srobert 50*f6aab3d8Srobert case DW_AT_count: 51*f6aab3d8Srobert if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { 52*f6aab3d8Srobert if (var_die.Tag() == DW_TAG_variable) 53*f6aab3d8Srobert if (exe_ctx) { 54*f6aab3d8Srobert if (auto frame = exe_ctx->GetFrameSP()) { 55*f6aab3d8Srobert Status error; 56*f6aab3d8Srobert lldb::VariableSP var_sp; 57*f6aab3d8Srobert auto valobj_sp = frame->GetValueForVariableExpressionPath( 58*f6aab3d8Srobert var_die.GetName(), eNoDynamicValues, 0, var_sp, error); 59*f6aab3d8Srobert if (valobj_sp) { 60*f6aab3d8Srobert num_elements = valobj_sp->GetValueAsUnsigned(0); 61*f6aab3d8Srobert break; 62*f6aab3d8Srobert } 63*f6aab3d8Srobert } 64*f6aab3d8Srobert } 65*f6aab3d8Srobert } else 66*f6aab3d8Srobert num_elements = form_value.Unsigned(); 67*f6aab3d8Srobert break; 68*f6aab3d8Srobert 69*f6aab3d8Srobert case DW_AT_bit_stride: 70*f6aab3d8Srobert array_info.bit_stride = form_value.Unsigned(); 71*f6aab3d8Srobert break; 72*f6aab3d8Srobert 73*f6aab3d8Srobert case DW_AT_byte_stride: 74*f6aab3d8Srobert array_info.byte_stride = form_value.Unsigned(); 75*f6aab3d8Srobert break; 76*f6aab3d8Srobert 77*f6aab3d8Srobert case DW_AT_lower_bound: 78*f6aab3d8Srobert lower_bound = form_value.Unsigned(); 79*f6aab3d8Srobert break; 80*f6aab3d8Srobert 81*f6aab3d8Srobert case DW_AT_upper_bound: 82*f6aab3d8Srobert upper_bound_valid = true; 83*f6aab3d8Srobert upper_bound = form_value.Unsigned(); 84*f6aab3d8Srobert break; 85*f6aab3d8Srobert 86*f6aab3d8Srobert default: 87*f6aab3d8Srobert break; 88*f6aab3d8Srobert } 89*f6aab3d8Srobert } 90*f6aab3d8Srobert } 91*f6aab3d8Srobert 92*f6aab3d8Srobert if (num_elements == 0) { 93*f6aab3d8Srobert if (upper_bound_valid && upper_bound >= lower_bound) 94*f6aab3d8Srobert num_elements = upper_bound - lower_bound + 1; 95*f6aab3d8Srobert } 96*f6aab3d8Srobert 97*f6aab3d8Srobert array_info.element_orders.push_back(num_elements); 98*f6aab3d8Srobert } 99*f6aab3d8Srobert } 100*f6aab3d8Srobert return array_info; 101*f6aab3d8Srobert } 102*f6aab3d8Srobert 103*f6aab3d8Srobert AccessType GetAccessTypeFromDWARF(uint32_t dwarf_accessibility)104*f6aab3d8SrobertDWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) { 105*f6aab3d8Srobert switch (dwarf_accessibility) { 106*f6aab3d8Srobert case DW_ACCESS_public: 107*f6aab3d8Srobert return eAccessPublic; 108*f6aab3d8Srobert case DW_ACCESS_private: 109*f6aab3d8Srobert return eAccessPrivate; 110*f6aab3d8Srobert case DW_ACCESS_protected: 111*f6aab3d8Srobert return eAccessProtected; 112*f6aab3d8Srobert default: 113*f6aab3d8Srobert break; 114*f6aab3d8Srobert } 115*f6aab3d8Srobert return eAccessNone; 116*f6aab3d8Srobert } 117