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