File: | tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp |
Warning: | line 231, column 7 Value stored to 'ref_addr_size' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
18 | class DWARFUnit; |
19 | |
20 | using namespace lldb_private; |
21 | |
22 | static 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 | |
60 | static 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 |
99 | static 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 | |
136 | DWARFFormValue::FixedFormSizes |
137 | DWARFFormValue::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 | |
155 | DWARFFormValue::DWARFFormValue() : m_cu(NULL__null), m_form(0), m_value() {} |
156 | |
157 | DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form) |
158 | : m_cu(cu), m_form(form), m_value() {} |
159 | |
160 | void DWARFFormValue::Clear() { |
161 | m_cu = nullptr; |
162 | m_form = 0; |
163 | memset(&m_value, 0, sizeof(m_value)); |
164 | } |
165 | |
166 | bool 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 | |
291 | bool 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 | |
296 | bool 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 | |
405 | void 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 | |
528 | const 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 | |
552 | dw_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 | |
570 | uint64_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 | |
590 | uint64_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 | |
608 | const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } |
609 | |
610 | bool 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 | |
622 | bool 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 | |
635 | int 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 | |
729 | bool 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 | } |