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