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 | #include <optional> |
11 | |
12 | #include "lldb/Core/Module.h" |
13 | #include "lldb/Core/dwarf.h" |
14 | #include "lldb/Symbol/ObjectFile.h" |
15 | #include "lldb/Utility/Stream.h" |
16 | |
17 | #include "DWARFDebugInfo.h" |
18 | #include "DWARFFormValue.h" |
19 | #include "DWARFUnit.h" |
20 | |
21 | using namespace lldb_private; |
22 | using namespace lldb_private::dwarf; |
23 | using namespace lldb_private::plugin::dwarf; |
24 | |
25 | void DWARFFormValue::Clear() { |
26 | m_unit = nullptr; |
27 | m_form = dw_form_t(0); |
28 | m_value = ValueTypeTag(); |
29 | } |
30 | |
31 | bool DWARFFormValue::(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); |
47 | m_value.value.uval = |
48 | data.GetMaxU64(offset_ptr, byte_size: DWARFUnit::GetAddressByteSize(cu: 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, byte_size: 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, byte_size: 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); |
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, byte_size: ref_addr_size); |
127 | break; |
128 | case DW_FORM_indirect: |
129 | m_form = static_cast<dw_form_t>(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: *offset_ptr, length: 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 | {.valid: 0, .size: 0}, // 0x00 unused |
155 | {.valid: 0, .size: 0}, // 0x01 DW_FORM_addr |
156 | {.valid: 0, .size: 0}, // 0x02 unused |
157 | {.valid: 0, .size: 0}, // 0x03 DW_FORM_block2 |
158 | {.valid: 0, .size: 0}, // 0x04 DW_FORM_block4 |
159 | {.valid: 1, .size: 2}, // 0x05 DW_FORM_data2 |
160 | {.valid: 1, .size: 4}, // 0x06 DW_FORM_data4 |
161 | {.valid: 1, .size: 8}, // 0x07 DW_FORM_data8 |
162 | {.valid: 0, .size: 0}, // 0x08 DW_FORM_string |
163 | {.valid: 0, .size: 0}, // 0x09 DW_FORM_block |
164 | {.valid: 0, .size: 0}, // 0x0a DW_FORM_block1 |
165 | {.valid: 1, .size: 1}, // 0x0b DW_FORM_data1 |
166 | {.valid: 1, .size: 1}, // 0x0c DW_FORM_flag |
167 | {.valid: 0, .size: 0}, // 0x0d DW_FORM_sdata |
168 | {.valid: 1, .size: 4}, // 0x0e DW_FORM_strp |
169 | {.valid: 0, .size: 0}, // 0x0f DW_FORM_udata |
170 | {.valid: 0, .size: 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 | {.valid: 1, .size: 1}, // 0x11 DW_FORM_ref1 |
173 | {.valid: 1, .size: 2}, // 0x12 DW_FORM_ref2 |
174 | {.valid: 1, .size: 4}, // 0x13 DW_FORM_ref4 |
175 | {.valid: 1, .size: 8}, // 0x14 DW_FORM_ref8 |
176 | {.valid: 0, .size: 0}, // 0x15 DW_FORM_ref_udata |
177 | {.valid: 0, .size: 0}, // 0x16 DW_FORM_indirect |
178 | {.valid: 1, .size: 4}, // 0x17 DW_FORM_sec_offset |
179 | {.valid: 0, .size: 0}, // 0x18 DW_FORM_exprloc |
180 | {.valid: 1, .size: 0}, // 0x19 DW_FORM_flag_present |
181 | {.valid: 0, .size: 0}, // 0x1a DW_FORM_strx (ULEB128) |
182 | {.valid: 0, .size: 0}, // 0x1b DW_FORM_addrx (ULEB128) |
183 | {.valid: 1, .size: 4}, // 0x1c DW_FORM_ref_sup4 |
184 | {.valid: 0, .size: 0}, // 0x1d DW_FORM_strp_sup (4 bytes for DWARF32, 8 bytes for DWARF64) |
185 | {.valid: 1, .size: 16}, // 0x1e DW_FORM_data16 |
186 | {.valid: 1, .size: 4}, // 0x1f DW_FORM_line_strp |
187 | {.valid: 1, .size: 8}, // 0x20 DW_FORM_ref_sig8 |
188 | }; |
189 | |
190 | std::optional<uint8_t> DWARFFormValue::GetFixedSize(dw_form_t form, |
191 | const DWARFUnit *u) { |
192 | if (form <= DW_FORM_ref_sig8 && g_form_sizes[form].valid) |
193 | return static_cast<uint8_t>(g_form_sizes[form].size); |
194 | if (form == DW_FORM_addr && u) |
195 | return u->GetAddressByteSize(); |
196 | return std::nullopt; |
197 | } |
198 | |
199 | std::optional<uint8_t> DWARFFormValue::GetFixedSize() const { |
200 | return GetFixedSize(form: m_form, u: m_unit); |
201 | } |
202 | |
203 | bool DWARFFormValue::(const DWARFDataExtractor &debug_info_data, |
204 | lldb::offset_t *offset_ptr) const { |
205 | return DWARFFormValue::SkipValue(form: m_form, debug_info_data, offset_ptr, unit: m_unit); |
206 | } |
207 | |
208 | bool DWARFFormValue::(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 | uint64_t size = debug_info_data.GetULEB128(offset_ptr); |
219 | *offset_ptr += size; |
220 | } |
221 | return true; |
222 | case DW_FORM_block1: { |
223 | uint8_t size = debug_info_data.GetU8(offset_ptr); |
224 | *offset_ptr += size; |
225 | } |
226 | return true; |
227 | case DW_FORM_block2: { |
228 | uint16_t size = debug_info_data.GetU16(offset_ptr); |
229 | *offset_ptr += size; |
230 | } |
231 | return true; |
232 | case DW_FORM_block4: { |
233 | uint32_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(cu: unit); |
246 | return true; |
247 | |
248 | case DW_FORM_ref_addr: |
249 | ref_addr_size = 4; |
250 | assert(unit); // 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 | auto indirect_form = |
324 | static_cast<dw_form_t>(debug_info_data.GetULEB128(offset_ptr)); |
325 | return DWARFFormValue::SkipValue(form: indirect_form, debug_info_data, |
326 | offset_ptr, unit); |
327 | } |
328 | |
329 | default: |
330 | break; |
331 | } |
332 | return false; |
333 | } |
334 | |
335 | void DWARFFormValue::Dump(Stream &s) const { |
336 | uint64_t uvalue = Unsigned(); |
337 | bool unit_relative_offset = false; |
338 | |
339 | switch (m_form) { |
340 | case DW_FORM_addr: |
341 | DumpAddress(s&: s.AsRawOstream(), addr: uvalue, addr_size: sizeof(uint64_t)); |
342 | break; |
343 | case DW_FORM_flag: |
344 | case DW_FORM_data1: |
345 | s.PutHex8(uvalue); |
346 | break; |
347 | case DW_FORM_data2: |
348 | s.PutHex16(uvalue); |
349 | break; |
350 | case DW_FORM_sec_offset: |
351 | case DW_FORM_data4: |
352 | s.PutHex32(uvalue); |
353 | break; |
354 | case DW_FORM_ref_sig8: |
355 | case DW_FORM_data8: |
356 | s.PutHex64(uvalue); |
357 | break; |
358 | case DW_FORM_string: |
359 | s.QuotedCString(cstr: AsCString()); |
360 | break; |
361 | case DW_FORM_exprloc: |
362 | case DW_FORM_block: |
363 | case DW_FORM_block1: |
364 | case DW_FORM_block2: |
365 | case DW_FORM_block4: |
366 | if (uvalue > 0) { |
367 | switch (m_form) { |
368 | case DW_FORM_exprloc: |
369 | case DW_FORM_block: |
370 | s.Printf(format: "<0x%" PRIx64 "> " , uvalue); |
371 | break; |
372 | case DW_FORM_block1: |
373 | s.Printf(format: "<0x%2.2x> " , (uint8_t)uvalue); |
374 | break; |
375 | case DW_FORM_block2: |
376 | s.Printf(format: "<0x%4.4x> " , (uint16_t)uvalue); |
377 | break; |
378 | case DW_FORM_block4: |
379 | s.Printf(format: "<0x%8.8x> " , (uint32_t)uvalue); |
380 | break; |
381 | default: |
382 | break; |
383 | } |
384 | |
385 | const uint8_t *data_ptr = m_value.data; |
386 | if (data_ptr) { |
387 | const uint8_t *end_data_ptr = |
388 | data_ptr + uvalue; // uvalue contains size of block |
389 | while (data_ptr < end_data_ptr) { |
390 | s.Printf(format: "%2.2x " , *data_ptr); |
391 | ++data_ptr; |
392 | } |
393 | } else |
394 | s.PutCString(cstr: "NULL" ); |
395 | } |
396 | break; |
397 | |
398 | case DW_FORM_sdata: |
399 | s.PutSLEB128(uval: uvalue); |
400 | break; |
401 | case DW_FORM_udata: |
402 | s.PutULEB128(uval: uvalue); |
403 | break; |
404 | case DW_FORM_strp: |
405 | case DW_FORM_line_strp: { |
406 | const char *dbg_str = AsCString(); |
407 | if (dbg_str) { |
408 | s.QuotedCString(cstr: dbg_str); |
409 | } else { |
410 | s.PutHex32(uvalue); |
411 | } |
412 | } break; |
413 | |
414 | case DW_FORM_ref_addr: { |
415 | assert(m_unit); // Unit must be valid for DW_FORM_ref_addr objects or we |
416 | // will get this wrong |
417 | if (m_unit->GetVersion() <= 2) |
418 | DumpAddress(s&: s.AsRawOstream(), addr: uvalue, addr_size: sizeof(uint64_t) * 2); |
419 | else |
420 | DumpAddress(s&: s.AsRawOstream(), addr: uvalue, |
421 | addr_size: 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't |
422 | // support DWARF64 yet |
423 | break; |
424 | } |
425 | case DW_FORM_ref1: |
426 | unit_relative_offset = true; |
427 | break; |
428 | case DW_FORM_ref2: |
429 | unit_relative_offset = true; |
430 | break; |
431 | case DW_FORM_ref4: |
432 | unit_relative_offset = true; |
433 | break; |
434 | case DW_FORM_ref8: |
435 | unit_relative_offset = true; |
436 | break; |
437 | case DW_FORM_ref_udata: |
438 | unit_relative_offset = true; |
439 | break; |
440 | |
441 | // All DW_FORM_indirect attributes should be resolved prior to calling this |
442 | // function |
443 | case DW_FORM_indirect: |
444 | s.PutCString(cstr: "DW_FORM_indirect" ); |
445 | break; |
446 | case DW_FORM_flag_present: |
447 | break; |
448 | default: |
449 | s.Printf(format: "DW_FORM(0x%4.4x)" , m_form); |
450 | break; |
451 | } |
452 | |
453 | if (unit_relative_offset) { |
454 | assert(m_unit); // Unit must be valid for DW_FORM_ref forms that are compile |
455 | // unit relative or we will get this wrong |
456 | s.Printf(format: "{0x%8.8" PRIx64 "}" , uvalue + m_unit->GetOffset()); |
457 | } |
458 | } |
459 | |
460 | const char *DWARFFormValue::AsCString() const { |
461 | DWARFContext &context = m_unit->GetSymbolFileDWARF().GetDWARFContext(); |
462 | |
463 | if (m_form == DW_FORM_string) |
464 | return m_value.value.cstr; |
465 | if (m_form == DW_FORM_strp) |
466 | return context.getOrLoadStrData().PeekCStr(offset: m_value.value.uval); |
467 | |
468 | if (m_form == DW_FORM_GNU_str_index || m_form == DW_FORM_strx || |
469 | m_form == DW_FORM_strx1 || m_form == DW_FORM_strx2 || |
470 | m_form == DW_FORM_strx3 || m_form == DW_FORM_strx4) { |
471 | |
472 | std::optional<uint64_t> offset = |
473 | m_unit->GetStringOffsetSectionItem(index: m_value.value.uval); |
474 | if (!offset) |
475 | return nullptr; |
476 | return context.getOrLoadStrData().PeekCStr(offset: *offset); |
477 | } |
478 | |
479 | if (m_form == DW_FORM_line_strp) |
480 | return context.getOrLoadLineStrData().PeekCStr(offset: m_value.value.uval); |
481 | |
482 | return nullptr; |
483 | } |
484 | |
485 | dw_addr_t DWARFFormValue::Address() const { |
486 | SymbolFileDWARF &symbol_file = m_unit->GetSymbolFileDWARF(); |
487 | |
488 | if (m_form == DW_FORM_addr) |
489 | return Unsigned(); |
490 | |
491 | assert(m_unit); |
492 | assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || |
493 | m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || |
494 | m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4); |
495 | |
496 | uint32_t index_size = m_unit->GetAddressByteSize(); |
497 | dw_offset_t addr_base = m_unit->GetAddrBase(); |
498 | lldb::offset_t offset = addr_base + m_value.value.uval * index_size; |
499 | return symbol_file.GetDWARFContext().getOrLoadAddrData().GetMaxU64( |
500 | offset_ptr: &offset, byte_size: index_size); |
501 | } |
502 | |
503 | std::pair<DWARFUnit *, uint64_t> |
504 | DWARFFormValue::ReferencedUnitAndOffset() const { |
505 | uint64_t value = m_value.value.uval; |
506 | switch (m_form) { |
507 | case DW_FORM_ref1: |
508 | case DW_FORM_ref2: |
509 | case DW_FORM_ref4: |
510 | case DW_FORM_ref8: |
511 | case DW_FORM_ref_udata: |
512 | assert(m_unit); // Unit must be valid for DW_FORM_ref forms that are compile |
513 | // unit relative or we will get this wrong |
514 | value += m_unit->GetOffset(); |
515 | if (!m_unit->ContainsDIEOffset(die_offset: value)) { |
516 | m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( |
517 | format: "DW_FORM_ref* DIE reference {0:x16} is outside of its CU" , args&: value); |
518 | return {nullptr, 0}; |
519 | } |
520 | return {const_cast<DWARFUnit *>(m_unit), value}; |
521 | |
522 | case DW_FORM_ref_addr: { |
523 | DWARFUnit *ref_cu = |
524 | m_unit->GetSymbolFileDWARF().DebugInfo().GetUnitContainingDIEOffset( |
525 | section: DIERef::Section::DebugInfo, die_offset: value); |
526 | if (!ref_cu) { |
527 | m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( |
528 | format: "DW_FORM_ref_addr DIE reference {0:x16} has no matching CU" , args&: value); |
529 | return {nullptr, 0}; |
530 | } |
531 | return {ref_cu, value}; |
532 | } |
533 | |
534 | case DW_FORM_ref_sig8: { |
535 | DWARFTypeUnit *tu = |
536 | m_unit->GetSymbolFileDWARF().DebugInfo().GetTypeUnitForHash(hash: value); |
537 | if (!tu) |
538 | return {nullptr, 0}; |
539 | return {tu, tu->GetTypeOffset()}; |
540 | } |
541 | |
542 | default: |
543 | return {nullptr, 0}; |
544 | } |
545 | } |
546 | |
547 | DWARFDIE DWARFFormValue::Reference() const { |
548 | auto [unit, offset] = ReferencedUnitAndOffset(); |
549 | return unit ? unit->GetDIE(die_offset: offset) : DWARFDIE(); |
550 | } |
551 | |
552 | uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { |
553 | uint64_t value = m_value.value.uval; |
554 | switch (m_form) { |
555 | case DW_FORM_ref1: |
556 | case DW_FORM_ref2: |
557 | case DW_FORM_ref4: |
558 | case DW_FORM_ref8: |
559 | case DW_FORM_ref_udata: |
560 | return value + base_offset; |
561 | |
562 | case DW_FORM_ref_addr: |
563 | case DW_FORM_ref_sig8: |
564 | case DW_FORM_GNU_ref_alt: |
565 | return value; |
566 | |
567 | default: |
568 | return DW_INVALID_OFFSET; |
569 | } |
570 | } |
571 | |
572 | const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } |
573 | |
574 | bool DWARFFormValue::IsBlockForm(const dw_form_t form) { |
575 | switch (form) { |
576 | case DW_FORM_exprloc: |
577 | case DW_FORM_block: |
578 | case DW_FORM_block1: |
579 | case DW_FORM_block2: |
580 | case DW_FORM_block4: |
581 | return true; |
582 | default: |
583 | return false; |
584 | } |
585 | llvm_unreachable("All cases handled above!" ); |
586 | } |
587 | |
588 | bool DWARFFormValue::IsDataForm(const dw_form_t form) { |
589 | switch (form) { |
590 | case DW_FORM_sdata: |
591 | case DW_FORM_udata: |
592 | case DW_FORM_data1: |
593 | case DW_FORM_data2: |
594 | case DW_FORM_data4: |
595 | case DW_FORM_data8: |
596 | return true; |
597 | default: |
598 | return false; |
599 | } |
600 | llvm_unreachable("All cases handled above!" ); |
601 | } |
602 | |
603 | bool DWARFFormValue::FormIsSupported(dw_form_t form) { |
604 | switch (form) { |
605 | case DW_FORM_addr: |
606 | case DW_FORM_addrx: |
607 | case DW_FORM_loclistx: |
608 | case DW_FORM_rnglistx: |
609 | case DW_FORM_block2: |
610 | case DW_FORM_block4: |
611 | case DW_FORM_data2: |
612 | case DW_FORM_data4: |
613 | case DW_FORM_data8: |
614 | case DW_FORM_string: |
615 | case DW_FORM_block: |
616 | case DW_FORM_block1: |
617 | case DW_FORM_data1: |
618 | case DW_FORM_flag: |
619 | case DW_FORM_sdata: |
620 | case DW_FORM_strp: |
621 | case DW_FORM_line_strp: |
622 | case DW_FORM_strx: |
623 | case DW_FORM_strx1: |
624 | case DW_FORM_strx2: |
625 | case DW_FORM_strx3: |
626 | case DW_FORM_strx4: |
627 | case DW_FORM_udata: |
628 | case DW_FORM_ref_addr: |
629 | case DW_FORM_ref1: |
630 | case DW_FORM_ref2: |
631 | case DW_FORM_ref4: |
632 | case DW_FORM_ref8: |
633 | case DW_FORM_ref_udata: |
634 | case DW_FORM_indirect: |
635 | case DW_FORM_sec_offset: |
636 | case DW_FORM_exprloc: |
637 | case DW_FORM_flag_present: |
638 | case DW_FORM_ref_sig8: |
639 | case DW_FORM_GNU_str_index: |
640 | case DW_FORM_GNU_addr_index: |
641 | case DW_FORM_implicit_const: |
642 | return true; |
643 | default: |
644 | break; |
645 | } |
646 | return false; |
647 | } |
648 | |