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 #include "SymbolFileDWARF.h" 13 14 #include "lldb/Core/ValueObject.h" 15 #include "lldb/Symbol/SymbolFile.h" 16 #include "lldb/Target/StackFrame.h" 17 #include <optional> 18 19 using namespace lldb; 20 using namespace lldb_private; 21 using namespace lldb_private::dwarf; 22 using namespace lldb_private::plugin::dwarf; 23 24 std::optional<SymbolFile::ArrayInfo> 25 DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, 26 const ExecutionContext *exe_ctx) { 27 SymbolFile::ArrayInfo array_info; 28 if (!parent_die) 29 return std::nullopt; 30 31 for (DWARFDIE die : parent_die.children()) { 32 const dw_tag_t tag = die.Tag(); 33 if (tag != DW_TAG_subrange_type) 34 continue; 35 36 DWARFAttributes attributes = die.GetAttributes(); 37 if (attributes.Size() == 0) 38 continue; 39 40 uint64_t num_elements = 0; 41 uint64_t lower_bound = 0; 42 uint64_t upper_bound = 0; 43 bool upper_bound_valid = false; 44 for (size_t i = 0; i < attributes.Size(); ++i) { 45 const dw_attr_t attr = attributes.AttributeAtIndex(i); 46 DWARFFormValue form_value; 47 if (attributes.ExtractFormValueAtIndex(i, form_value)) { 48 switch (attr) { 49 case DW_AT_name: 50 break; 51 52 case DW_AT_count: 53 if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { 54 if (var_die.Tag() == DW_TAG_variable) 55 if (exe_ctx) { 56 if (auto frame = exe_ctx->GetFrameSP()) { 57 Status error; 58 lldb::VariableSP var_sp; 59 auto valobj_sp = frame->GetValueForVariableExpressionPath( 60 var_die.GetName(), eNoDynamicValues, 0, var_sp, error); 61 if (valobj_sp) { 62 num_elements = valobj_sp->GetValueAsUnsigned(0); 63 break; 64 } 65 } 66 } 67 } else 68 num_elements = form_value.Unsigned(); 69 break; 70 71 case DW_AT_bit_stride: 72 array_info.bit_stride = form_value.Unsigned(); 73 break; 74 75 case DW_AT_byte_stride: 76 array_info.byte_stride = form_value.Unsigned(); 77 break; 78 79 case DW_AT_lower_bound: 80 lower_bound = form_value.Unsigned(); 81 break; 82 83 case DW_AT_upper_bound: 84 upper_bound_valid = true; 85 upper_bound = form_value.Unsigned(); 86 break; 87 88 default: 89 break; 90 } 91 } 92 } 93 94 if (num_elements == 0) { 95 if (upper_bound_valid && upper_bound >= lower_bound) 96 num_elements = upper_bound - lower_bound + 1; 97 } 98 99 array_info.element_orders.push_back(num_elements); 100 } 101 return array_info; 102 } 103 104 Type *DWARFASTParser::GetTypeForDIE(const DWARFDIE &die) { 105 if (!die) 106 return nullptr; 107 108 SymbolFileDWARF *dwarf = die.GetDWARF(); 109 if (!dwarf) 110 return nullptr; 111 112 DWARFAttributes attributes = die.GetAttributes(); 113 if (attributes.Size() == 0) 114 return nullptr; 115 116 DWARFFormValue type_die_form; 117 for (size_t i = 0; i < attributes.Size(); ++i) { 118 dw_attr_t attr = attributes.AttributeAtIndex(i); 119 DWARFFormValue form_value; 120 121 if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value)) 122 return dwarf->ResolveTypeUID(form_value.Reference(), true); 123 } 124 125 return nullptr; 126 } 127 128 AccessType 129 DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) { 130 switch (dwarf_accessibility) { 131 case DW_ACCESS_public: 132 return eAccessPublic; 133 case DW_ACCESS_private: 134 return eAccessPrivate; 135 case DW_ACCESS_protected: 136 return eAccessProtected; 137 default: 138 break; 139 } 140 return eAccessNone; 141 } 142