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