File: | tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp |
Warning: | line 363, column 5 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) |
158 | : m_cu(cu), m_form(0), m_value() {} |
159 | |
160 | DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form) |
161 | : m_cu(cu), m_form(form), m_value() {} |
162 | |
163 | void DWARFFormValue::Clear() { |
164 | m_cu = nullptr; |
165 | m_form = 0; |
166 | memset(&m_value, 0, sizeof(m_value)); |
167 | } |
168 | |
169 | bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, |
170 | lldb::offset_t *offset_ptr) { |
171 | if (m_form == DW_FORM_implicit_const) |
172 | return true; |
173 | |
174 | bool indirect = false; |
175 | bool is_block = false; |
176 | m_value.data = NULL__null; |
177 | uint8_t ref_addr_size; |
178 | // Read the value for the form into value and follow and DW_FORM_indirect |
179 | // instances we run into |
180 | do { |
181 | indirect = false; |
182 | switch (m_form) { |
183 | case DW_FORM_addr: |
184 | assert(m_cu)((m_cu) ? static_cast<void> (0) : __assert_fail ("m_cu" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 184, __PRETTY_FUNCTION__)); |
185 | m_value.value.uval = data.GetMaxU64( |
186 | offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); |
187 | break; |
188 | case DW_FORM_block2: |
189 | m_value.value.uval = data.GetU16(offset_ptr); |
190 | is_block = true; |
191 | break; |
192 | case DW_FORM_block4: |
193 | m_value.value.uval = data.GetU32(offset_ptr); |
194 | is_block = true; |
195 | break; |
196 | case DW_FORM_data2: |
197 | m_value.value.uval = data.GetU16(offset_ptr); |
198 | break; |
199 | case DW_FORM_data4: |
200 | m_value.value.uval = data.GetU32(offset_ptr); |
201 | break; |
202 | case DW_FORM_data8: |
203 | m_value.value.uval = data.GetU64(offset_ptr); |
204 | break; |
205 | case DW_FORM_data16: |
206 | m_value.value.uval = 16; |
207 | is_block = true; |
208 | break; |
209 | case DW_FORM_string: |
210 | m_value.value.cstr = data.GetCStr(offset_ptr); |
211 | break; |
212 | case DW_FORM_exprloc: |
213 | case DW_FORM_block: |
214 | m_value.value.uval = data.GetULEB128(offset_ptr); |
215 | is_block = true; |
216 | break; |
217 | case DW_FORM_block1: |
218 | m_value.value.uval = data.GetU8(offset_ptr); |
219 | is_block = true; |
220 | break; |
221 | case DW_FORM_data1: |
222 | m_value.value.uval = data.GetU8(offset_ptr); |
223 | break; |
224 | case DW_FORM_flag: |
225 | m_value.value.uval = data.GetU8(offset_ptr); |
226 | break; |
227 | case DW_FORM_sdata: |
228 | m_value.value.sval = data.GetSLEB128(offset_ptr); |
229 | break; |
230 | case DW_FORM_strp: |
231 | case DW_FORM_line_strp: |
232 | assert(m_cu)((m_cu) ? static_cast<void> (0) : __assert_fail ("m_cu" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 232, __PRETTY_FUNCTION__)); |
233 | m_value.value.uval = |
234 | data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); |
235 | break; |
236 | case DW_FORM_strx: |
237 | m_value.value.uval = data.GetULEB128(offset_ptr); |
238 | break; |
239 | case DW_FORM_strx1: |
240 | m_value.value.uval = data.GetU8(offset_ptr); |
241 | break; |
242 | case DW_FORM_strx2: |
243 | m_value.value.uval = data.GetU16(offset_ptr); |
244 | break; |
245 | case DW_FORM_strx3: |
246 | m_value.value.uval = data.GetMaxU64(offset_ptr, 3); |
247 | break; |
248 | case DW_FORM_strx4: |
249 | m_value.value.uval = data.GetU32(offset_ptr); |
250 | break; |
251 | // case DW_FORM_APPLE_db_str: |
252 | case DW_FORM_udata: |
253 | m_value.value.uval = data.GetULEB128(offset_ptr); |
254 | break; |
255 | case DW_FORM_ref_addr: |
256 | assert(m_cu)((m_cu) ? static_cast<void> (0) : __assert_fail ("m_cu" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 256, __PRETTY_FUNCTION__)); |
257 | ref_addr_size = 4; |
258 | if (m_cu->GetVersion() <= 2) |
259 | ref_addr_size = m_cu->GetAddressByteSize(); |
260 | else |
261 | ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; |
262 | m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); |
263 | break; |
264 | case DW_FORM_ref1: |
265 | m_value.value.uval = data.GetU8(offset_ptr); |
266 | break; |
267 | case DW_FORM_ref2: |
268 | m_value.value.uval = data.GetU16(offset_ptr); |
269 | break; |
270 | case DW_FORM_ref4: |
271 | m_value.value.uval = data.GetU32(offset_ptr); |
272 | break; |
273 | case DW_FORM_ref8: |
274 | m_value.value.uval = data.GetU64(offset_ptr); |
275 | break; |
276 | case DW_FORM_ref_udata: |
277 | m_value.value.uval = data.GetULEB128(offset_ptr); |
278 | break; |
279 | case DW_FORM_indirect: |
280 | m_form = data.GetULEB128(offset_ptr); |
281 | indirect = true; |
282 | break; |
283 | |
284 | case DW_FORM_sec_offset: |
285 | assert(m_cu)((m_cu) ? static_cast<void> (0) : __assert_fail ("m_cu" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 285, __PRETTY_FUNCTION__)); |
286 | m_value.value.uval = |
287 | data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); |
288 | break; |
289 | case DW_FORM_flag_present: |
290 | m_value.value.uval = 1; |
291 | break; |
292 | case DW_FORM_ref_sig8: |
293 | m_value.value.uval = data.GetU64(offset_ptr); |
294 | break; |
295 | case DW_FORM_GNU_str_index: |
296 | m_value.value.uval = data.GetULEB128(offset_ptr); |
297 | break; |
298 | case DW_FORM_GNU_addr_index: |
299 | m_value.value.uval = data.GetULEB128(offset_ptr); |
300 | break; |
301 | default: |
302 | return false; |
303 | break; |
304 | } |
305 | } while (indirect); |
306 | |
307 | if (is_block) { |
308 | m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); |
309 | if (m_value.data != NULL__null) { |
310 | *offset_ptr += m_value.value.uval; |
311 | } |
312 | } |
313 | |
314 | return true; |
315 | } |
316 | |
317 | bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data, |
318 | lldb::offset_t *offset_ptr) const { |
319 | return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); |
320 | } |
321 | |
322 | bool DWARFFormValue::SkipValue(dw_form_t form, |
323 | const DWARFDataExtractor &debug_info_data, |
324 | lldb::offset_t *offset_ptr, |
325 | const DWARFUnit *cu) { |
326 | uint8_t ref_addr_size; |
327 | switch (form) { |
328 | // Blocks if inlined data that have a length field and the data bytes inlined |
329 | // in the .debug_info |
330 | case DW_FORM_exprloc: |
331 | case DW_FORM_block: { |
332 | dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); |
333 | *offset_ptr += size; |
334 | } |
335 | return true; |
336 | case DW_FORM_block1: { |
337 | dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); |
338 | *offset_ptr += size; |
339 | } |
340 | return true; |
341 | case DW_FORM_block2: { |
342 | dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); |
343 | *offset_ptr += size; |
344 | } |
345 | return true; |
346 | case DW_FORM_block4: { |
347 | dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); |
348 | *offset_ptr += size; |
349 | } |
350 | return true; |
351 | |
352 | // Inlined NULL terminated C-strings |
353 | case DW_FORM_string: |
354 | debug_info_data.GetCStr(offset_ptr); |
355 | return true; |
356 | |
357 | // Compile unit address sized values |
358 | case DW_FORM_addr: |
359 | *offset_ptr += DWARFUnit::GetAddressByteSize(cu); |
360 | return true; |
361 | |
362 | case DW_FORM_ref_addr: |
363 | ref_addr_size = 4; |
Value stored to 'ref_addr_size' is never read | |
364 | assert(cu)((cu) ? static_cast<void> (0) : __assert_fail ("cu", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 364, __PRETTY_FUNCTION__)); // CU must be valid for DW_FORM_ref_addr objects or we will get |
365 | // this wrong |
366 | if (cu->GetVersion() <= 2) |
367 | ref_addr_size = cu->GetAddressByteSize(); |
368 | else |
369 | ref_addr_size = cu->IsDWARF64() ? 8 : 4; |
370 | *offset_ptr += ref_addr_size; |
371 | return true; |
372 | |
373 | // 0 bytes values (implied from DW_FORM) |
374 | case DW_FORM_flag_present: |
375 | case DW_FORM_implicit_const: |
376 | return true; |
377 | |
378 | // 1 byte values |
379 | case DW_FORM_data1: |
380 | case DW_FORM_flag: |
381 | case DW_FORM_ref1: |
382 | case DW_FORM_strx1: |
383 | *offset_ptr += 1; |
384 | return true; |
385 | |
386 | // 2 byte values |
387 | case DW_FORM_data2: |
388 | case DW_FORM_ref2: |
389 | case DW_FORM_strx2: |
390 | *offset_ptr += 2; |
391 | return true; |
392 | |
393 | // 3 byte values |
394 | case DW_FORM_strx3: |
395 | *offset_ptr += 3; |
396 | return true; |
397 | |
398 | // 32 bit for DWARF 32, 64 for DWARF 64 |
399 | case DW_FORM_sec_offset: |
400 | case DW_FORM_strp: |
401 | assert(cu)((cu) ? static_cast<void> (0) : __assert_fail ("cu", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 401, __PRETTY_FUNCTION__)); |
402 | *offset_ptr += (cu->IsDWARF64() ? 8 : 4); |
403 | return true; |
404 | |
405 | // 4 byte values |
406 | case DW_FORM_data4: |
407 | case DW_FORM_ref4: |
408 | case DW_FORM_strx4: |
409 | *offset_ptr += 4; |
410 | return true; |
411 | |
412 | // 8 byte values |
413 | case DW_FORM_data8: |
414 | case DW_FORM_ref8: |
415 | case DW_FORM_ref_sig8: |
416 | *offset_ptr += 8; |
417 | return true; |
418 | |
419 | // signed or unsigned LEB 128 values |
420 | case DW_FORM_sdata: |
421 | case DW_FORM_udata: |
422 | case DW_FORM_ref_udata: |
423 | case DW_FORM_GNU_addr_index: |
424 | case DW_FORM_GNU_str_index: |
425 | case DW_FORM_strx: |
426 | debug_info_data.Skip_LEB128(offset_ptr); |
427 | return true; |
428 | |
429 | case DW_FORM_indirect: { |
430 | dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); |
431 | return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr, |
432 | cu); |
433 | } |
434 | |
435 | default: |
436 | break; |
437 | } |
438 | return false; |
439 | } |
440 | |
441 | void DWARFFormValue::Dump(Stream &s) const { |
442 | uint64_t uvalue = Unsigned(); |
443 | bool cu_relative_offset = false; |
444 | |
445 | switch (m_form) { |
446 | case DW_FORM_addr: |
447 | s.Address(uvalue, sizeof(uint64_t)); |
448 | break; |
449 | case DW_FORM_flag: |
450 | case DW_FORM_data1: |
451 | s.PutHex8(uvalue); |
452 | break; |
453 | case DW_FORM_data2: |
454 | s.PutHex16(uvalue); |
455 | break; |
456 | case DW_FORM_sec_offset: |
457 | case DW_FORM_data4: |
458 | s.PutHex32(uvalue); |
459 | break; |
460 | case DW_FORM_ref_sig8: |
461 | case DW_FORM_data8: |
462 | s.PutHex64(uvalue); |
463 | break; |
464 | case DW_FORM_string: |
465 | s.QuotedCString(AsCString()); |
466 | break; |
467 | case DW_FORM_exprloc: |
468 | case DW_FORM_block: |
469 | case DW_FORM_block1: |
470 | case DW_FORM_block2: |
471 | case DW_FORM_block4: |
472 | if (uvalue > 0) { |
473 | switch (m_form) { |
474 | case DW_FORM_exprloc: |
475 | case DW_FORM_block: |
476 | s.Printf("<0x%" PRIx64"l" "x" "> ", uvalue); |
477 | break; |
478 | case DW_FORM_block1: |
479 | s.Printf("<0x%2.2x> ", (uint8_t)uvalue); |
480 | break; |
481 | case DW_FORM_block2: |
482 | s.Printf("<0x%4.4x> ", (uint16_t)uvalue); |
483 | break; |
484 | case DW_FORM_block4: |
485 | s.Printf("<0x%8.8x> ", (uint32_t)uvalue); |
486 | break; |
487 | default: |
488 | break; |
489 | } |
490 | |
491 | const uint8_t *data_ptr = m_value.data; |
492 | if (data_ptr) { |
493 | const uint8_t *end_data_ptr = |
494 | data_ptr + uvalue; // uvalue contains size of block |
495 | while (data_ptr < end_data_ptr) { |
496 | s.Printf("%2.2x ", *data_ptr); |
497 | ++data_ptr; |
498 | } |
499 | } else |
500 | s.PutCString("NULL"); |
501 | } |
502 | break; |
503 | |
504 | case DW_FORM_sdata: |
505 | s.PutSLEB128(uvalue); |
506 | break; |
507 | case DW_FORM_udata: |
508 | s.PutULEB128(uvalue); |
509 | break; |
510 | case DW_FORM_strp: { |
511 | const char *dbg_str = AsCString(); |
512 | if (dbg_str) { |
513 | s.QuotedCString(dbg_str); |
514 | } else { |
515 | s.PutHex32(uvalue); |
516 | } |
517 | } break; |
518 | |
519 | case DW_FORM_ref_addr: { |
520 | assert(m_cu)((m_cu) ? static_cast<void> (0) : __assert_fail ("m_cu" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 520, __PRETTY_FUNCTION__)); // CU must be valid for DW_FORM_ref_addr objects or we will |
521 | // get this wrong |
522 | if (m_cu->GetVersion() <= 2) |
523 | s.Address(uvalue, sizeof(uint64_t) * 2); |
524 | else |
525 | s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't |
526 | // support DWARF64 yet |
527 | break; |
528 | } |
529 | case DW_FORM_ref1: |
530 | cu_relative_offset = true; |
531 | break; |
532 | case DW_FORM_ref2: |
533 | cu_relative_offset = true; |
534 | break; |
535 | case DW_FORM_ref4: |
536 | cu_relative_offset = true; |
537 | break; |
538 | case DW_FORM_ref8: |
539 | cu_relative_offset = true; |
540 | break; |
541 | case DW_FORM_ref_udata: |
542 | cu_relative_offset = true; |
543 | break; |
544 | |
545 | // All DW_FORM_indirect attributes should be resolved prior to calling this |
546 | // function |
547 | case DW_FORM_indirect: |
548 | s.PutCString("DW_FORM_indirect"); |
549 | break; |
550 | case DW_FORM_flag_present: |
551 | break; |
552 | default: |
553 | s.Printf("DW_FORM(0x%4.4x)", m_form); |
554 | break; |
555 | } |
556 | |
557 | if (cu_relative_offset) { |
558 | assert(m_cu)((m_cu) ? static_cast<void> (0) : __assert_fail ("m_cu" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 558, __PRETTY_FUNCTION__)); // CU must be valid for DW_FORM_ref forms that are compile |
559 | // unit relative or we will get this wrong |
560 | s.Printf("{0x%8.8" PRIx64"l" "x" "}", uvalue + m_cu->GetOffset()); |
561 | } |
562 | } |
563 | |
564 | const char *DWARFFormValue::AsCString() const { |
565 | SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); |
566 | |
567 | if (m_form == DW_FORM_string) { |
568 | return m_value.value.cstr; |
569 | } else if (m_form == DW_FORM_strp) { |
570 | if (!symbol_file) |
571 | return nullptr; |
572 | |
573 | return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); |
574 | } else if (m_form == DW_FORM_GNU_str_index) { |
575 | if (!symbol_file) |
576 | return nullptr; |
577 | |
578 | uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4; |
579 | lldb::offset_t offset = m_value.value.uval * index_size; |
580 | dw_offset_t str_offset = |
581 | symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, |
582 | index_size); |
583 | return symbol_file->get_debug_str_data().PeekCStr(str_offset); |
584 | } |
585 | |
586 | if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 || |
587 | m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 || |
588 | m_form == DW_FORM_strx4) { |
589 | |
590 | // The same code as above. |
591 | if (!symbol_file) |
592 | return nullptr; |
593 | |
594 | lldb::offset_t baseOffset = 0; |
595 | const DWARFDataExtractor &strOffsets = |
596 | symbol_file->get_debug_str_offsets_data(); |
597 | uint64_t length = strOffsets.GetU32(&baseOffset); |
598 | if (length == 0xffffffff) |
599 | length = strOffsets.GetU64(&baseOffset); |
600 | |
601 | // Check version. |
602 | if (strOffsets.GetU16(&baseOffset) < 5) |
603 | return nullptr; |
604 | |
605 | // Skip padding. |
606 | baseOffset += 2; |
607 | |
608 | uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4; |
609 | lldb::offset_t offset = baseOffset + m_value.value.uval * indexSize; |
610 | dw_offset_t strOffset = |
611 | symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize); |
612 | return symbol_file->get_debug_str_data().PeekCStr(strOffset); |
613 | } |
614 | |
615 | if (m_form == DW_FORM_line_strp) |
616 | return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); |
617 | |
618 | return nullptr; |
619 | } |
620 | |
621 | dw_addr_t DWARFFormValue::Address() const { |
622 | SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); |
623 | |
624 | if (m_form == DW_FORM_addr) |
625 | return Unsigned(); |
626 | |
627 | assert(m_cu)((m_cu) ? static_cast<void> (0) : __assert_fail ("m_cu" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 627, __PRETTY_FUNCTION__)); |
628 | assert(m_form == DW_FORM_GNU_addr_index)((m_form == DW_FORM_GNU_addr_index) ? static_cast<void> (0) : __assert_fail ("m_form == DW_FORM_GNU_addr_index", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 628, __PRETTY_FUNCTION__)); |
629 | |
630 | if (!symbol_file) |
631 | return 0; |
632 | |
633 | uint32_t index_size = m_cu->GetAddressByteSize(); |
634 | dw_offset_t addr_base = m_cu->GetAddrBase(); |
635 | lldb::offset_t offset = addr_base + m_value.value.uval * index_size; |
636 | return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); |
637 | } |
638 | |
639 | uint64_t DWARFFormValue::Reference() const { |
640 | uint64_t die_offset = m_value.value.uval; |
641 | switch (m_form) { |
642 | case DW_FORM_ref1: |
643 | case DW_FORM_ref2: |
644 | case DW_FORM_ref4: |
645 | case DW_FORM_ref8: |
646 | case DW_FORM_ref_udata: |
647 | assert(m_cu)((m_cu) ? static_cast<void> (0) : __assert_fail ("m_cu" , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 647, __PRETTY_FUNCTION__)); // CU must be valid for DW_FORM_ref forms that are compile |
648 | // unit relative or we will get this wrong |
649 | die_offset += m_cu->GetOffset(); |
650 | break; |
651 | |
652 | default: |
653 | break; |
654 | } |
655 | |
656 | return die_offset; |
657 | } |
658 | |
659 | uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { |
660 | uint64_t die_offset = m_value.value.uval; |
661 | switch (m_form) { |
662 | case DW_FORM_ref1: |
663 | case DW_FORM_ref2: |
664 | case DW_FORM_ref4: |
665 | case DW_FORM_ref8: |
666 | case DW_FORM_ref_udata: |
667 | die_offset += base_offset; |
668 | break; |
669 | |
670 | default: |
671 | break; |
672 | } |
673 | |
674 | return die_offset; |
675 | } |
676 | |
677 | const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } |
678 | |
679 | bool DWARFFormValue::IsBlockForm(const dw_form_t form) { |
680 | switch (form) { |
681 | case DW_FORM_exprloc: |
682 | case DW_FORM_block: |
683 | case DW_FORM_block1: |
684 | case DW_FORM_block2: |
685 | case DW_FORM_block4: |
686 | return true; |
687 | } |
688 | return false; |
689 | } |
690 | |
691 | bool DWARFFormValue::IsDataForm(const dw_form_t form) { |
692 | switch (form) { |
693 | case DW_FORM_sdata: |
694 | case DW_FORM_udata: |
695 | case DW_FORM_data1: |
696 | case DW_FORM_data2: |
697 | case DW_FORM_data4: |
698 | case DW_FORM_data8: |
699 | return true; |
700 | } |
701 | return false; |
702 | } |
703 | |
704 | int DWARFFormValue::Compare(const DWARFFormValue &a_value, |
705 | const DWARFFormValue &b_value) { |
706 | dw_form_t a_form = a_value.Form(); |
707 | dw_form_t b_form = b_value.Form(); |
708 | if (a_form < b_form) |
709 | return -1; |
710 | if (a_form > b_form) |
711 | return 1; |
712 | switch (a_form) { |
713 | case DW_FORM_addr: |
714 | case DW_FORM_flag: |
715 | case DW_FORM_data1: |
716 | case DW_FORM_data2: |
717 | case DW_FORM_data4: |
718 | case DW_FORM_data8: |
719 | case DW_FORM_udata: |
720 | case DW_FORM_ref_addr: |
721 | case DW_FORM_sec_offset: |
722 | case DW_FORM_flag_present: |
723 | case DW_FORM_ref_sig8: |
724 | case DW_FORM_GNU_addr_index: { |
725 | uint64_t a = a_value.Unsigned(); |
726 | uint64_t b = b_value.Unsigned(); |
727 | if (a < b) |
728 | return -1; |
729 | if (a > b) |
730 | return 1; |
731 | return 0; |
732 | } |
733 | |
734 | case DW_FORM_sdata: { |
735 | int64_t a = a_value.Signed(); |
736 | int64_t b = b_value.Signed(); |
737 | if (a < b) |
738 | return -1; |
739 | if (a > b) |
740 | return 1; |
741 | return 0; |
742 | } |
743 | |
744 | case DW_FORM_string: |
745 | case DW_FORM_strp: |
746 | case DW_FORM_GNU_str_index: { |
747 | const char *a_string = a_value.AsCString(); |
748 | const char *b_string = b_value.AsCString(); |
749 | if (a_string == b_string) |
750 | return 0; |
751 | else if (a_string && b_string) |
752 | return strcmp(a_string, b_string); |
753 | else if (a_string == NULL__null) |
754 | return -1; // A string is NULL, and B is valid |
755 | else |
756 | return 1; // A string valid, and B is NULL |
757 | } |
758 | |
759 | case DW_FORM_block: |
760 | case DW_FORM_block1: |
761 | case DW_FORM_block2: |
762 | case DW_FORM_block4: |
763 | case DW_FORM_exprloc: { |
764 | uint64_t a_len = a_value.Unsigned(); |
765 | uint64_t b_len = b_value.Unsigned(); |
766 | if (a_len < b_len) |
767 | return -1; |
768 | if (a_len > b_len) |
769 | return 1; |
770 | // The block lengths are the same |
771 | return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); |
772 | } break; |
773 | |
774 | case DW_FORM_ref1: |
775 | case DW_FORM_ref2: |
776 | case DW_FORM_ref4: |
777 | case DW_FORM_ref8: |
778 | case DW_FORM_ref_udata: { |
779 | uint64_t a = a_value.Reference(); |
780 | uint64_t b = b_value.Reference(); |
781 | if (a < b) |
782 | return -1; |
783 | if (a > b) |
784 | return 1; |
785 | return 0; |
786 | } |
787 | |
788 | case DW_FORM_indirect: |
789 | llvm_unreachable(::llvm::llvm_unreachable_internal("This shouldn't happen after the form has been extracted..." , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 790) |
790 | "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-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 790); |
791 | |
792 | default: |
793 | llvm_unreachable("Unhandled DW_FORM")::llvm::llvm_unreachable_internal("Unhandled DW_FORM", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 793); |
794 | } |
795 | return -1; |
796 | } |
797 | |
798 | bool DWARFFormValue::FormIsSupported(dw_form_t form) { |
799 | switch (form) { |
800 | case DW_FORM_addr: |
801 | case DW_FORM_block2: |
802 | case DW_FORM_block4: |
803 | case DW_FORM_data2: |
804 | case DW_FORM_data4: |
805 | case DW_FORM_data8: |
806 | case DW_FORM_string: |
807 | case DW_FORM_block: |
808 | case DW_FORM_block1: |
809 | case DW_FORM_data1: |
810 | case DW_FORM_flag: |
811 | case DW_FORM_sdata: |
812 | case DW_FORM_strp: |
813 | case DW_FORM_strx: |
814 | case DW_FORM_strx1: |
815 | case DW_FORM_strx2: |
816 | case DW_FORM_strx3: |
817 | case DW_FORM_strx4: |
818 | case DW_FORM_udata: |
819 | case DW_FORM_ref_addr: |
820 | case DW_FORM_ref1: |
821 | case DW_FORM_ref2: |
822 | case DW_FORM_ref4: |
823 | case DW_FORM_ref8: |
824 | case DW_FORM_ref_udata: |
825 | case DW_FORM_indirect: |
826 | case DW_FORM_sec_offset: |
827 | case DW_FORM_exprloc: |
828 | case DW_FORM_flag_present: |
829 | case DW_FORM_ref_sig8: |
830 | case DW_FORM_GNU_str_index: |
831 | case DW_FORM_GNU_addr_index: |
832 | case DW_FORM_implicit_const: |
833 | return true; |
834 | default: |
835 | break; |
836 | } |
837 | return false; |
838 | } |