1 //===- DWARFFormValue.cpp -------------------------------------------------===//
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 "llvm/DebugInfo/DWARF/DWARFFormValue.h"
11 #include "SyntaxHighlighting.h"
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/None.h"
14 #include "llvm/ADT/Optional.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/BinaryFormat/Dwarf.h"
17 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
18 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
19 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <cinttypes>
24 #include <cstdint>
25 #include <limits>
26 
27 using namespace llvm;
28 using namespace dwarf;
29 using namespace syntax;
30 
31 static const DWARFFormValue::FormClass DWARF4FormClasses[] = {
32     DWARFFormValue::FC_Unknown,  // 0x0
33     DWARFFormValue::FC_Address,  // 0x01 DW_FORM_addr
34     DWARFFormValue::FC_Unknown,  // 0x02 unused
35     DWARFFormValue::FC_Block,    // 0x03 DW_FORM_block2
36     DWARFFormValue::FC_Block,    // 0x04 DW_FORM_block4
37     DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
38     // --- These can be FC_SectionOffset in DWARF3 and below:
39     DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
40     DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
41     // ---
42     DWARFFormValue::FC_String,        // 0x08 DW_FORM_string
43     DWARFFormValue::FC_Block,         // 0x09 DW_FORM_block
44     DWARFFormValue::FC_Block,         // 0x0a DW_FORM_block1
45     DWARFFormValue::FC_Constant,      // 0x0b DW_FORM_data1
46     DWARFFormValue::FC_Flag,          // 0x0c DW_FORM_flag
47     DWARFFormValue::FC_Constant,      // 0x0d DW_FORM_sdata
48     DWARFFormValue::FC_String,        // 0x0e DW_FORM_strp
49     DWARFFormValue::FC_Constant,      // 0x0f DW_FORM_udata
50     DWARFFormValue::FC_Reference,     // 0x10 DW_FORM_ref_addr
51     DWARFFormValue::FC_Reference,     // 0x11 DW_FORM_ref1
52     DWARFFormValue::FC_Reference,     // 0x12 DW_FORM_ref2
53     DWARFFormValue::FC_Reference,     // 0x13 DW_FORM_ref4
54     DWARFFormValue::FC_Reference,     // 0x14 DW_FORM_ref8
55     DWARFFormValue::FC_Reference,     // 0x15 DW_FORM_ref_udata
56     DWARFFormValue::FC_Indirect,      // 0x16 DW_FORM_indirect
57     DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
58     DWARFFormValue::FC_Exprloc,       // 0x18 DW_FORM_exprloc
59     DWARFFormValue::FC_Flag,          // 0x19 DW_FORM_flag_present
60 };
61 
62 Optional<uint8_t>
63 DWARFFormValue::getFixedByteSize(dwarf::Form Form,
64                                  const DWARFFormParams Params) {
65   switch (Form) {
66   case DW_FORM_addr:
67     if (Params)
68       return Params.AddrSize;
69     return None;
70 
71   case DW_FORM_block:          // ULEB128 length L followed by L bytes.
72   case DW_FORM_block1:         // 1 byte length L followed by L bytes.
73   case DW_FORM_block2:         // 2 byte length L followed by L bytes.
74   case DW_FORM_block4:         // 4 byte length L followed by L bytes.
75   case DW_FORM_string:         // C-string with null terminator.
76   case DW_FORM_sdata:          // SLEB128.
77   case DW_FORM_udata:          // ULEB128.
78   case DW_FORM_ref_udata:      // ULEB128.
79   case DW_FORM_indirect:       // ULEB128.
80   case DW_FORM_exprloc:        // ULEB128 length L followed by L bytes.
81   case DW_FORM_strx:           // ULEB128.
82   case DW_FORM_addrx:          // ULEB128.
83   case DW_FORM_loclistx:       // ULEB128.
84   case DW_FORM_rnglistx:       // ULEB128.
85   case DW_FORM_GNU_addr_index: // ULEB128.
86   case DW_FORM_GNU_str_index:  // ULEB128.
87     return None;
88 
89   case DW_FORM_ref_addr:
90     if (Params)
91       return Params.getRefAddrByteSize();
92     return None;
93 
94   case DW_FORM_flag:
95   case DW_FORM_data1:
96   case DW_FORM_ref1:
97   case DW_FORM_strx1:
98   case DW_FORM_addrx1:
99     return 1;
100 
101   case DW_FORM_data2:
102   case DW_FORM_ref2:
103   case DW_FORM_strx2:
104   case DW_FORM_addrx2:
105     return 2;
106 
107   case DW_FORM_strx3:
108     return 3;
109 
110   case DW_FORM_data4:
111   case DW_FORM_ref4:
112   case DW_FORM_ref_sup4:
113   case DW_FORM_strx4:
114   case DW_FORM_addrx4:
115     return 4;
116 
117   case DW_FORM_strp:
118   case DW_FORM_GNU_ref_alt:
119   case DW_FORM_GNU_strp_alt:
120   case DW_FORM_line_strp:
121   case DW_FORM_sec_offset:
122   case DW_FORM_strp_sup:
123     if (Params)
124       return Params.getDwarfOffsetByteSize();
125     return None;
126 
127   case DW_FORM_data8:
128   case DW_FORM_ref8:
129   case DW_FORM_ref_sig8:
130   case DW_FORM_ref_sup8:
131     return 8;
132 
133   case DW_FORM_flag_present:
134     return 0;
135 
136   case DW_FORM_data16:
137     return 16;
138 
139   case DW_FORM_implicit_const:
140     // The implicit value is stored in the abbreviation as a SLEB128, and
141     // there no data in debug info.
142     return 0;
143 
144   default:
145     llvm_unreachable("Handle this form in this switch statement");
146   }
147   return None;
148 }
149 
150 bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
151                                uint32_t *OffsetPtr,
152                                const DWARFFormParams Params) {
153   bool Indirect = false;
154   do {
155     switch (Form) {
156     // Blocks of inlined data that have a length field and the data bytes
157     // inlined in the .debug_info.
158     case DW_FORM_exprloc:
159     case DW_FORM_block: {
160       uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
161       *OffsetPtr += size;
162       return true;
163     }
164     case DW_FORM_block1: {
165       uint8_t size = DebugInfoData.getU8(OffsetPtr);
166       *OffsetPtr += size;
167       return true;
168     }
169     case DW_FORM_block2: {
170       uint16_t size = DebugInfoData.getU16(OffsetPtr);
171       *OffsetPtr += size;
172       return true;
173     }
174     case DW_FORM_block4: {
175       uint32_t size = DebugInfoData.getU32(OffsetPtr);
176       *OffsetPtr += size;
177       return true;
178     }
179 
180     // Inlined NULL terminated C-strings.
181     case DW_FORM_string:
182       DebugInfoData.getCStr(OffsetPtr);
183       return true;
184 
185     case DW_FORM_addr:
186     case DW_FORM_ref_addr:
187     case DW_FORM_flag_present:
188     case DW_FORM_data1:
189     case DW_FORM_data2:
190     case DW_FORM_data4:
191     case DW_FORM_data8:
192     case DW_FORM_data16:
193     case DW_FORM_flag:
194     case DW_FORM_ref1:
195     case DW_FORM_ref2:
196     case DW_FORM_ref4:
197     case DW_FORM_ref8:
198     case DW_FORM_ref_sig8:
199     case DW_FORM_ref_sup4:
200     case DW_FORM_ref_sup8:
201     case DW_FORM_strx1:
202     case DW_FORM_strx2:
203     case DW_FORM_strx4:
204     case DW_FORM_addrx1:
205     case DW_FORM_addrx2:
206     case DW_FORM_addrx4:
207     case DW_FORM_sec_offset:
208     case DW_FORM_strp:
209     case DW_FORM_strp_sup:
210     case DW_FORM_line_strp:
211     case DW_FORM_GNU_ref_alt:
212     case DW_FORM_GNU_strp_alt:
213       if (Optional<uint8_t> FixedSize =
214               DWARFFormValue::getFixedByteSize(Form, Params)) {
215         *OffsetPtr += *FixedSize;
216         return true;
217       }
218       return false;
219 
220     // signed or unsigned LEB 128 values.
221     case DW_FORM_sdata:
222       DebugInfoData.getSLEB128(OffsetPtr);
223       return true;
224 
225     case DW_FORM_udata:
226     case DW_FORM_ref_udata:
227     case DW_FORM_strx:
228     case DW_FORM_addrx:
229     case DW_FORM_loclistx:
230     case DW_FORM_rnglistx:
231     case DW_FORM_GNU_addr_index:
232     case DW_FORM_GNU_str_index:
233       DebugInfoData.getULEB128(OffsetPtr);
234       return true;
235 
236     case DW_FORM_indirect:
237       Indirect = true;
238       Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
239       break;
240 
241     default:
242       return false;
243     }
244   } while (Indirect);
245   return true;
246 }
247 
248 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
249   // First, check DWARF4 form classes.
250   if (Form < makeArrayRef(DWARF4FormClasses).size() &&
251       DWARF4FormClasses[Form] == FC)
252     return true;
253   // Check more forms from DWARF4 and DWARF5 proposals.
254   switch (Form) {
255   case DW_FORM_ref_sig8:
256   case DW_FORM_GNU_ref_alt:
257     return (FC == FC_Reference);
258   case DW_FORM_GNU_addr_index:
259     return (FC == FC_Address);
260   case DW_FORM_GNU_str_index:
261   case DW_FORM_GNU_strp_alt:
262   case DW_FORM_strx:
263   case DW_FORM_strx1:
264   case DW_FORM_strx2:
265   case DW_FORM_strx3:
266   case DW_FORM_strx4:
267     return (FC == FC_String);
268   case DW_FORM_implicit_const:
269     return (FC == FC_Constant);
270   default:
271     break;
272   }
273   // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
274   // Don't check for DWARF version here, as some producers may still do this
275   // by mistake. Also accept DW_FORM_strp since this is .debug_str section
276   // offset.
277   return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
278           Form == DW_FORM_strp) &&
279          FC == FC_SectionOffset;
280 }
281 
282 bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
283                                   uint32_t *OffsetPtr, DWARFFormParams FP,
284                                   const DWARFUnit *CU) {
285   U = CU;
286   bool Indirect = false;
287   bool IsBlock = false;
288   Value.data = nullptr;
289   // Read the value for the form into value and follow and DW_FORM_indirect
290   // instances we run into
291   do {
292     Indirect = false;
293     switch (Form) {
294     case DW_FORM_addr:
295     case DW_FORM_ref_addr: {
296       uint16_t Size =
297           (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
298       Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
299       break;
300     }
301     case DW_FORM_exprloc:
302     case DW_FORM_block:
303       Value.uval = Data.getULEB128(OffsetPtr);
304       IsBlock = true;
305       break;
306     case DW_FORM_block1:
307       Value.uval = Data.getU8(OffsetPtr);
308       IsBlock = true;
309       break;
310     case DW_FORM_block2:
311       Value.uval = Data.getU16(OffsetPtr);
312       IsBlock = true;
313       break;
314     case DW_FORM_block4:
315       Value.uval = Data.getU32(OffsetPtr);
316       IsBlock = true;
317       break;
318     case DW_FORM_data1:
319     case DW_FORM_ref1:
320     case DW_FORM_flag:
321     case DW_FORM_strx1:
322     case DW_FORM_addrx1:
323       Value.uval = Data.getU8(OffsetPtr);
324       break;
325     case DW_FORM_data2:
326     case DW_FORM_ref2:
327     case DW_FORM_strx2:
328     case DW_FORM_addrx2:
329       Value.uval = Data.getU16(OffsetPtr);
330       break;
331     case DW_FORM_strx3:
332       Value.uval = Data.getU24(OffsetPtr);
333       break;
334     case DW_FORM_data4:
335     case DW_FORM_ref4:
336     case DW_FORM_ref_sup4:
337     case DW_FORM_strx4:
338     case DW_FORM_addrx4:
339       Value.uval = Data.getRelocatedValue(4, OffsetPtr);
340       break;
341     case DW_FORM_data8:
342     case DW_FORM_ref8:
343     case DW_FORM_ref_sup8:
344       Value.uval = Data.getU64(OffsetPtr);
345       break;
346     case DW_FORM_data16:
347       // Treat this like a 16-byte block.
348       Value.uval = 16;
349       IsBlock = true;
350       break;
351     case DW_FORM_sdata:
352       Value.sval = Data.getSLEB128(OffsetPtr);
353       break;
354     case DW_FORM_udata:
355     case DW_FORM_ref_udata:
356       Value.uval = Data.getULEB128(OffsetPtr);
357       break;
358     case DW_FORM_string:
359       Value.cstr = Data.getCStr(OffsetPtr);
360       break;
361     case DW_FORM_indirect:
362       Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr));
363       Indirect = true;
364       break;
365     case DW_FORM_strp:
366     case DW_FORM_sec_offset:
367     case DW_FORM_GNU_ref_alt:
368     case DW_FORM_GNU_strp_alt:
369     case DW_FORM_line_strp:
370     case DW_FORM_strp_sup: {
371       Value.uval =
372           Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
373       break;
374     }
375     case DW_FORM_flag_present:
376       Value.uval = 1;
377       break;
378     case DW_FORM_ref_sig8:
379       Value.uval = Data.getU64(OffsetPtr);
380       break;
381     case DW_FORM_GNU_addr_index:
382     case DW_FORM_GNU_str_index:
383     case DW_FORM_strx:
384       Value.uval = Data.getULEB128(OffsetPtr);
385       break;
386     default:
387       // DWARFFormValue::skipValue() will have caught this and caused all
388       // DWARF DIEs to fail to be parsed, so this code is not be reachable.
389       llvm_unreachable("unsupported form");
390     }
391   } while (Indirect);
392 
393   if (IsBlock) {
394     StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
395     Value.data = nullptr;
396     if (!Str.empty()) {
397       Value.data = reinterpret_cast<const uint8_t *>(Str.data());
398       *OffsetPtr += Value.uval;
399     }
400   }
401 
402   return true;
403 }
404 
405 void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
406   uint64_t UValue = Value.uval;
407   bool CURelativeOffset = false;
408   raw_ostream &AddrOS =
409       DumpOpts.ShowAddresses ? WithColor(OS, syntax::Address).get() : nulls();
410   switch (Form) {
411   case DW_FORM_addr:
412     AddrOS << format("0x%016" PRIx64, UValue);
413     break;
414   case DW_FORM_GNU_addr_index: {
415     AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
416     uint64_t Address;
417     if (U == nullptr)
418       OS << "<invalid dwarf unit>";
419     else if (U->getAddrOffsetSectionItem(UValue, Address))
420       AddrOS << format("0x%016" PRIx64, Address);
421     else
422       OS << "<no .debug_addr section>";
423     break;
424   }
425   case DW_FORM_flag_present:
426     OS << "true";
427     break;
428   case DW_FORM_flag:
429   case DW_FORM_data1:
430     OS << format("0x%02x", (uint8_t)UValue);
431     break;
432   case DW_FORM_data2:
433     OS << format("0x%04x", (uint16_t)UValue);
434     break;
435   case DW_FORM_data4:
436     OS << format("0x%08x", (uint32_t)UValue);
437     break;
438   case DW_FORM_ref_sig8:
439     AddrOS << format("0x%016" PRIx64, UValue);
440     break;
441   case DW_FORM_data8:
442     OS << format("0x%016" PRIx64, UValue);
443     break;
444   case DW_FORM_data16:
445     OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16);
446     break;
447   case DW_FORM_string:
448     OS << '"';
449     OS.write_escaped(Value.cstr);
450     OS << '"';
451     break;
452   case DW_FORM_exprloc:
453   case DW_FORM_block:
454   case DW_FORM_block1:
455   case DW_FORM_block2:
456   case DW_FORM_block4:
457     if (UValue > 0) {
458       switch (Form) {
459       case DW_FORM_exprloc:
460       case DW_FORM_block:
461         OS << format("<0x%" PRIx64 "> ", UValue);
462         break;
463       case DW_FORM_block1:
464         OS << format("<0x%2.2x> ", (uint8_t)UValue);
465         break;
466       case DW_FORM_block2:
467         OS << format("<0x%4.4x> ", (uint16_t)UValue);
468         break;
469       case DW_FORM_block4:
470         OS << format("<0x%8.8x> ", (uint32_t)UValue);
471         break;
472       default:
473         break;
474       }
475 
476       const uint8_t *DataPtr = Value.data;
477       if (DataPtr) {
478         // UValue contains size of block
479         const uint8_t *EndDataPtr = DataPtr + UValue;
480         while (DataPtr < EndDataPtr) {
481           OS << format("%2.2x ", *DataPtr);
482           ++DataPtr;
483         }
484       } else
485         OS << "NULL";
486     }
487     break;
488 
489   case DW_FORM_sdata:
490     OS << Value.sval;
491     break;
492   case DW_FORM_udata:
493     OS << Value.uval;
494     break;
495   case DW_FORM_strp:
496     if (DumpOpts.Verbose)
497       OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
498     dumpString(OS);
499     break;
500   case DW_FORM_strx:
501   case DW_FORM_strx1:
502   case DW_FORM_strx2:
503   case DW_FORM_strx3:
504   case DW_FORM_strx4:
505   case DW_FORM_GNU_str_index:
506     if (DumpOpts.Verbose)
507       OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
508     dumpString(OS);
509     break;
510   case DW_FORM_GNU_strp_alt:
511     if (DumpOpts.Verbose)
512       OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
513     dumpString(OS);
514     break;
515   case DW_FORM_ref_addr:
516     AddrOS << format("0x%016" PRIx64, UValue);
517     break;
518   case DW_FORM_ref1:
519     CURelativeOffset = true;
520     AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue);
521     break;
522   case DW_FORM_ref2:
523     CURelativeOffset = true;
524     AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue);
525     break;
526   case DW_FORM_ref4:
527     CURelativeOffset = true;
528     AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue);
529     break;
530   case DW_FORM_ref8:
531     CURelativeOffset = true;
532     AddrOS << format("cu + 0x%8.8" PRIx64, UValue);
533     break;
534   case DW_FORM_ref_udata:
535     CURelativeOffset = true;
536     AddrOS << format("cu + 0x%" PRIx64, UValue);
537     break;
538   case DW_FORM_GNU_ref_alt:
539     AddrOS << format("<alt 0x%" PRIx64 ">", UValue);
540     break;
541 
542   // All DW_FORM_indirect attributes should be resolved prior to calling
543   // this function
544   case DW_FORM_indirect:
545     OS << "DW_FORM_indirect";
546     break;
547 
548   // Should be formatted to 64-bit for DWARF64.
549   case DW_FORM_sec_offset:
550     AddrOS << format("0x%08x", (uint32_t)UValue);
551     break;
552 
553   default:
554     OS << format("DW_FORM(0x%4.4x)", Form);
555     break;
556   }
557 
558   if (CURelativeOffset && DumpOpts.Verbose) {
559     OS << " => {";
560     WithColor(OS, syntax::Address).get()
561         << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
562     OS << "}";
563   }
564 }
565 
566 void DWARFFormValue::dumpString(raw_ostream &OS) const {
567   Optional<const char *> DbgStr = getAsCString();
568   if (DbgStr.hasValue()) {
569     raw_ostream &COS = WithColor(OS, syntax::String);
570     COS << '"';
571     COS.write_escaped(DbgStr.getValue());
572     COS << '"';
573   }
574 }
575 
576 Optional<const char *> DWARFFormValue::getAsCString() const {
577   if (!isFormClass(FC_String))
578     return None;
579   if (Form == DW_FORM_string)
580     return Value.cstr;
581   // FIXME: Add support for DW_FORM_GNU_strp_alt
582   if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
583     return None;
584   uint32_t Offset = Value.uval;
585   if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
586       Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
587       Form == DW_FORM_strx4) {
588     uint64_t StrOffset;
589     if (!U->getStringOffsetSectionItem(Offset, StrOffset))
590       return None;
591     Offset = StrOffset;
592   }
593   if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
594     return Str;
595   }
596   return None;
597 }
598 
599 Optional<uint64_t> DWARFFormValue::getAsAddress() const {
600   if (!isFormClass(FC_Address))
601     return None;
602   if (Form == DW_FORM_GNU_addr_index) {
603     uint32_t Index = Value.uval;
604     uint64_t Result;
605     if (!U || !U->getAddrOffsetSectionItem(Index, Result))
606       return None;
607     return Result;
608   }
609   return Value.uval;
610 }
611 
612 Optional<uint64_t> DWARFFormValue::getAsReference() const {
613   if (!isFormClass(FC_Reference))
614     return None;
615   switch (Form) {
616   case DW_FORM_ref1:
617   case DW_FORM_ref2:
618   case DW_FORM_ref4:
619   case DW_FORM_ref8:
620   case DW_FORM_ref_udata:
621     if (!U)
622       return None;
623     return Value.uval + U->getOffset();
624   case DW_FORM_ref_addr:
625   case DW_FORM_ref_sig8:
626   case DW_FORM_GNU_ref_alt:
627     return Value.uval;
628   default:
629     return None;
630   }
631 }
632 
633 Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
634   if (!isFormClass(FC_SectionOffset))
635     return None;
636   return Value.uval;
637 }
638 
639 Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
640   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
641       Form == DW_FORM_sdata)
642     return None;
643   return Value.uval;
644 }
645 
646 Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
647   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
648       (Form == DW_FORM_udata &&
649        uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
650     return None;
651   switch (Form) {
652   case DW_FORM_data4:
653     return int32_t(Value.uval);
654   case DW_FORM_data2:
655     return int16_t(Value.uval);
656   case DW_FORM_data1:
657     return int8_t(Value.uval);
658   case DW_FORM_sdata:
659   case DW_FORM_data8:
660   default:
661     return Value.sval;
662   }
663 }
664 
665 Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
666   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
667       Form != DW_FORM_data16)
668     return None;
669   return makeArrayRef(Value.data, Value.uval);
670 }
671 
672 Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
673   if (!isFormClass(FC_String) && Form == DW_FORM_string)
674     return None;
675   return Value.uval;
676 }
677 
678 Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
679   if (!isFormClass(FC_Reference))
680     return None;
681   return Value.uval;
682 }
683