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 #include <optional> 17 18 using namespace lldb; 19 using namespace lldb_private; 20 using namespace lldb_private::dwarf; 21 22 std::optional<SymbolFile::ArrayInfo> 23 DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, 24 const ExecutionContext *exe_ctx) { 25 SymbolFile::ArrayInfo array_info; 26 if (!parent_die) 27 return std::nullopt; 28 29 for (DWARFDIE die : parent_die.children()) { 30 const dw_tag_t tag = die.Tag(); 31 if (tag != DW_TAG_subrange_type) 32 continue; 33 34 DWARFAttributes attributes = die.GetAttributes(); 35 if (attributes.Size() == 0) 36 continue; 37 38 uint64_t num_elements = 0; 39 uint64_t lower_bound = 0; 40 uint64_t upper_bound = 0; 41 bool upper_bound_valid = false; 42 for (size_t i = 0; i < attributes.Size(); ++i) { 43 const dw_attr_t attr = attributes.AttributeAtIndex(i); 44 DWARFFormValue form_value; 45 if (attributes.ExtractFormValueAtIndex(i, form_value)) { 46 switch (attr) { 47 case DW_AT_name: 48 break; 49 50 case DW_AT_count: 51 if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { 52 if (var_die.Tag() == DW_TAG_variable) 53 if (exe_ctx) { 54 if (auto frame = exe_ctx->GetFrameSP()) { 55 Status error; 56 lldb::VariableSP var_sp; 57 auto valobj_sp = frame->GetValueForVariableExpressionPath( 58 var_die.GetName(), eNoDynamicValues, 0, var_sp, error); 59 if (valobj_sp) { 60 num_elements = valobj_sp->GetValueAsUnsigned(0); 61 break; 62 } 63 } 64 } 65 } else 66 num_elements = form_value.Unsigned(); 67 break; 68 69 case DW_AT_bit_stride: 70 array_info.bit_stride = form_value.Unsigned(); 71 break; 72 73 case DW_AT_byte_stride: 74 array_info.byte_stride = form_value.Unsigned(); 75 break; 76 77 case DW_AT_lower_bound: 78 lower_bound = form_value.Unsigned(); 79 break; 80 81 case DW_AT_upper_bound: 82 upper_bound_valid = true; 83 upper_bound = form_value.Unsigned(); 84 break; 85 86 default: 87 break; 88 } 89 } 90 } 91 92 if (num_elements == 0) { 93 if (upper_bound_valid && upper_bound >= lower_bound) 94 num_elements = upper_bound - lower_bound + 1; 95 } 96 97 array_info.element_orders.push_back(num_elements); 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