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>
ParseChildArrayInfo(const DWARFDIE & parent_die,const ExecutionContext * exe_ctx)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 
GetTypeForDIE(const DWARFDIE & die)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
GetAccessTypeFromDWARF(uint32_t dwarf_accessibility)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