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