clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DWARFFormValue.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Analysis -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ASMParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/BinaryFormat -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitstream -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /include/llvm/CodeGen -I /include/llvm/CodeGen/PBQP -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Coroutines -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData/Coverage -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/CodeView -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/DWARF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/MSF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/PDB -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Demangle -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/JITLink -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/Orc -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenACC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenMP -I /include/llvm/CodeGen/GlobalISel -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IRReader -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/LTO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Linker -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC/MCParser -I /include/llvm/CodeGen/MIRParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Object -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Option -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Passes -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Scalar -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ADT -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Support -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/Symbolize -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Target -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Utils -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Vectorize -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/IPO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libLLVM/../include -I /usr/src/gnu/usr.bin/clang/libLLVM/obj -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" |
10 | #include "llvm/ADT/ArrayRef.h" |
11 | #include "llvm/ADT/None.h" |
12 | #include "llvm/ADT/Optional.h" |
13 | #include "llvm/ADT/StringRef.h" |
14 | #include "llvm/BinaryFormat/Dwarf.h" |
15 | #include "llvm/DebugInfo/DWARF/DWARFContext.h" |
16 | #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" |
17 | #include "llvm/DebugInfo/DWARF/DWARFUnit.h" |
18 | #include "llvm/Support/ErrorHandling.h" |
19 | #include "llvm/Support/Format.h" |
20 | #include "llvm/Support/WithColor.h" |
21 | #include "llvm/Support/raw_ostream.h" |
22 | #include <cinttypes> |
23 | #include <cstdint> |
24 | #include <limits> |
25 | |
26 | using namespace llvm; |
27 | using namespace dwarf; |
28 | |
29 | static const DWARFFormValue::FormClass DWARF5FormClasses[] = { |
30 | DWARFFormValue::FC_Unknown, |
31 | DWARFFormValue::FC_Address, |
32 | DWARFFormValue::FC_Unknown, |
33 | DWARFFormValue::FC_Block, |
34 | DWARFFormValue::FC_Block, |
35 | DWARFFormValue::FC_Constant, |
36 | |
37 | DWARFFormValue::FC_Constant, |
38 | DWARFFormValue::FC_Constant, |
39 | |
40 | DWARFFormValue::FC_String, |
41 | DWARFFormValue::FC_Block, |
42 | DWARFFormValue::FC_Block, |
43 | DWARFFormValue::FC_Constant, |
44 | DWARFFormValue::FC_Flag, |
45 | DWARFFormValue::FC_Constant, |
46 | DWARFFormValue::FC_String, |
47 | DWARFFormValue::FC_Constant, |
48 | DWARFFormValue::FC_Reference, |
49 | DWARFFormValue::FC_Reference, |
50 | DWARFFormValue::FC_Reference, |
51 | DWARFFormValue::FC_Reference, |
52 | DWARFFormValue::FC_Reference, |
53 | DWARFFormValue::FC_Reference, |
54 | DWARFFormValue::FC_Indirect, |
55 | DWARFFormValue::FC_SectionOffset, |
56 | DWARFFormValue::FC_Exprloc, |
57 | DWARFFormValue::FC_Flag, |
58 | DWARFFormValue::FC_String, |
59 | DWARFFormValue::FC_Address, |
60 | DWARFFormValue::FC_Reference, |
61 | DWARFFormValue::FC_String, |
62 | DWARFFormValue::FC_Constant, |
63 | DWARFFormValue::FC_String, |
64 | DWARFFormValue::FC_Reference, |
65 | DWARFFormValue::FC_Constant, |
66 | DWARFFormValue::FC_SectionOffset, |
67 | DWARFFormValue::FC_SectionOffset, |
68 | DWARFFormValue::FC_Reference, |
69 | DWARFFormValue::FC_String, |
70 | DWARFFormValue::FC_String, |
71 | DWARFFormValue::FC_String, |
72 | DWARFFormValue::FC_String, |
73 | DWARFFormValue::FC_Address, |
74 | DWARFFormValue::FC_Address, |
75 | DWARFFormValue::FC_Address, |
76 | DWARFFormValue::FC_Address, |
77 | DWARFFormValue::FC_Address, |
78 | }; |
79 | |
80 | DWARFFormValue DWARFFormValue::createFromSValue(dwarf::Form F, int64_t V) { |
81 | return DWARFFormValue(F, ValueType(V)); |
82 | } |
83 | |
84 | DWARFFormValue DWARFFormValue::createFromUValue(dwarf::Form F, uint64_t V) { |
85 | return DWARFFormValue(F, ValueType(V)); |
86 | } |
87 | |
88 | DWARFFormValue DWARFFormValue::createFromPValue(dwarf::Form F, const char *V) { |
89 | return DWARFFormValue(F, ValueType(V)); |
90 | } |
91 | |
92 | DWARFFormValue DWARFFormValue::createFromBlockValue(dwarf::Form F, |
93 | ArrayRef<uint8_t> D) { |
94 | ValueType V; |
95 | V.uval = D.size(); |
96 | V.data = D.data(); |
97 | return DWARFFormValue(F, V); |
98 | } |
99 | |
100 | DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U, |
101 | uint64_t *OffsetPtr) { |
102 | DWARFFormValue FormValue(F); |
103 | FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, |
104 | U->getFormParams(), U); |
105 | return FormValue; |
106 | } |
107 | |
108 | bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, |
109 | uint64_t *OffsetPtr, |
110 | const dwarf::FormParams Params) { |
111 | bool Indirect = false; |
112 | do { |
113 | switch (Form) { |
114 | |
115 | |
116 | case DW_FORM_exprloc: |
117 | case DW_FORM_block: { |
118 | uint64_t size = DebugInfoData.getULEB128(OffsetPtr); |
119 | *OffsetPtr += size; |
120 | return true; |
121 | } |
122 | case DW_FORM_block1: { |
123 | uint8_t size = DebugInfoData.getU8(OffsetPtr); |
124 | *OffsetPtr += size; |
125 | return true; |
126 | } |
127 | case DW_FORM_block2: { |
128 | uint16_t size = DebugInfoData.getU16(OffsetPtr); |
129 | *OffsetPtr += size; |
130 | return true; |
131 | } |
132 | case DW_FORM_block4: { |
133 | uint32_t size = DebugInfoData.getU32(OffsetPtr); |
134 | *OffsetPtr += size; |
135 | return true; |
136 | } |
137 | |
138 | |
139 | case DW_FORM_string: |
140 | DebugInfoData.getCStr(OffsetPtr); |
141 | return true; |
142 | |
143 | case DW_FORM_addr: |
144 | case DW_FORM_ref_addr: |
145 | case DW_FORM_flag_present: |
146 | case DW_FORM_data1: |
147 | case DW_FORM_data2: |
148 | case DW_FORM_data4: |
149 | case DW_FORM_data8: |
150 | case DW_FORM_data16: |
151 | case DW_FORM_flag: |
152 | case DW_FORM_ref1: |
153 | case DW_FORM_ref2: |
154 | case DW_FORM_ref4: |
155 | case DW_FORM_ref8: |
156 | case DW_FORM_ref_sig8: |
157 | case DW_FORM_ref_sup4: |
158 | case DW_FORM_ref_sup8: |
159 | case DW_FORM_strx1: |
160 | case DW_FORM_strx2: |
161 | case DW_FORM_strx4: |
162 | case DW_FORM_addrx1: |
163 | case DW_FORM_addrx2: |
164 | case DW_FORM_addrx4: |
165 | case DW_FORM_sec_offset: |
166 | case DW_FORM_strp: |
167 | case DW_FORM_strp_sup: |
168 | case DW_FORM_line_strp: |
169 | case DW_FORM_GNU_ref_alt: |
170 | case DW_FORM_GNU_strp_alt: |
171 | case DW_FORM_implicit_const: |
172 | if (Optional<uint8_t> FixedSize = |
173 | dwarf::getFixedFormByteSize(Form, Params)) { |
174 | *OffsetPtr += *FixedSize; |
175 | return true; |
176 | } |
177 | return false; |
178 | |
179 | |
180 | case DW_FORM_sdata: |
181 | DebugInfoData.getSLEB128(OffsetPtr); |
182 | return true; |
183 | |
184 | case DW_FORM_udata: |
185 | case DW_FORM_ref_udata: |
186 | case DW_FORM_strx: |
187 | case DW_FORM_addrx: |
188 | case DW_FORM_loclistx: |
189 | case DW_FORM_rnglistx: |
190 | case DW_FORM_GNU_addr_index: |
191 | case DW_FORM_GNU_str_index: |
192 | DebugInfoData.getULEB128(OffsetPtr); |
193 | return true; |
194 | |
195 | case DW_FORM_LLVM_addrx_offset: |
196 | DebugInfoData.getULEB128(OffsetPtr); |
197 | *OffsetPtr += 4; |
198 | return true; |
199 | |
200 | case DW_FORM_indirect: |
201 | Indirect = true; |
202 | Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr)); |
203 | break; |
204 | |
205 | default: |
206 | return false; |
207 | } |
208 | } while (Indirect); |
209 | return true; |
210 | } |
211 | |
212 | bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { |
213 | |
214 | if (Form < makeArrayRef(DWARF5FormClasses).size() && |
| 9 | | Assuming the condition is true | |
|
215 | DWARF5FormClasses[Form] == FC) |
| 10 | | The left operand of '==' is a garbage value due to array index out of bounds |
|
216 | return true; |
217 | |
218 | switch (Form) { |
219 | case DW_FORM_GNU_ref_alt: |
220 | return (FC == FC_Reference); |
221 | case DW_FORM_GNU_addr_index: |
222 | return (FC == FC_Address); |
223 | case DW_FORM_GNU_str_index: |
224 | case DW_FORM_GNU_strp_alt: |
225 | return (FC == FC_String); |
226 | case DW_FORM_LLVM_addrx_offset: |
227 | return (FC == FC_Address); |
228 | default: |
229 | break; |
230 | } |
231 | |
232 | if (FC == FC_SectionOffset) { |
233 | if (Form == DW_FORM_strp || Form == DW_FORM_line_strp) |
234 | return true; |
235 | |
236 | |
237 | if (Form == DW_FORM_data4 || Form == DW_FORM_data8) |
238 | return !U || U->getVersion() <= 3; |
239 | } |
240 | |
241 | return false; |
242 | } |
243 | |
244 | bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, |
245 | uint64_t *OffsetPtr, dwarf::FormParams FP, |
246 | const DWARFContext *Ctx, |
247 | const DWARFUnit *CU) { |
248 | if (!Ctx && CU) |
249 | Ctx = &CU->getContext(); |
250 | C = Ctx; |
251 | U = CU; |
252 | Format = FP.Format; |
253 | bool Indirect = false; |
254 | bool IsBlock = false; |
255 | Value.data = nullptr; |
256 | |
257 | |
258 | Error Err = Error::success(); |
259 | do { |
260 | Indirect = false; |
261 | switch (Form) { |
262 | case DW_FORM_addr: |
263 | case DW_FORM_ref_addr: { |
264 | uint16_t Size = |
265 | (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize(); |
266 | Value.uval = |
267 | Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex, &Err); |
268 | break; |
269 | } |
270 | case DW_FORM_exprloc: |
271 | case DW_FORM_block: |
272 | Value.uval = Data.getULEB128(OffsetPtr, &Err); |
273 | IsBlock = true; |
274 | break; |
275 | case DW_FORM_block1: |
276 | Value.uval = Data.getU8(OffsetPtr, &Err); |
277 | IsBlock = true; |
278 | break; |
279 | case DW_FORM_block2: |
280 | Value.uval = Data.getU16(OffsetPtr, &Err); |
281 | IsBlock = true; |
282 | break; |
283 | case DW_FORM_block4: |
284 | Value.uval = Data.getU32(OffsetPtr, &Err); |
285 | IsBlock = true; |
286 | break; |
287 | case DW_FORM_data1: |
288 | case DW_FORM_ref1: |
289 | case DW_FORM_flag: |
290 | case DW_FORM_strx1: |
291 | case DW_FORM_addrx1: |
292 | Value.uval = Data.getU8(OffsetPtr, &Err); |
293 | break; |
294 | case DW_FORM_data2: |
295 | case DW_FORM_ref2: |
296 | case DW_FORM_strx2: |
297 | case DW_FORM_addrx2: |
298 | Value.uval = Data.getU16(OffsetPtr, &Err); |
299 | break; |
300 | case DW_FORM_strx3: |
301 | Value.uval = Data.getU24(OffsetPtr, &Err); |
302 | break; |
303 | case DW_FORM_data4: |
304 | case DW_FORM_ref4: |
305 | case DW_FORM_ref_sup4: |
306 | case DW_FORM_strx4: |
307 | case DW_FORM_addrx4: |
308 | Value.uval = Data.getRelocatedValue(4, OffsetPtr, nullptr, &Err); |
309 | break; |
310 | case DW_FORM_data8: |
311 | case DW_FORM_ref8: |
312 | case DW_FORM_ref_sup8: |
313 | Value.uval = Data.getRelocatedValue(8, OffsetPtr, nullptr, &Err); |
314 | break; |
315 | case DW_FORM_data16: |
316 | |
317 | Value.uval = 16; |
318 | IsBlock = true; |
319 | break; |
320 | case DW_FORM_sdata: |
321 | Value.sval = Data.getSLEB128(OffsetPtr, &Err); |
322 | break; |
323 | case DW_FORM_udata: |
324 | case DW_FORM_ref_udata: |
325 | case DW_FORM_rnglistx: |
326 | case DW_FORM_loclistx: |
327 | case DW_FORM_GNU_addr_index: |
328 | case DW_FORM_GNU_str_index: |
329 | case DW_FORM_addrx: |
330 | case DW_FORM_strx: |
331 | Value.uval = Data.getULEB128(OffsetPtr, &Err); |
332 | break; |
333 | case DW_FORM_LLVM_addrx_offset: |
334 | Value.uval = Data.getULEB128(OffsetPtr, &Err) << 32; |
335 | Value.uval = Data.getU32(OffsetPtr, &Err); |
336 | break; |
337 | case DW_FORM_string: |
338 | Value.cstr = Data.getCStr(OffsetPtr, &Err); |
339 | break; |
340 | case DW_FORM_indirect: |
341 | Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr, &Err)); |
342 | Indirect = true; |
343 | break; |
344 | case DW_FORM_strp: |
345 | case DW_FORM_sec_offset: |
346 | case DW_FORM_GNU_ref_alt: |
347 | case DW_FORM_GNU_strp_alt: |
348 | case DW_FORM_line_strp: |
349 | case DW_FORM_strp_sup: { |
350 | Value.uval = Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), |
351 | OffsetPtr, nullptr, &Err); |
352 | break; |
353 | } |
354 | case DW_FORM_flag_present: |
355 | Value.uval = 1; |
356 | break; |
357 | case DW_FORM_ref_sig8: |
358 | Value.uval = Data.getU64(OffsetPtr, &Err); |
359 | break; |
360 | case DW_FORM_implicit_const: |
361 | |
362 | break; |
363 | default: |
364 | |
365 | |
366 | llvm_unreachable("unsupported form"); |
367 | } |
368 | } while (Indirect && !Err); |
369 | |
370 | if (IsBlock) |
371 | Value.data = Data.getBytes(OffsetPtr, Value.uval, &Err).bytes_begin(); |
372 | |
373 | return !errorToBool(std::move(Err)); |
374 | } |
375 | |
376 | void DWARFFormValue::dumpAddress(raw_ostream &OS, uint8_t AddressSize, |
377 | uint64_t Address) { |
378 | uint8_t HexDigits = AddressSize * 2; |
379 | OS << format("0x%*.*" PRIx64, HexDigits, HexDigits, Address); |
380 | } |
381 | |
382 | void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS, |
383 | DIDumpOptions DumpOpts, |
384 | object::SectionedAddress SA) const { |
385 | dumpAddress(OS, U->getAddressByteSize(), SA.Address); |
386 | dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts, |
387 | SA.SectionIndex); |
388 | } |
389 | |
390 | void DWARFFormValue::dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS, |
391 | DIDumpOptions DumpOpts, |
392 | uint64_t SectionIndex) { |
393 | if (!DumpOpts.Verbose || SectionIndex == -1ULL) |
394 | return; |
395 | ArrayRef<SectionName> SectionNames = Obj.getSectionNames(); |
396 | const auto &SecRef = SectionNames[SectionIndex]; |
397 | |
398 | OS << " \"" << SecRef.Name << '\"'; |
399 | |
400 | |
401 | if (!SecRef.IsNameUnique) |
402 | OS << format(" [%" PRIu64 "]", SectionIndex); |
403 | } |
404 | |
405 | void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { |
406 | uint64_t UValue = Value.uval; |
407 | bool CURelativeOffset = false; |
408 | raw_ostream &AddrOS = DumpOpts.ShowAddresses |
| 1 | Assuming field 'ShowAddresses' is false | |
|
| |
409 | ? WithColor(OS, HighlightColor::Address).get() |
410 | : nulls(); |
411 | int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format); |
412 | switch (Form) { |
| 3 | | Control jumps to 'case DW_FORM_GNU_strp_alt:' at line 544 | |
|
413 | case DW_FORM_addr: |
414 | dumpSectionedAddress(AddrOS, DumpOpts, {Value.uval, Value.SectionIndex}); |
415 | break; |
416 | case DW_FORM_addrx: |
417 | case DW_FORM_addrx1: |
418 | case DW_FORM_addrx2: |
419 | case DW_FORM_addrx3: |
420 | case DW_FORM_addrx4: |
421 | case DW_FORM_GNU_addr_index: { |
422 | if (U == nullptr) { |
423 | OS << "<invalid dwarf unit>"; |
424 | break; |
425 | } |
426 | Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(UValue); |
427 | if (!A || DumpOpts.Verbose) |
428 | AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue); |
429 | if (A) |
430 | dumpSectionedAddress(AddrOS, DumpOpts, *A); |
431 | else |
432 | OS << "<unresolved>"; |
433 | break; |
434 | } |
435 | case DW_FORM_LLVM_addrx_offset: { |
436 | if (U == nullptr) { |
437 | OS << "<invalid dwarf unit>"; |
438 | break; |
439 | } |
440 | uint32_t Index = UValue >> 32; |
441 | uint32_t Offset = UValue & 0xffffffff; |
442 | Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(Index); |
443 | if (!A || DumpOpts.Verbose) |
444 | AddrOS << format("indexed (%8.8x) + 0x%x address = ", Index, Offset); |
445 | if (A) { |
446 | A->Address += Offset; |
447 | dumpSectionedAddress(AddrOS, DumpOpts, *A); |
448 | } else |
449 | OS << "<unresolved>"; |
450 | break; |
451 | } |
452 | case DW_FORM_flag_present: |
453 | OS << "true"; |
454 | break; |
455 | case DW_FORM_flag: |
456 | case DW_FORM_data1: |
457 | OS << format("0x%02x", (uint8_t)UValue); |
458 | break; |
459 | case DW_FORM_data2: |
460 | OS << format("0x%04x", (uint16_t)UValue); |
461 | break; |
462 | case DW_FORM_data4: |
463 | OS << format("0x%08x", (uint32_t)UValue); |
464 | break; |
465 | case DW_FORM_ref_sig8: |
466 | AddrOS << format("0x%016" PRIx64, UValue); |
467 | break; |
468 | case DW_FORM_data8: |
469 | OS << format("0x%016" PRIx64, UValue); |
470 | break; |
471 | case DW_FORM_data16: |
472 | OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16); |
473 | break; |
474 | case DW_FORM_string: |
475 | OS << '"'; |
476 | OS.write_escaped(Value.cstr); |
477 | OS << '"'; |
478 | break; |
479 | case DW_FORM_exprloc: |
480 | case DW_FORM_block: |
481 | case DW_FORM_block1: |
482 | case DW_FORM_block2: |
483 | case DW_FORM_block4: |
484 | if (UValue > 0) { |
485 | switch (Form) { |
486 | case DW_FORM_exprloc: |
487 | case DW_FORM_block: |
488 | AddrOS << format("<0x%" PRIx64 "> ", UValue); |
489 | break; |
490 | case DW_FORM_block1: |
491 | AddrOS << format("<0x%2.2x> ", (uint8_t)UValue); |
492 | break; |
493 | case DW_FORM_block2: |
494 | AddrOS << format("<0x%4.4x> ", (uint16_t)UValue); |
495 | break; |
496 | case DW_FORM_block4: |
497 | AddrOS << format("<0x%8.8x> ", (uint32_t)UValue); |
498 | break; |
499 | default: |
500 | break; |
501 | } |
502 | |
503 | const uint8_t *DataPtr = Value.data; |
504 | if (DataPtr) { |
505 | |
506 | const uint8_t *EndDataPtr = DataPtr + UValue; |
507 | while (DataPtr < EndDataPtr) { |
508 | AddrOS << format("%2.2x ", *DataPtr); |
509 | ++DataPtr; |
510 | } |
511 | } else |
512 | OS << "NULL"; |
513 | } |
514 | break; |
515 | |
516 | case DW_FORM_sdata: |
517 | case DW_FORM_implicit_const: |
518 | OS << Value.sval; |
519 | break; |
520 | case DW_FORM_udata: |
521 | OS << Value.uval; |
522 | break; |
523 | case DW_FORM_strp: |
524 | if (DumpOpts.Verbose) |
525 | OS << format(" .debug_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, UValue); |
526 | dumpString(OS); |
527 | break; |
528 | case DW_FORM_line_strp: |
529 | if (DumpOpts.Verbose) |
530 | OS << format(" .debug_line_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, |
531 | UValue); |
532 | dumpString(OS); |
533 | break; |
534 | case DW_FORM_strx: |
535 | case DW_FORM_strx1: |
536 | case DW_FORM_strx2: |
537 | case DW_FORM_strx3: |
538 | case DW_FORM_strx4: |
539 | case DW_FORM_GNU_str_index: |
540 | if (DumpOpts.Verbose) |
541 | OS << format("indexed (%8.8x) string = ", (uint32_t)UValue); |
542 | dumpString(OS); |
543 | break; |
544 | case DW_FORM_GNU_strp_alt: |
545 | if (DumpOpts.Verbose) |
| 4 | | Assuming field 'Verbose' is false | |
|
| |
546 | OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue); |
547 | dumpString(OS); |
| 6 | | Calling 'DWARFFormValue::dumpString' | |
|
548 | break; |
549 | case DW_FORM_ref_addr: |
550 | AddrOS << format("0x%016" PRIx64, UValue); |
551 | break; |
552 | case DW_FORM_ref1: |
553 | CURelativeOffset = true; |
554 | if (DumpOpts.Verbose) |
555 | AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue); |
556 | break; |
557 | case DW_FORM_ref2: |
558 | CURelativeOffset = true; |
559 | if (DumpOpts.Verbose) |
560 | AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue); |
561 | break; |
562 | case DW_FORM_ref4: |
563 | CURelativeOffset = true; |
564 | if (DumpOpts.Verbose) |
565 | AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue); |
566 | break; |
567 | case DW_FORM_ref8: |
568 | CURelativeOffset = true; |
569 | if (DumpOpts.Verbose) |
570 | AddrOS << format("cu + 0x%8.8" PRIx64, UValue); |
571 | break; |
572 | case DW_FORM_ref_udata: |
573 | CURelativeOffset = true; |
574 | if (DumpOpts.Verbose) |
575 | AddrOS << format("cu + 0x%" PRIx64, UValue); |
576 | break; |
577 | case DW_FORM_GNU_ref_alt: |
578 | AddrOS << format("<alt 0x%" PRIx64 ">", UValue); |
579 | break; |
580 | |
581 | |
582 | |
583 | case DW_FORM_indirect: |
584 | OS << "DW_FORM_indirect"; |
585 | break; |
586 | |
587 | case DW_FORM_rnglistx: |
588 | OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue); |
589 | break; |
590 | |
591 | case DW_FORM_loclistx: |
592 | OS << format("indexed (0x%x) loclist = ", (uint32_t)UValue); |
593 | break; |
594 | |
595 | case DW_FORM_sec_offset: |
596 | AddrOS << format("0x%0*" PRIx64, OffsetDumpWidth, UValue); |
597 | break; |
598 | |
599 | default: |
600 | OS << format("DW_FORM(0x%4.4x)", Form); |
601 | break; |
602 | } |
603 | |
604 | if (CURelativeOffset) { |
605 | if (DumpOpts.Verbose) |
606 | OS << " => {"; |
607 | if (DumpOpts.ShowAddresses) |
608 | WithColor(OS, HighlightColor::Address).get() |
609 | << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0)); |
610 | if (DumpOpts.Verbose) |
611 | OS << "}"; |
612 | } |
613 | } |
614 | |
615 | void DWARFFormValue::dumpString(raw_ostream &OS) const { |
616 | Optional<const char *> DbgStr = getAsCString(); |
| 7 | | Calling 'DWARFFormValue::getAsCString' | |
|
617 | if (DbgStr.hasValue()) { |
618 | auto COS = WithColor(OS, HighlightColor::String); |
619 | COS.get() << '"'; |
620 | COS.get().write_escaped(DbgStr.getValue()); |
621 | COS.get() << '"'; |
622 | } |
623 | } |
624 | |
625 | Optional<const char *> DWARFFormValue::getAsCString() const { |
626 | if (!isFormClass(FC_String)) |
| 8 | | Calling 'DWARFFormValue::isFormClass' | |
|
627 | return None; |
628 | if (Form == DW_FORM_string) |
629 | return Value.cstr; |
630 | |
631 | if (Form == DW_FORM_GNU_strp_alt || C == nullptr) |
632 | return None; |
633 | uint64_t Offset = Value.uval; |
634 | if (Form == DW_FORM_line_strp) { |
635 | |
636 | if (const char *Str = C->getLineStringExtractor().getCStr(&Offset)) |
637 | return Str; |
638 | return None; |
639 | } |
640 | if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx || |
641 | Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 || |
642 | Form == DW_FORM_strx4) { |
643 | if (!U) |
644 | return None; |
645 | Optional<uint64_t> StrOffset = U->getStringOffsetSectionItem(Offset); |
646 | if (!StrOffset) |
647 | return None; |
648 | Offset = *StrOffset; |
649 | } |
650 | |
651 | |
652 | if (U) { |
653 | if (const char *Str = U->getStringExtractor().getCStr(&Offset)) |
654 | return Str; |
655 | return None; |
656 | } |
657 | if (const char *Str = C->getStringExtractor().getCStr(&Offset)) |
658 | return Str; |
659 | return None; |
660 | } |
661 | |
662 | Optional<uint64_t> DWARFFormValue::getAsAddress() const { |
663 | if (auto SA = getAsSectionedAddress()) |
664 | return SA->Address; |
665 | return None; |
666 | } |
667 | |
668 | Optional<object::SectionedAddress> |
669 | DWARFFormValue::getAsSectionedAddress() const { |
670 | if (!isFormClass(FC_Address)) |
671 | return None; |
672 | bool AddrOffset = Form == dwarf::DW_FORM_LLVM_addrx_offset; |
673 | if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx || AddrOffset) { |
674 | |
675 | uint32_t Index = AddrOffset ? (Value.uval >> 32) : Value.uval; |
676 | if (!U) |
677 | return None; |
678 | Optional<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index); |
679 | if (!SA) |
680 | return None; |
681 | if (AddrOffset) |
682 | SA->Address += (Value.uval & 0xffffffff); |
683 | return SA; |
684 | } |
685 | return {{Value.uval, Value.SectionIndex}}; |
686 | } |
687 | |
688 | Optional<uint64_t> DWARFFormValue::getAsReference() const { |
689 | if (auto R = getAsRelativeReference()) |
690 | return R->Unit ? R->Unit->getOffset() + R->Offset : R->Offset; |
691 | return None; |
692 | } |
693 | |
694 | Optional<DWARFFormValue::UnitOffset> DWARFFormValue::getAsRelativeReference() const { |
695 | if (!isFormClass(FC_Reference)) |
696 | return None; |
697 | switch (Form) { |
698 | case DW_FORM_ref1: |
699 | case DW_FORM_ref2: |
700 | case DW_FORM_ref4: |
701 | case DW_FORM_ref8: |
702 | case DW_FORM_ref_udata: |
703 | if (!U) |
704 | return None; |
705 | return UnitOffset{const_cast<DWARFUnit*>(U), Value.uval}; |
706 | case DW_FORM_ref_addr: |
707 | case DW_FORM_ref_sig8: |
708 | case DW_FORM_GNU_ref_alt: |
709 | return UnitOffset{nullptr, Value.uval}; |
710 | default: |
711 | return None; |
712 | } |
713 | } |
714 | |
715 | Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const { |
716 | if (!isFormClass(FC_SectionOffset)) |
717 | return None; |
718 | return Value.uval; |
719 | } |
720 | |
721 | Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const { |
722 | if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || |
723 | Form == DW_FORM_sdata) |
724 | return None; |
725 | return Value.uval; |
726 | } |
727 | |
728 | Optional<int64_t> DWARFFormValue::getAsSignedConstant() const { |
729 | if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || |
730 | (Form == DW_FORM_udata && |
731 | uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval)) |
732 | return None; |
733 | switch (Form) { |
734 | case DW_FORM_data4: |
735 | return int32_t(Value.uval); |
736 | case DW_FORM_data2: |
737 | return int16_t(Value.uval); |
738 | case DW_FORM_data1: |
739 | return int8_t(Value.uval); |
740 | case DW_FORM_sdata: |
741 | case DW_FORM_data8: |
742 | default: |
743 | return Value.sval; |
744 | } |
745 | } |
746 | |
747 | Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const { |
748 | if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) && |
749 | Form != DW_FORM_data16) |
750 | return None; |
751 | return makeArrayRef(Value.data, Value.uval); |
752 | } |
753 | |
754 | Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const { |
755 | if (!isFormClass(FC_String) && Form == DW_FORM_string) |
756 | return None; |
757 | return Value.uval; |
758 | } |
759 | |
760 | Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const { |
761 | if (!isFormClass(FC_Reference)) |
762 | return None; |
763 | return Value.uval; |
764 | } |