DWARFFormValue.cpp revision 314564
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/Stream.h"
13#include "lldb/Core/dwarf.h"
14
15#include "DWARFCompileUnit.h"
16#include "DWARFFormValue.h"
17
18class DWARFCompileUnit;
19
20using namespace lldb_private;
21
22static 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
60static 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
99static 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
136DWARFFormValue::FixedFormSizes
137DWARFFormValue::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
155DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
156
157DWARFFormValue::DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form)
158    : m_cu(cu), m_form(form), m_value() {}
159
160void DWARFFormValue::Clear() {
161  m_cu = nullptr;
162  m_form = 0;
163  memset(&m_value, 0, sizeof(m_value));
164}
165
166bool 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, DWARFCompileUnit::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, DWARFCompileUnit::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, DWARFCompileUnit::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
291bool 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
296bool DWARFFormValue::SkipValue(dw_form_t form,
297                               const DWARFDataExtractor &debug_info_data,
298                               lldb::offset_t *offset_ptr,
299                               const DWARFCompileUnit *cu) {
300  uint8_t ref_addr_size;
301  switch (form) {
302  // Blocks if inlined data that have a length field and the data bytes
303  // inlined 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 += DWARFCompileUnit::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
405void DWARFFormValue::Dump(Stream &s) const {
406  uint64_t uvalue = Unsigned();
407  bool cu_relative_offset = false;
408
409  bool verbose = s.GetVerbose();
410
411  switch (m_form) {
412  case DW_FORM_addr:
413    s.Address(uvalue, sizeof(uint64_t));
414    break;
415  case DW_FORM_flag:
416  case DW_FORM_data1:
417    s.PutHex8(uvalue);
418    break;
419  case DW_FORM_data2:
420    s.PutHex16(uvalue);
421    break;
422  case DW_FORM_sec_offset:
423  case DW_FORM_data4:
424    s.PutHex32(uvalue);
425    break;
426  case DW_FORM_ref_sig8:
427  case DW_FORM_data8:
428    s.PutHex64(uvalue);
429    break;
430  case DW_FORM_string:
431    s.QuotedCString(AsCString());
432    break;
433  case DW_FORM_exprloc:
434  case DW_FORM_block:
435  case DW_FORM_block1:
436  case DW_FORM_block2:
437  case DW_FORM_block4:
438    if (uvalue > 0) {
439      switch (m_form) {
440      case DW_FORM_exprloc:
441      case DW_FORM_block:
442        s.Printf("<0x%" PRIx64 "> ", uvalue);
443        break;
444      case DW_FORM_block1:
445        s.Printf("<0x%2.2x> ", (uint8_t)uvalue);
446        break;
447      case DW_FORM_block2:
448        s.Printf("<0x%4.4x> ", (uint16_t)uvalue);
449        break;
450      case DW_FORM_block4:
451        s.Printf("<0x%8.8x> ", (uint32_t)uvalue);
452        break;
453      default:
454        break;
455      }
456
457      const uint8_t *data_ptr = m_value.data;
458      if (data_ptr) {
459        const uint8_t *end_data_ptr =
460            data_ptr + uvalue; // uvalue contains size of block
461        while (data_ptr < end_data_ptr) {
462          s.Printf("%2.2x ", *data_ptr);
463          ++data_ptr;
464        }
465      } else
466        s.PutCString("NULL");
467    }
468    break;
469
470  case DW_FORM_sdata:
471    s.PutSLEB128(uvalue);
472    break;
473  case DW_FORM_udata:
474    s.PutULEB128(uvalue);
475    break;
476  case DW_FORM_strp: {
477    const char *dbg_str = AsCString();
478    if (dbg_str) {
479      if (verbose)
480        s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
481      s.QuotedCString(dbg_str);
482    } else {
483      s.PutHex32(uvalue);
484    }
485  } break;
486
487  case DW_FORM_ref_addr: {
488    assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will
489                  // get this wrong
490    if (m_cu->GetVersion() <= 2)
491      s.Address(uvalue, sizeof(uint64_t) * 2);
492    else
493      s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't
494                                // support DWARF64 yet
495    break;
496  }
497  case DW_FORM_ref1:
498    cu_relative_offset = true;
499    if (verbose)
500      s.Printf("cu + 0x%2.2x", (uint8_t)uvalue);
501    break;
502  case DW_FORM_ref2:
503    cu_relative_offset = true;
504    if (verbose)
505      s.Printf("cu + 0x%4.4x", (uint16_t)uvalue);
506    break;
507  case DW_FORM_ref4:
508    cu_relative_offset = true;
509    if (verbose)
510      s.Printf("cu + 0x%4.4x", (uint32_t)uvalue);
511    break;
512  case DW_FORM_ref8:
513    cu_relative_offset = true;
514    if (verbose)
515      s.Printf("cu + 0x%8.8" PRIx64, uvalue);
516    break;
517  case DW_FORM_ref_udata:
518    cu_relative_offset = true;
519    if (verbose)
520      s.Printf("cu + 0x%" PRIx64, uvalue);
521    break;
522
523  // All DW_FORM_indirect attributes should be resolved prior to calling this
524  // function
525  case DW_FORM_indirect:
526    s.PutCString("DW_FORM_indirect");
527    break;
528  case DW_FORM_flag_present:
529    break;
530  default:
531    s.Printf("DW_FORM(0x%4.4x)", m_form);
532    break;
533  }
534
535  if (cu_relative_offset) {
536    assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
537                  // unit relative or we will get this wrong
538    if (verbose)
539      s.PutCString(" => ");
540
541    s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
542  }
543}
544
545const char *DWARFFormValue::AsCString() const {
546  SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
547
548  if (m_form == DW_FORM_string) {
549    return m_value.value.cstr;
550  } else if (m_form == DW_FORM_strp) {
551    if (!symbol_file)
552      return nullptr;
553
554    return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
555  } else if (m_form == DW_FORM_GNU_str_index) {
556    if (!symbol_file)
557      return nullptr;
558
559    uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
560    lldb::offset_t offset = m_value.value.uval * index_size;
561    dw_offset_t str_offset =
562        symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
563                                                            index_size);
564    return symbol_file->get_debug_str_data().PeekCStr(str_offset);
565  }
566  return nullptr;
567}
568
569dw_addr_t DWARFFormValue::Address() const {
570  SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
571
572  if (m_form == DW_FORM_addr)
573    return Unsigned();
574
575  assert(m_cu);
576  assert(m_form == DW_FORM_GNU_addr_index);
577
578  if (!symbol_file)
579    return 0;
580
581  uint32_t index_size = m_cu->GetAddressByteSize();
582  dw_offset_t addr_base = m_cu->GetAddrBase();
583  lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
584  return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
585}
586
587uint64_t DWARFFormValue::Reference() const {
588  uint64_t die_offset = m_value.value.uval;
589  switch (m_form) {
590  case DW_FORM_ref1:
591  case DW_FORM_ref2:
592  case DW_FORM_ref4:
593  case DW_FORM_ref8:
594  case DW_FORM_ref_udata:
595    assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
596                  // unit relative or we will get this wrong
597    die_offset += m_cu->GetOffset();
598    break;
599
600  default:
601    break;
602  }
603
604  return die_offset;
605}
606
607uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
608  uint64_t die_offset = m_value.value.uval;
609  switch (m_form) {
610  case DW_FORM_ref1:
611  case DW_FORM_ref2:
612  case DW_FORM_ref4:
613  case DW_FORM_ref8:
614  case DW_FORM_ref_udata:
615    die_offset += base_offset;
616    break;
617
618  default:
619    break;
620  }
621
622  return die_offset;
623}
624
625const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
626
627bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
628  switch (form) {
629  case DW_FORM_exprloc:
630  case DW_FORM_block:
631  case DW_FORM_block1:
632  case DW_FORM_block2:
633  case DW_FORM_block4:
634    return true;
635  }
636  return false;
637}
638
639bool DWARFFormValue::IsDataForm(const dw_form_t form) {
640  switch (form) {
641  case DW_FORM_sdata:
642  case DW_FORM_udata:
643  case DW_FORM_data1:
644  case DW_FORM_data2:
645  case DW_FORM_data4:
646  case DW_FORM_data8:
647    return true;
648  }
649  return false;
650}
651
652int DWARFFormValue::Compare(const DWARFFormValue &a_value,
653                            const DWARFFormValue &b_value) {
654  dw_form_t a_form = a_value.Form();
655  dw_form_t b_form = b_value.Form();
656  if (a_form < b_form)
657    return -1;
658  if (a_form > b_form)
659    return 1;
660  switch (a_form) {
661  case DW_FORM_addr:
662  case DW_FORM_flag:
663  case DW_FORM_data1:
664  case DW_FORM_data2:
665  case DW_FORM_data4:
666  case DW_FORM_data8:
667  case DW_FORM_udata:
668  case DW_FORM_ref_addr:
669  case DW_FORM_sec_offset:
670  case DW_FORM_flag_present:
671  case DW_FORM_ref_sig8:
672  case DW_FORM_GNU_addr_index: {
673    uint64_t a = a_value.Unsigned();
674    uint64_t b = b_value.Unsigned();
675    if (a < b)
676      return -1;
677    if (a > b)
678      return 1;
679    return 0;
680  }
681
682  case DW_FORM_sdata: {
683    int64_t a = a_value.Signed();
684    int64_t b = b_value.Signed();
685    if (a < b)
686      return -1;
687    if (a > b)
688      return 1;
689    return 0;
690  }
691
692  case DW_FORM_string:
693  case DW_FORM_strp:
694  case DW_FORM_GNU_str_index: {
695    const char *a_string = a_value.AsCString();
696    const char *b_string = b_value.AsCString();
697    if (a_string == b_string)
698      return 0;
699    else if (a_string && b_string)
700      return strcmp(a_string, b_string);
701    else if (a_string == NULL)
702      return -1; // A string is NULL, and B is valid
703    else
704      return 1; // A string valid, and B is NULL
705  }
706
707  case DW_FORM_block:
708  case DW_FORM_block1:
709  case DW_FORM_block2:
710  case DW_FORM_block4:
711  case DW_FORM_exprloc: {
712    uint64_t a_len = a_value.Unsigned();
713    uint64_t b_len = b_value.Unsigned();
714    if (a_len < b_len)
715      return -1;
716    if (a_len > b_len)
717      return 1;
718    // The block lengths are the same
719    return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
720  } break;
721
722  case DW_FORM_ref1:
723  case DW_FORM_ref2:
724  case DW_FORM_ref4:
725  case DW_FORM_ref8:
726  case DW_FORM_ref_udata: {
727    uint64_t a = a_value.Reference();
728    uint64_t b = b_value.Reference();
729    if (a < b)
730      return -1;
731    if (a > b)
732      return 1;
733    return 0;
734  }
735
736  case DW_FORM_indirect:
737    llvm_unreachable(
738        "This shouldn't happen after the form has been extracted...");
739
740  default:
741    llvm_unreachable("Unhandled DW_FORM");
742  }
743  return -1;
744}
745