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