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