Bug Summary

File:tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
Warning:line 231, column 7
Value stored to 'ref_addr_size' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DWARFFormValue.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -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 -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lldb/source/Plugins/SymbolFile/DWARF -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn338205/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-7~svn338205/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/lib/gcc/x86_64-linux-gnu/8/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lldb/source/Plugins/SymbolFile/DWARF -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-07-29-043837-17923-1 -x c++ /build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp -faddrsig
1//===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <assert.h>
11
12#include "lldb/Core/dwarf.h"
13#include "lldb/Utility/Stream.h"
14
15#include "DWARFUnit.h"
16#include "DWARFFormValue.h"
17
18class DWARFUnit;
19
20using namespace lldb_private;
21
22static uint8_t g_form_sizes_addr4[] = {
23 0, // 0x00 unused
24 4, // 0x01 DW_FORM_addr
25 0, // 0x02 unused
26 0, // 0x03 DW_FORM_block2
27 0, // 0x04 DW_FORM_block4
28 2, // 0x05 DW_FORM_data2
29 4, // 0x06 DW_FORM_data4
30 8, // 0x07 DW_FORM_data8
31 0, // 0x08 DW_FORM_string
32 0, // 0x09 DW_FORM_block
33 0, // 0x0a DW_FORM_block1
34 1, // 0x0b DW_FORM_data1
35 1, // 0x0c DW_FORM_flag
36 0, // 0x0d DW_FORM_sdata
37 4, // 0x0e DW_FORM_strp
38 0, // 0x0f DW_FORM_udata
39 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
40 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
41 1, // 0x11 DW_FORM_ref1
42 2, // 0x12 DW_FORM_ref2
43 4, // 0x13 DW_FORM_ref4
44 8, // 0x14 DW_FORM_ref8
45 0, // 0x15 DW_FORM_ref_udata
46 0, // 0x16 DW_FORM_indirect
47 4, // 0x17 DW_FORM_sec_offset
48 0, // 0x18 DW_FORM_exprloc
49 0, // 0x19 DW_FORM_flag_present
50 0, // 0x1a
51 0, // 0x1b
52 0, // 0x1c
53 0, // 0x1d
54 0, // 0x1e
55 0, // 0x1f
56 8, // 0x20 DW_FORM_ref_sig8
57
58};
59
60static uint8_t g_form_sizes_addr8[] = {
61 0, // 0x00 unused
62 8, // 0x01 DW_FORM_addr
63 0, // 0x02 unused
64 0, // 0x03 DW_FORM_block2
65 0, // 0x04 DW_FORM_block4
66 2, // 0x05 DW_FORM_data2
67 4, // 0x06 DW_FORM_data4
68 8, // 0x07 DW_FORM_data8
69 0, // 0x08 DW_FORM_string
70 0, // 0x09 DW_FORM_block
71 0, // 0x0a DW_FORM_block1
72 1, // 0x0b DW_FORM_data1
73 1, // 0x0c DW_FORM_flag
74 0, // 0x0d DW_FORM_sdata
75 4, // 0x0e DW_FORM_strp
76 0, // 0x0f DW_FORM_udata
77 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
78 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
79 1, // 0x11 DW_FORM_ref1
80 2, // 0x12 DW_FORM_ref2
81 4, // 0x13 DW_FORM_ref4
82 8, // 0x14 DW_FORM_ref8
83 0, // 0x15 DW_FORM_ref_udata
84 0, // 0x16 DW_FORM_indirect
85 4, // 0x17 DW_FORM_sec_offset
86 0, // 0x18 DW_FORM_exprloc
87 0, // 0x19 DW_FORM_flag_present
88 0, // 0x1a
89 0, // 0x1b
90 0, // 0x1c
91 0, // 0x1d
92 0, // 0x1e
93 0, // 0x1f
94 8, // 0x20 DW_FORM_ref_sig8
95};
96
97// Difference with g_form_sizes_addr8:
98// DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4
99static uint8_t g_form_sizes_addr8_dwarf64[] = {
100 0, // 0x00 unused
101 8, // 0x01 DW_FORM_addr
102 0, // 0x02 unused
103 0, // 0x03 DW_FORM_block2
104 0, // 0x04 DW_FORM_block4
105 2, // 0x05 DW_FORM_data2
106 4, // 0x06 DW_FORM_data4
107 8, // 0x07 DW_FORM_data8
108 0, // 0x08 DW_FORM_string
109 0, // 0x09 DW_FORM_block
110 0, // 0x0a DW_FORM_block1
111 1, // 0x0b DW_FORM_data1
112 1, // 0x0c DW_FORM_flag
113 0, // 0x0d DW_FORM_sdata
114 8, // 0x0e DW_FORM_strp
115 0, // 0x0f DW_FORM_udata
116 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
117 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
118 1, // 0x11 DW_FORM_ref1
119 2, // 0x12 DW_FORM_ref2
120 4, // 0x13 DW_FORM_ref4
121 8, // 0x14 DW_FORM_ref8
122 0, // 0x15 DW_FORM_ref_udata
123 0, // 0x16 DW_FORM_indirect
124 8, // 0x17 DW_FORM_sec_offset
125 0, // 0x18 DW_FORM_exprloc
126 0, // 0x19 DW_FORM_flag_present
127 0, // 0x1a
128 0, // 0x1b
129 0, // 0x1c
130 0, // 0x1d
131 0, // 0x1e
132 0, // 0x1f
133 8, // 0x20 DW_FORM_ref_sig8
134};
135
136DWARFFormValue::FixedFormSizes
137DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,
138 bool is_dwarf64) {
139 if (!is_dwarf64) {
140 switch (addr_size) {
141 case 4:
142 return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
143 case 8:
144 return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
145 }
146 } else {
147 if (addr_size == 8)
148 return FixedFormSizes(g_form_sizes_addr8_dwarf64,
149 sizeof(g_form_sizes_addr8_dwarf64));
150 // is_dwarf64 && addr_size == 4 : no provider does this.
151 }
152 return FixedFormSizes();
153}
154
155DWARFFormValue::DWARFFormValue() : m_cu(NULL__null), m_form(0), m_value() {}
156
157DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form)
158 : m_cu(cu), m_form(form), m_value() {}
159
160void DWARFFormValue::Clear() {
161 m_cu = nullptr;
162 m_form = 0;
163 memset(&m_value, 0, sizeof(m_value));
164}
165
166bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
167 lldb::offset_t *offset_ptr) {
168 bool indirect = false;
169 bool is_block = false;
170 m_value.data = NULL__null;
171 uint8_t ref_addr_size;
172 // Read the value for the form into value and follow and DW_FORM_indirect
173 // instances we run into
174 do {
175 indirect = false;
176 switch (m_form) {
177 case DW_FORM_addr:
178 assert(m_cu)(static_cast <bool> (m_cu) ? void (0) : __assert_fail (
"m_cu", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 178, __extension__ __PRETTY_FUNCTION__))
;
179 m_value.value.uval = data.GetMaxU64(
180 offset_ptr, DWARFUnit::GetAddressByteSize(m_cu));
181 break;
182 case DW_FORM_block2:
183 m_value.value.uval = data.GetU16(offset_ptr);
184 is_block = true;
185 break;
186 case DW_FORM_block4:
187 m_value.value.uval = data.GetU32(offset_ptr);
188 is_block = true;
189 break;
190 case DW_FORM_data2:
191 m_value.value.uval = data.GetU16(offset_ptr);
192 break;
193 case DW_FORM_data4:
194 m_value.value.uval = data.GetU32(offset_ptr);
195 break;
196 case DW_FORM_data8:
197 m_value.value.uval = data.GetU64(offset_ptr);
198 break;
199 case DW_FORM_string:
200 m_value.value.cstr = data.GetCStr(offset_ptr);
201 break;
202 case DW_FORM_exprloc:
203 case DW_FORM_block:
204 m_value.value.uval = data.GetULEB128(offset_ptr);
205 is_block = true;
206 break;
207 case DW_FORM_block1:
208 m_value.value.uval = data.GetU8(offset_ptr);
209 is_block = true;
210 break;
211 case DW_FORM_data1:
212 m_value.value.uval = data.GetU8(offset_ptr);
213 break;
214 case DW_FORM_flag:
215 m_value.value.uval = data.GetU8(offset_ptr);
216 break;
217 case DW_FORM_sdata:
218 m_value.value.sval = data.GetSLEB128(offset_ptr);
219 break;
220 case DW_FORM_strp:
221 assert(m_cu)(static_cast <bool> (m_cu) ? void (0) : __assert_fail (
"m_cu", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 221, __extension__ __PRETTY_FUNCTION__))
;
222 m_value.value.uval =
223 data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
224 break;
225 // case DW_FORM_APPLE_db_str:
226 case DW_FORM_udata:
227 m_value.value.uval = data.GetULEB128(offset_ptr);
228 break;
229 case DW_FORM_ref_addr:
230 assert(m_cu)(static_cast <bool> (m_cu) ? void (0) : __assert_fail (
"m_cu", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 230, __extension__ __PRETTY_FUNCTION__))
;
231 ref_addr_size = 4;
Value stored to 'ref_addr_size' is never read
232 if (m_cu->GetVersion() <= 2)
233 ref_addr_size = m_cu->GetAddressByteSize();
234 else
235 ref_addr_size = m_cu->IsDWARF64() ? 8 : 4;
236 m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size);
237 break;
238 case DW_FORM_ref1:
239 m_value.value.uval = data.GetU8(offset_ptr);
240 break;
241 case DW_FORM_ref2:
242 m_value.value.uval = data.GetU16(offset_ptr);
243 break;
244 case DW_FORM_ref4:
245 m_value.value.uval = data.GetU32(offset_ptr);
246 break;
247 case DW_FORM_ref8:
248 m_value.value.uval = data.GetU64(offset_ptr);
249 break;
250 case DW_FORM_ref_udata:
251 m_value.value.uval = data.GetULEB128(offset_ptr);
252 break;
253 case DW_FORM_indirect:
254 m_form = data.GetULEB128(offset_ptr);
255 indirect = true;
256 break;
257
258 case DW_FORM_sec_offset:
259 assert(m_cu)(static_cast <bool> (m_cu) ? void (0) : __assert_fail (
"m_cu", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 259, __extension__ __PRETTY_FUNCTION__))
;
260 m_value.value.uval =
261 data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
262 break;
263 case DW_FORM_flag_present:
264 m_value.value.uval = 1;
265 break;
266 case DW_FORM_ref_sig8:
267 m_value.value.uval = data.GetU64(offset_ptr);
268 break;
269 case DW_FORM_GNU_str_index:
270 m_value.value.uval = data.GetULEB128(offset_ptr);
271 break;
272 case DW_FORM_GNU_addr_index:
273 m_value.value.uval = data.GetULEB128(offset_ptr);
274 break;
275 default:
276 return false;
277 break;
278 }
279 } while (indirect);
280
281 if (is_block) {
282 m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
283 if (m_value.data != NULL__null) {
284 *offset_ptr += m_value.value.uval;
285 }
286 }
287
288 return true;
289}
290
291bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data,
292 lldb::offset_t *offset_ptr) const {
293 return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu);
294}
295
296bool DWARFFormValue::SkipValue(dw_form_t form,
297 const DWARFDataExtractor &debug_info_data,
298 lldb::offset_t *offset_ptr,
299 const DWARFUnit *cu) {
300 uint8_t ref_addr_size;
301 switch (form) {
302 // Blocks if inlined data that have a length field and the data bytes inlined
303 // in the .debug_info
304 case DW_FORM_exprloc:
305 case DW_FORM_block: {
306 dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr);
307 *offset_ptr += size;
308 }
309 return true;
310 case DW_FORM_block1: {
311 dw_uleb128_t size = debug_info_data.GetU8(offset_ptr);
312 *offset_ptr += size;
313 }
314 return true;
315 case DW_FORM_block2: {
316 dw_uleb128_t size = debug_info_data.GetU16(offset_ptr);
317 *offset_ptr += size;
318 }
319 return true;
320 case DW_FORM_block4: {
321 dw_uleb128_t size = debug_info_data.GetU32(offset_ptr);
322 *offset_ptr += size;
323 }
324 return true;
325
326 // Inlined NULL terminated C-strings
327 case DW_FORM_string:
328 debug_info_data.GetCStr(offset_ptr);
329 return true;
330
331 // Compile unit address sized values
332 case DW_FORM_addr:
333 *offset_ptr += DWARFUnit::GetAddressByteSize(cu);
334 return true;
335
336 case DW_FORM_ref_addr:
337 ref_addr_size = 4;
338 assert(cu)(static_cast <bool> (cu) ? void (0) : __assert_fail ("cu"
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 338, __extension__ __PRETTY_FUNCTION__))
; // CU must be valid for DW_FORM_ref_addr objects or we will get
339 // this wrong
340 if (cu->GetVersion() <= 2)
341 ref_addr_size = cu->GetAddressByteSize();
342 else
343 ref_addr_size = cu->IsDWARF64() ? 8 : 4;
344 *offset_ptr += ref_addr_size;
345 return true;
346
347 // 0 bytes values (implied from DW_FORM)
348 case DW_FORM_flag_present:
349 return true;
350
351 // 1 byte values
352 case DW_FORM_data1:
353 case DW_FORM_flag:
354 case DW_FORM_ref1:
355 *offset_ptr += 1;
356 return true;
357
358 // 2 byte values
359 case DW_FORM_data2:
360 case DW_FORM_ref2:
361 *offset_ptr += 2;
362 return true;
363
364 // 32 bit for DWARF 32, 64 for DWARF 64
365 case DW_FORM_sec_offset:
366 case DW_FORM_strp:
367 assert(cu)(static_cast <bool> (cu) ? void (0) : __assert_fail ("cu"
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 367, __extension__ __PRETTY_FUNCTION__))
;
368 *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
369 return true;
370
371 // 4 byte values
372 case DW_FORM_data4:
373 case DW_FORM_ref4:
374 *offset_ptr += 4;
375 return true;
376
377 // 8 byte values
378 case DW_FORM_data8:
379 case DW_FORM_ref8:
380 case DW_FORM_ref_sig8:
381 *offset_ptr += 8;
382 return true;
383
384 // signed or unsigned LEB 128 values
385 case DW_FORM_sdata:
386 case DW_FORM_udata:
387 case DW_FORM_ref_udata:
388 case DW_FORM_GNU_addr_index:
389 case DW_FORM_GNU_str_index:
390 debug_info_data.Skip_LEB128(offset_ptr);
391 return true;
392
393 case DW_FORM_indirect: {
394 dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
395 return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr,
396 cu);
397 }
398
399 default:
400 break;
401 }
402 return false;
403}
404
405void DWARFFormValue::Dump(Stream &s) const {
406 uint64_t uvalue = Unsigned();
407 bool cu_relative_offset = false;
408
409 switch (m_form) {
410 case DW_FORM_addr:
411 s.Address(uvalue, sizeof(uint64_t));
412 break;
413 case DW_FORM_flag:
414 case DW_FORM_data1:
415 s.PutHex8(uvalue);
416 break;
417 case DW_FORM_data2:
418 s.PutHex16(uvalue);
419 break;
420 case DW_FORM_sec_offset:
421 case DW_FORM_data4:
422 s.PutHex32(uvalue);
423 break;
424 case DW_FORM_ref_sig8:
425 case DW_FORM_data8:
426 s.PutHex64(uvalue);
427 break;
428 case DW_FORM_string:
429 s.QuotedCString(AsCString());
430 break;
431 case DW_FORM_exprloc:
432 case DW_FORM_block:
433 case DW_FORM_block1:
434 case DW_FORM_block2:
435 case DW_FORM_block4:
436 if (uvalue > 0) {
437 switch (m_form) {
438 case DW_FORM_exprloc:
439 case DW_FORM_block:
440 s.Printf("<0x%" PRIx64"l" "x" "> ", uvalue);
441 break;
442 case DW_FORM_block1:
443 s.Printf("<0x%2.2x> ", (uint8_t)uvalue);
444 break;
445 case DW_FORM_block2:
446 s.Printf("<0x%4.4x> ", (uint16_t)uvalue);
447 break;
448 case DW_FORM_block4:
449 s.Printf("<0x%8.8x> ", (uint32_t)uvalue);
450 break;
451 default:
452 break;
453 }
454
455 const uint8_t *data_ptr = m_value.data;
456 if (data_ptr) {
457 const uint8_t *end_data_ptr =
458 data_ptr + uvalue; // uvalue contains size of block
459 while (data_ptr < end_data_ptr) {
460 s.Printf("%2.2x ", *data_ptr);
461 ++data_ptr;
462 }
463 } else
464 s.PutCString("NULL");
465 }
466 break;
467
468 case DW_FORM_sdata:
469 s.PutSLEB128(uvalue);
470 break;
471 case DW_FORM_udata:
472 s.PutULEB128(uvalue);
473 break;
474 case DW_FORM_strp: {
475 const char *dbg_str = AsCString();
476 if (dbg_str) {
477 s.QuotedCString(dbg_str);
478 } else {
479 s.PutHex32(uvalue);
480 }
481 } break;
482
483 case DW_FORM_ref_addr: {
484 assert(m_cu)(static_cast <bool> (m_cu) ? void (0) : __assert_fail (
"m_cu", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 484, __extension__ __PRETTY_FUNCTION__))
; // CU must be valid for DW_FORM_ref_addr objects or we will
485 // get this wrong
486 if (m_cu->GetVersion() <= 2)
487 s.Address(uvalue, sizeof(uint64_t) * 2);
488 else
489 s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't
490 // support DWARF64 yet
491 break;
492 }
493 case DW_FORM_ref1:
494 cu_relative_offset = true;
495 break;
496 case DW_FORM_ref2:
497 cu_relative_offset = true;
498 break;
499 case DW_FORM_ref4:
500 cu_relative_offset = true;
501 break;
502 case DW_FORM_ref8:
503 cu_relative_offset = true;
504 break;
505 case DW_FORM_ref_udata:
506 cu_relative_offset = true;
507 break;
508
509 // All DW_FORM_indirect attributes should be resolved prior to calling this
510 // function
511 case DW_FORM_indirect:
512 s.PutCString("DW_FORM_indirect");
513 break;
514 case DW_FORM_flag_present:
515 break;
516 default:
517 s.Printf("DW_FORM(0x%4.4x)", m_form);
518 break;
519 }
520
521 if (cu_relative_offset) {
522 assert(m_cu)(static_cast <bool> (m_cu) ? void (0) : __assert_fail (
"m_cu", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 522, __extension__ __PRETTY_FUNCTION__))
; // CU must be valid for DW_FORM_ref forms that are compile
523 // unit relative or we will get this wrong
524 s.Printf("{0x%8.8" PRIx64"l" "x" "}", uvalue + m_cu->GetOffset());
525 }
526}
527
528const char *DWARFFormValue::AsCString() const {
529 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
530
531 if (m_form == DW_FORM_string) {
532 return m_value.value.cstr;
533 } else if (m_form == DW_FORM_strp) {
534 if (!symbol_file)
535 return nullptr;
536
537 return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
538 } else if (m_form == DW_FORM_GNU_str_index) {
539 if (!symbol_file)
540 return nullptr;
541
542 uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
543 lldb::offset_t offset = m_value.value.uval * index_size;
544 dw_offset_t str_offset =
545 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
546 index_size);
547 return symbol_file->get_debug_str_data().PeekCStr(str_offset);
548 }
549 return nullptr;
550}
551
552dw_addr_t DWARFFormValue::Address() const {
553 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
554
555 if (m_form == DW_FORM_addr)
556 return Unsigned();
557
558 assert(m_cu)(static_cast <bool> (m_cu) ? void (0) : __assert_fail (
"m_cu", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 558, __extension__ __PRETTY_FUNCTION__))
;
559 assert(m_form == DW_FORM_GNU_addr_index)(static_cast <bool> (m_form == DW_FORM_GNU_addr_index) ?
void (0) : __assert_fail ("m_form == DW_FORM_GNU_addr_index"
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 559, __extension__ __PRETTY_FUNCTION__))
;
560
561 if (!symbol_file)
562 return 0;
563
564 uint32_t index_size = m_cu->GetAddressByteSize();
565 dw_offset_t addr_base = m_cu->GetAddrBase();
566 lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
567 return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
568}
569
570uint64_t DWARFFormValue::Reference() const {
571 uint64_t die_offset = m_value.value.uval;
572 switch (m_form) {
573 case DW_FORM_ref1:
574 case DW_FORM_ref2:
575 case DW_FORM_ref4:
576 case DW_FORM_ref8:
577 case DW_FORM_ref_udata:
578 assert(m_cu)(static_cast <bool> (m_cu) ? void (0) : __assert_fail (
"m_cu", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 578, __extension__ __PRETTY_FUNCTION__))
; // CU must be valid for DW_FORM_ref forms that are compile
579 // unit relative or we will get this wrong
580 die_offset += m_cu->GetOffset();
581 break;
582
583 default:
584 break;
585 }
586
587 return die_offset;
588}
589
590uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
591 uint64_t die_offset = m_value.value.uval;
592 switch (m_form) {
593 case DW_FORM_ref1:
594 case DW_FORM_ref2:
595 case DW_FORM_ref4:
596 case DW_FORM_ref8:
597 case DW_FORM_ref_udata:
598 die_offset += base_offset;
599 break;
600
601 default:
602 break;
603 }
604
605 return die_offset;
606}
607
608const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
609
610bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
611 switch (form) {
612 case DW_FORM_exprloc:
613 case DW_FORM_block:
614 case DW_FORM_block1:
615 case DW_FORM_block2:
616 case DW_FORM_block4:
617 return true;
618 }
619 return false;
620}
621
622bool DWARFFormValue::IsDataForm(const dw_form_t form) {
623 switch (form) {
624 case DW_FORM_sdata:
625 case DW_FORM_udata:
626 case DW_FORM_data1:
627 case DW_FORM_data2:
628 case DW_FORM_data4:
629 case DW_FORM_data8:
630 return true;
631 }
632 return false;
633}
634
635int DWARFFormValue::Compare(const DWARFFormValue &a_value,
636 const DWARFFormValue &b_value) {
637 dw_form_t a_form = a_value.Form();
638 dw_form_t b_form = b_value.Form();
639 if (a_form < b_form)
640 return -1;
641 if (a_form > b_form)
642 return 1;
643 switch (a_form) {
644 case DW_FORM_addr:
645 case DW_FORM_flag:
646 case DW_FORM_data1:
647 case DW_FORM_data2:
648 case DW_FORM_data4:
649 case DW_FORM_data8:
650 case DW_FORM_udata:
651 case DW_FORM_ref_addr:
652 case DW_FORM_sec_offset:
653 case DW_FORM_flag_present:
654 case DW_FORM_ref_sig8:
655 case DW_FORM_GNU_addr_index: {
656 uint64_t a = a_value.Unsigned();
657 uint64_t b = b_value.Unsigned();
658 if (a < b)
659 return -1;
660 if (a > b)
661 return 1;
662 return 0;
663 }
664
665 case DW_FORM_sdata: {
666 int64_t a = a_value.Signed();
667 int64_t b = b_value.Signed();
668 if (a < b)
669 return -1;
670 if (a > b)
671 return 1;
672 return 0;
673 }
674
675 case DW_FORM_string:
676 case DW_FORM_strp:
677 case DW_FORM_GNU_str_index: {
678 const char *a_string = a_value.AsCString();
679 const char *b_string = b_value.AsCString();
680 if (a_string == b_string)
681 return 0;
682 else if (a_string && b_string)
683 return strcmp(a_string, b_string);
684 else if (a_string == NULL__null)
685 return -1; // A string is NULL, and B is valid
686 else
687 return 1; // A string valid, and B is NULL
688 }
689
690 case DW_FORM_block:
691 case DW_FORM_block1:
692 case DW_FORM_block2:
693 case DW_FORM_block4:
694 case DW_FORM_exprloc: {
695 uint64_t a_len = a_value.Unsigned();
696 uint64_t b_len = b_value.Unsigned();
697 if (a_len < b_len)
698 return -1;
699 if (a_len > b_len)
700 return 1;
701 // The block lengths are the same
702 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
703 } break;
704
705 case DW_FORM_ref1:
706 case DW_FORM_ref2:
707 case DW_FORM_ref4:
708 case DW_FORM_ref8:
709 case DW_FORM_ref_udata: {
710 uint64_t a = a_value.Reference();
711 uint64_t b = b_value.Reference();
712 if (a < b)
713 return -1;
714 if (a > b)
715 return 1;
716 return 0;
717 }
718
719 case DW_FORM_indirect:
720 llvm_unreachable(::llvm::llvm_unreachable_internal("This shouldn't happen after the form has been extracted..."
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 721)
721 "This shouldn't happen after the form has been extracted...")::llvm::llvm_unreachable_internal("This shouldn't happen after the form has been extracted..."
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 721)
;
722
723 default:
724 llvm_unreachable("Unhandled DW_FORM")::llvm::llvm_unreachable_internal("Unhandled DW_FORM", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp"
, 724)
;
725 }
726 return -1;
727}
728
729bool DWARFFormValue::FormIsSupported(dw_form_t form) {
730 switch (form) {
731 case DW_FORM_addr:
732 case DW_FORM_block2:
733 case DW_FORM_block4:
734 case DW_FORM_data2:
735 case DW_FORM_data4:
736 case DW_FORM_data8:
737 case DW_FORM_string:
738 case DW_FORM_block:
739 case DW_FORM_block1:
740 case DW_FORM_data1:
741 case DW_FORM_flag:
742 case DW_FORM_sdata:
743 case DW_FORM_strp:
744 case DW_FORM_udata:
745 case DW_FORM_ref_addr:
746 case DW_FORM_ref1:
747 case DW_FORM_ref2:
748 case DW_FORM_ref4:
749 case DW_FORM_ref8:
750 case DW_FORM_ref_udata:
751 case DW_FORM_indirect:
752 case DW_FORM_sec_offset:
753 case DW_FORM_exprloc:
754 case DW_FORM_flag_present:
755 case DW_FORM_ref_sig8:
756 case DW_FORM_GNU_str_index:
757 case DW_FORM_GNU_addr_index:
758 return true;
759 default:
760 break;
761 }
762 return false;
763}