File: | build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp |
Warning: | line 249, column 5 Value stored to 'ref_addr_size' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- DWARFFormValue.cpp ------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include <cassert> |
10 | |
11 | #include "lldb/Core/Module.h" |
12 | #include "lldb/Core/dwarf.h" |
13 | #include "lldb/Symbol/ObjectFile.h" |
14 | #include "lldb/Utility/Stream.h" |
15 | |
16 | #include "DWARFDebugInfo.h" |
17 | #include "DWARFFormValue.h" |
18 | #include "DWARFUnit.h" |
19 | |
20 | class DWARFUnit; |
21 | |
22 | using namespace lldb_private; |
23 | using namespace lldb_private::dwarf; |
24 | |
25 | void DWARFFormValue::Clear() { |
26 | m_unit = nullptr; |
27 | m_form = 0; |
28 | m_value = ValueTypeTag(); |
29 | } |
30 | |
31 | bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, |
32 | lldb::offset_t *offset_ptr) { |
33 | if (m_form == DW_FORM_implicit_const) |
34 | return true; |
35 | |
36 | bool indirect = false; |
37 | bool is_block = false; |
38 | m_value.data = nullptr; |
39 | uint8_t ref_addr_size; |
40 | // Read the value for the form into value and follow and DW_FORM_indirect |
41 | // instances we run into |
42 | do { |
43 | indirect = false; |
44 | switch (m_form) { |
45 | case DW_FORM_addr: |
46 | assert(m_unit)(static_cast <bool> (m_unit) ? void (0) : __assert_fail ("m_unit", "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 46, __extension__ __PRETTY_FUNCTION__)); |
47 | m_value.value.uval = |
48 | data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_unit)); |
49 | break; |
50 | case DW_FORM_block1: |
51 | m_value.value.uval = data.GetU8(offset_ptr); |
52 | is_block = true; |
53 | break; |
54 | case DW_FORM_block2: |
55 | m_value.value.uval = data.GetU16(offset_ptr); |
56 | is_block = true; |
57 | break; |
58 | case DW_FORM_block4: |
59 | m_value.value.uval = data.GetU32(offset_ptr); |
60 | is_block = true; |
61 | break; |
62 | case DW_FORM_data16: |
63 | m_value.value.uval = 16; |
64 | is_block = true; |
65 | break; |
66 | case DW_FORM_exprloc: |
67 | case DW_FORM_block: |
68 | m_value.value.uval = data.GetULEB128(offset_ptr); |
69 | is_block = true; |
70 | break; |
71 | case DW_FORM_string: |
72 | m_value.value.cstr = data.GetCStr(offset_ptr); |
73 | break; |
74 | case DW_FORM_sdata: |
75 | m_value.value.sval = data.GetSLEB128(offset_ptr); |
76 | break; |
77 | case DW_FORM_strp: |
78 | case DW_FORM_line_strp: |
79 | case DW_FORM_sec_offset: |
80 | m_value.value.uval = data.GetMaxU64(offset_ptr, 4); |
81 | break; |
82 | case DW_FORM_addrx1: |
83 | case DW_FORM_strx1: |
84 | case DW_FORM_ref1: |
85 | case DW_FORM_data1: |
86 | case DW_FORM_flag: |
87 | m_value.value.uval = data.GetU8(offset_ptr); |
88 | break; |
89 | case DW_FORM_addrx2: |
90 | case DW_FORM_strx2: |
91 | case DW_FORM_ref2: |
92 | case DW_FORM_data2: |
93 | m_value.value.uval = data.GetU16(offset_ptr); |
94 | break; |
95 | case DW_FORM_addrx3: |
96 | case DW_FORM_strx3: |
97 | m_value.value.uval = data.GetMaxU64(offset_ptr, 3); |
98 | break; |
99 | case DW_FORM_addrx4: |
100 | case DW_FORM_strx4: |
101 | case DW_FORM_ref4: |
102 | case DW_FORM_data4: |
103 | m_value.value.uval = data.GetU32(offset_ptr); |
104 | break; |
105 | case DW_FORM_data8: |
106 | case DW_FORM_ref8: |
107 | case DW_FORM_ref_sig8: |
108 | m_value.value.uval = data.GetU64(offset_ptr); |
109 | break; |
110 | case DW_FORM_addrx: |
111 | case DW_FORM_loclistx: |
112 | case DW_FORM_rnglistx: |
113 | case DW_FORM_strx: |
114 | case DW_FORM_udata: |
115 | case DW_FORM_ref_udata: |
116 | case DW_FORM_GNU_str_index: |
117 | case DW_FORM_GNU_addr_index: |
118 | m_value.value.uval = data.GetULEB128(offset_ptr); |
119 | break; |
120 | case DW_FORM_ref_addr: |
121 | assert(m_unit)(static_cast <bool> (m_unit) ? void (0) : __assert_fail ("m_unit", "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 121, __extension__ __PRETTY_FUNCTION__)); |
122 | if (m_unit->GetVersion() <= 2) |
123 | ref_addr_size = m_unit->GetAddressByteSize(); |
124 | else |
125 | ref_addr_size = 4; |
126 | m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); |
127 | break; |
128 | case DW_FORM_indirect: |
129 | m_form = data.GetULEB128(offset_ptr); |
130 | indirect = true; |
131 | break; |
132 | case DW_FORM_flag_present: |
133 | m_value.value.uval = 1; |
134 | break; |
135 | default: |
136 | return false; |
137 | } |
138 | } while (indirect); |
139 | |
140 | if (is_block) { |
141 | m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); |
142 | if (m_value.data != nullptr) { |
143 | *offset_ptr += m_value.value.uval; |
144 | } |
145 | } |
146 | |
147 | return true; |
148 | } |
149 | |
150 | struct FormSize { |
151 | uint8_t valid:1, size:7; |
152 | }; |
153 | static FormSize g_form_sizes[] = { |
154 | {0, 0}, // 0x00 unused |
155 | {0, 0}, // 0x01 DW_FORM_addr |
156 | {0, 0}, // 0x02 unused |
157 | {0, 0}, // 0x03 DW_FORM_block2 |
158 | {0, 0}, // 0x04 DW_FORM_block4 |
159 | {1, 2}, // 0x05 DW_FORM_data2 |
160 | {1, 4}, // 0x06 DW_FORM_data4 |
161 | {1, 8}, // 0x07 DW_FORM_data8 |
162 | {0, 0}, // 0x08 DW_FORM_string |
163 | {0, 0}, // 0x09 DW_FORM_block |
164 | {0, 0}, // 0x0a DW_FORM_block1 |
165 | {1, 1}, // 0x0b DW_FORM_data1 |
166 | {1, 1}, // 0x0c DW_FORM_flag |
167 | {0, 0}, // 0x0d DW_FORM_sdata |
168 | {1, 4}, // 0x0e DW_FORM_strp |
169 | {0, 0}, // 0x0f DW_FORM_udata |
170 | {0, 0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes |
171 | // for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later |
172 | {1, 1}, // 0x11 DW_FORM_ref1 |
173 | {1, 2}, // 0x12 DW_FORM_ref2 |
174 | {1, 4}, // 0x13 DW_FORM_ref4 |
175 | {1, 8}, // 0x14 DW_FORM_ref8 |
176 | {0, 0}, // 0x15 DW_FORM_ref_udata |
177 | {0, 0}, // 0x16 DW_FORM_indirect |
178 | {1, 4}, // 0x17 DW_FORM_sec_offset |
179 | {0, 0}, // 0x18 DW_FORM_exprloc |
180 | {1, 0}, // 0x19 DW_FORM_flag_present |
181 | {0, 0}, // 0x1a DW_FORM_strx (ULEB128) |
182 | {0, 0}, // 0x1b DW_FORM_addrx (ULEB128) |
183 | {1, 4}, // 0x1c DW_FORM_ref_sup4 |
184 | {0, 0}, // 0x1d DW_FORM_strp_sup (4 bytes for DWARF32, 8 bytes for DWARF64) |
185 | {1, 16}, // 0x1e DW_FORM_data16 |
186 | {1, 4}, // 0x1f DW_FORM_line_strp |
187 | {1, 8}, // 0x20 DW_FORM_ref_sig8 |
188 | }; |
189 | |
190 | llvm::Optional<uint8_t> |
191 | DWARFFormValue::GetFixedSize(dw_form_t form, const DWARFUnit *u) { |
192 | if (form <= DW_FORM_ref_sig8 && g_form_sizes[form].valid) |
193 | return g_form_sizes[form].size; |
194 | if (form == DW_FORM_addr && u) |
195 | return u->GetAddressByteSize(); |
196 | return llvm::None; |
197 | } |
198 | |
199 | llvm::Optional<uint8_t> DWARFFormValue::GetFixedSize() const { |
200 | return GetFixedSize(m_form, m_unit); |
201 | } |
202 | |
203 | bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data, |
204 | lldb::offset_t *offset_ptr) const { |
205 | return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_unit); |
206 | } |
207 | |
208 | bool DWARFFormValue::SkipValue(dw_form_t form, |
209 | const DWARFDataExtractor &debug_info_data, |
210 | lldb::offset_t *offset_ptr, |
211 | const DWARFUnit *unit) { |
212 | uint8_t ref_addr_size; |
213 | switch (form) { |
214 | // Blocks if inlined data that have a length field and the data bytes inlined |
215 | // in the .debug_info |
216 | case DW_FORM_exprloc: |
217 | case DW_FORM_block: { |
218 | dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); |
219 | *offset_ptr += size; |
220 | } |
221 | return true; |
222 | case DW_FORM_block1: { |
223 | dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); |
224 | *offset_ptr += size; |
225 | } |
226 | return true; |
227 | case DW_FORM_block2: { |
228 | dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); |
229 | *offset_ptr += size; |
230 | } |
231 | return true; |
232 | case DW_FORM_block4: { |
233 | dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); |
234 | *offset_ptr += size; |
235 | } |
236 | return true; |
237 | |
238 | // Inlined NULL terminated C-strings |
239 | case DW_FORM_string: |
240 | debug_info_data.GetCStr(offset_ptr); |
241 | return true; |
242 | |
243 | // Compile unit address sized values |
244 | case DW_FORM_addr: |
245 | *offset_ptr += DWARFUnit::GetAddressByteSize(unit); |
246 | return true; |
247 | |
248 | case DW_FORM_ref_addr: |
249 | ref_addr_size = 4; |
Value stored to 'ref_addr_size' is never read | |
250 | assert(unit)(static_cast <bool> (unit) ? void (0) : __assert_fail ( "unit", "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 250, __extension__ __PRETTY_FUNCTION__)); // Unit must be valid for DW_FORM_ref_addr objects or we will |
251 | // get this wrong |
252 | if (unit->GetVersion() <= 2) |
253 | ref_addr_size = unit->GetAddressByteSize(); |
254 | else |
255 | ref_addr_size = 4; |
256 | *offset_ptr += ref_addr_size; |
257 | return true; |
258 | |
259 | // 0 bytes values (implied from DW_FORM) |
260 | case DW_FORM_flag_present: |
261 | case DW_FORM_implicit_const: |
262 | return true; |
263 | |
264 | // 1 byte values |
265 | case DW_FORM_addrx1: |
266 | case DW_FORM_data1: |
267 | case DW_FORM_flag: |
268 | case DW_FORM_ref1: |
269 | case DW_FORM_strx1: |
270 | *offset_ptr += 1; |
271 | return true; |
272 | |
273 | // 2 byte values |
274 | case DW_FORM_addrx2: |
275 | case DW_FORM_data2: |
276 | case DW_FORM_ref2: |
277 | case DW_FORM_strx2: |
278 | *offset_ptr += 2; |
279 | return true; |
280 | |
281 | // 3 byte values |
282 | case DW_FORM_addrx3: |
283 | case DW_FORM_strx3: |
284 | *offset_ptr += 3; |
285 | return true; |
286 | |
287 | // 32 bit for DWARF 32, 64 for DWARF 64 |
288 | case DW_FORM_sec_offset: |
289 | case DW_FORM_strp: |
290 | case DW_FORM_line_strp: |
291 | *offset_ptr += 4; |
292 | return true; |
293 | |
294 | // 4 byte values |
295 | case DW_FORM_addrx4: |
296 | case DW_FORM_data4: |
297 | case DW_FORM_ref4: |
298 | case DW_FORM_strx4: |
299 | *offset_ptr += 4; |
300 | return true; |
301 | |
302 | // 8 byte values |
303 | case DW_FORM_data8: |
304 | case DW_FORM_ref8: |
305 | case DW_FORM_ref_sig8: |
306 | *offset_ptr += 8; |
307 | return true; |
308 | |
309 | // signed or unsigned LEB 128 values |
310 | case DW_FORM_addrx: |
311 | case DW_FORM_loclistx: |
312 | case DW_FORM_rnglistx: |
313 | case DW_FORM_sdata: |
314 | case DW_FORM_udata: |
315 | case DW_FORM_ref_udata: |
316 | case DW_FORM_GNU_addr_index: |
317 | case DW_FORM_GNU_str_index: |
318 | case DW_FORM_strx: |
319 | debug_info_data.Skip_LEB128(offset_ptr); |
320 | return true; |
321 | |
322 | case DW_FORM_indirect: { |
323 | dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); |
324 | return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr, |
325 | unit); |
326 | } |
327 | |
328 | default: |
329 | break; |
330 | } |
331 | return false; |
332 | } |
333 | |
334 | void DWARFFormValue::Dump(Stream &s) const { |
335 | uint64_t uvalue = Unsigned(); |
336 | bool unit_relative_offset = false; |
337 | |
338 | switch (m_form) { |
339 | case DW_FORM_addr: |
340 | DumpAddress(s.AsRawOstream(), uvalue, sizeof(uint64_t)); |
341 | break; |
342 | case DW_FORM_flag: |
343 | case DW_FORM_data1: |
344 | s.PutHex8(uvalue); |
345 | break; |
346 | case DW_FORM_data2: |
347 | s.PutHex16(uvalue); |
348 | break; |
349 | case DW_FORM_sec_offset: |
350 | case DW_FORM_data4: |
351 | s.PutHex32(uvalue); |
352 | break; |
353 | case DW_FORM_ref_sig8: |
354 | case DW_FORM_data8: |
355 | s.PutHex64(uvalue); |
356 | break; |
357 | case DW_FORM_string: |
358 | s.QuotedCString(AsCString()); |
359 | break; |
360 | case DW_FORM_exprloc: |
361 | case DW_FORM_block: |
362 | case DW_FORM_block1: |
363 | case DW_FORM_block2: |
364 | case DW_FORM_block4: |
365 | if (uvalue > 0) { |
366 | switch (m_form) { |
367 | case DW_FORM_exprloc: |
368 | case DW_FORM_block: |
369 | s.Printf("<0x%" PRIx64"l" "x" "> ", uvalue); |
370 | break; |
371 | case DW_FORM_block1: |
372 | s.Printf("<0x%2.2x> ", (uint8_t)uvalue); |
373 | break; |
374 | case DW_FORM_block2: |
375 | s.Printf("<0x%4.4x> ", (uint16_t)uvalue); |
376 | break; |
377 | case DW_FORM_block4: |
378 | s.Printf("<0x%8.8x> ", (uint32_t)uvalue); |
379 | break; |
380 | default: |
381 | break; |
382 | } |
383 | |
384 | const uint8_t *data_ptr = m_value.data; |
385 | if (data_ptr) { |
386 | const uint8_t *end_data_ptr = |
387 | data_ptr + uvalue; // uvalue contains size of block |
388 | while (data_ptr < end_data_ptr) { |
389 | s.Printf("%2.2x ", *data_ptr); |
390 | ++data_ptr; |
391 | } |
392 | } else |
393 | s.PutCString("NULL"); |
394 | } |
395 | break; |
396 | |
397 | case DW_FORM_sdata: |
398 | s.PutSLEB128(uvalue); |
399 | break; |
400 | case DW_FORM_udata: |
401 | s.PutULEB128(uvalue); |
402 | break; |
403 | case DW_FORM_strp: |
404 | case DW_FORM_line_strp: { |
405 | const char *dbg_str = AsCString(); |
406 | if (dbg_str) { |
407 | s.QuotedCString(dbg_str); |
408 | } else { |
409 | s.PutHex32(uvalue); |
410 | } |
411 | } break; |
412 | |
413 | case DW_FORM_ref_addr: { |
414 | assert(m_unit)(static_cast <bool> (m_unit) ? void (0) : __assert_fail ("m_unit", "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 414, __extension__ __PRETTY_FUNCTION__)); // Unit must be valid for DW_FORM_ref_addr objects or we |
415 | // will get this wrong |
416 | if (m_unit->GetVersion() <= 2) |
417 | DumpAddress(s.AsRawOstream(), uvalue, sizeof(uint64_t) * 2); |
418 | else |
419 | DumpAddress(s.AsRawOstream(), uvalue, |
420 | 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't |
421 | // support DWARF64 yet |
422 | break; |
423 | } |
424 | case DW_FORM_ref1: |
425 | unit_relative_offset = true; |
426 | break; |
427 | case DW_FORM_ref2: |
428 | unit_relative_offset = true; |
429 | break; |
430 | case DW_FORM_ref4: |
431 | unit_relative_offset = true; |
432 | break; |
433 | case DW_FORM_ref8: |
434 | unit_relative_offset = true; |
435 | break; |
436 | case DW_FORM_ref_udata: |
437 | unit_relative_offset = true; |
438 | break; |
439 | |
440 | // All DW_FORM_indirect attributes should be resolved prior to calling this |
441 | // function |
442 | case DW_FORM_indirect: |
443 | s.PutCString("DW_FORM_indirect"); |
444 | break; |
445 | case DW_FORM_flag_present: |
446 | break; |
447 | default: |
448 | s.Printf("DW_FORM(0x%4.4x)", m_form); |
449 | break; |
450 | } |
451 | |
452 | if (unit_relative_offset) { |
453 | assert(m_unit)(static_cast <bool> (m_unit) ? void (0) : __assert_fail ("m_unit", "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 453, __extension__ __PRETTY_FUNCTION__)); // Unit must be valid for DW_FORM_ref forms that are compile |
454 | // unit relative or we will get this wrong |
455 | s.Printf("{0x%8.8" PRIx64"l" "x" "}", uvalue + m_unit->GetOffset()); |
456 | } |
457 | } |
458 | |
459 | const char *DWARFFormValue::AsCString() const { |
460 | DWARFContext &context = m_unit->GetSymbolFileDWARF().GetDWARFContext(); |
461 | |
462 | if (m_form == DW_FORM_string) |
463 | return m_value.value.cstr; |
464 | if (m_form == DW_FORM_strp) |
465 | return context.getOrLoadStrData().PeekCStr(m_value.value.uval); |
466 | |
467 | if (m_form == DW_FORM_GNU_str_index || m_form == DW_FORM_strx || |
468 | m_form == DW_FORM_strx1 || m_form == DW_FORM_strx2 || |
469 | m_form == DW_FORM_strx3 || m_form == DW_FORM_strx4) { |
470 | |
471 | llvm::Optional<uint64_t> offset = |
472 | m_unit->GetStringOffsetSectionItem(m_value.value.uval); |
473 | if (!offset) |
474 | return nullptr; |
475 | return context.getOrLoadStrData().PeekCStr(*offset); |
476 | } |
477 | |
478 | if (m_form == DW_FORM_line_strp) |
479 | return context.getOrLoadLineStrData().PeekCStr(m_value.value.uval); |
480 | |
481 | return nullptr; |
482 | } |
483 | |
484 | dw_addr_t DWARFFormValue::Address() const { |
485 | SymbolFileDWARF &symbol_file = m_unit->GetSymbolFileDWARF(); |
486 | |
487 | if (m_form == DW_FORM_addr) |
488 | return Unsigned(); |
489 | |
490 | assert(m_unit)(static_cast <bool> (m_unit) ? void (0) : __assert_fail ("m_unit", "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 490, __extension__ __PRETTY_FUNCTION__)); |
491 | assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx ||(static_cast <bool> (m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4 ) ? void (0) : __assert_fail ("m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4" , "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp", 493 , __extension__ __PRETTY_FUNCTION__)) |
492 | m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 ||(static_cast <bool> (m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4 ) ? void (0) : __assert_fail ("m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4" , "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp", 493 , __extension__ __PRETTY_FUNCTION__)) |
493 | m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4)(static_cast <bool> (m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4 ) ? void (0) : __assert_fail ("m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4" , "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp", 493 , __extension__ __PRETTY_FUNCTION__)); |
494 | |
495 | uint32_t index_size = m_unit->GetAddressByteSize(); |
496 | dw_offset_t addr_base = m_unit->GetAddrBase(); |
497 | lldb::offset_t offset = addr_base + m_value.value.uval * index_size; |
498 | return symbol_file.GetDWARFContext().getOrLoadAddrData().GetMaxU64( |
499 | &offset, index_size); |
500 | } |
501 | |
502 | DWARFDIE DWARFFormValue::Reference() const { |
503 | uint64_t value = m_value.value.uval; |
504 | switch (m_form) { |
505 | case DW_FORM_ref1: |
506 | case DW_FORM_ref2: |
507 | case DW_FORM_ref4: |
508 | case DW_FORM_ref8: |
509 | case DW_FORM_ref_udata: |
510 | assert(m_unit)(static_cast <bool> (m_unit) ? void (0) : __assert_fail ("m_unit", "lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp" , 510, __extension__ __PRETTY_FUNCTION__)); // Unit must be valid for DW_FORM_ref forms that are compile |
511 | // unit relative or we will get this wrong |
512 | value += m_unit->GetOffset(); |
513 | if (!m_unit->ContainsDIEOffset(value)) { |
514 | m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( |
515 | "DW_FORM_ref* DIE reference 0x%" PRIx64"l" "x" " is outside of its CU", |
516 | value); |
517 | return {}; |
518 | } |
519 | return const_cast<DWARFUnit *>(m_unit)->GetDIE(value); |
520 | |
521 | case DW_FORM_ref_addr: { |
522 | DWARFUnit *ref_cu = |
523 | m_unit->GetSymbolFileDWARF().DebugInfo().GetUnitContainingDIEOffset( |
524 | DIERef::Section::DebugInfo, value); |
525 | if (!ref_cu) { |
526 | m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( |
527 | "DW_FORM_ref_addr DIE reference 0x%" PRIx64"l" "x" " has no matching CU", |
528 | value); |
529 | return {}; |
530 | } |
531 | return ref_cu->GetDIE(value); |
532 | } |
533 | |
534 | case DW_FORM_ref_sig8: { |
535 | DWARFTypeUnit *tu = |
536 | m_unit->GetSymbolFileDWARF().DebugInfo().GetTypeUnitForHash(value); |
537 | if (!tu) |
538 | return {}; |
539 | return tu->GetDIE(tu->GetTypeOffset()); |
540 | } |
541 | |
542 | default: |
543 | return {}; |
544 | } |
545 | } |
546 | |
547 | uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { |
548 | uint64_t value = m_value.value.uval; |
549 | switch (m_form) { |
550 | case DW_FORM_ref1: |
551 | case DW_FORM_ref2: |
552 | case DW_FORM_ref4: |
553 | case DW_FORM_ref8: |
554 | case DW_FORM_ref_udata: |
555 | return value + base_offset; |
556 | |
557 | case DW_FORM_ref_addr: |
558 | case DW_FORM_ref_sig8: |
559 | case DW_FORM_GNU_ref_alt: |
560 | return value; |
561 | |
562 | default: |
563 | return DW_INVALID_OFFSET(~(dw_offset_t)0); |
564 | } |
565 | } |
566 | |
567 | const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } |
568 | |
569 | bool DWARFFormValue::IsBlockForm(const dw_form_t form) { |
570 | switch (form) { |
571 | case DW_FORM_exprloc: |
572 | case DW_FORM_block: |
573 | case DW_FORM_block1: |
574 | case DW_FORM_block2: |
575 | case DW_FORM_block4: |
576 | return true; |
577 | } |
578 | return false; |
579 | } |
580 | |
581 | bool DWARFFormValue::IsDataForm(const dw_form_t form) { |
582 | switch (form) { |
583 | case DW_FORM_sdata: |
584 | case DW_FORM_udata: |
585 | case DW_FORM_data1: |
586 | case DW_FORM_data2: |
587 | case DW_FORM_data4: |
588 | case DW_FORM_data8: |
589 | return true; |
590 | } |
591 | return false; |
592 | } |
593 | |
594 | bool DWARFFormValue::FormIsSupported(dw_form_t form) { |
595 | switch (form) { |
596 | case DW_FORM_addr: |
597 | case DW_FORM_addrx: |
598 | case DW_FORM_loclistx: |
599 | case DW_FORM_rnglistx: |
600 | case DW_FORM_block2: |
601 | case DW_FORM_block4: |
602 | case DW_FORM_data2: |
603 | case DW_FORM_data4: |
604 | case DW_FORM_data8: |
605 | case DW_FORM_string: |
606 | case DW_FORM_block: |
607 | case DW_FORM_block1: |
608 | case DW_FORM_data1: |
609 | case DW_FORM_flag: |
610 | case DW_FORM_sdata: |
611 | case DW_FORM_strp: |
612 | case DW_FORM_line_strp: |
613 | case DW_FORM_strx: |
614 | case DW_FORM_strx1: |
615 | case DW_FORM_strx2: |
616 | case DW_FORM_strx3: |
617 | case DW_FORM_strx4: |
618 | case DW_FORM_udata: |
619 | case DW_FORM_ref_addr: |
620 | case DW_FORM_ref1: |
621 | case DW_FORM_ref2: |
622 | case DW_FORM_ref4: |
623 | case DW_FORM_ref8: |
624 | case DW_FORM_ref_udata: |
625 | case DW_FORM_indirect: |
626 | case DW_FORM_sec_offset: |
627 | case DW_FORM_exprloc: |
628 | case DW_FORM_flag_present: |
629 | case DW_FORM_ref_sig8: |
630 | case DW_FORM_GNU_str_index: |
631 | case DW_FORM_GNU_addr_index: |
632 | case DW_FORM_implicit_const: |
633 | return true; |
634 | default: |
635 | break; |
636 | } |
637 | return false; |
638 | } |