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