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(attr: 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_expr: var_die.GetName(), use_dynamic: eNoDynamicValues, options: 0, var_sp, error); |
61 | if (valobj_sp) { |
62 | num_elements = valobj_sp->GetValueAsUnsigned(fail_value: 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(Elt: 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(die: form_value.Reference(), assert_not_being_parsed: 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 |