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