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, const DWARFUnit *CU) {
280   U = CU;
281   bool Indirect = false;
282   bool IsBlock = false;
283   Value.data = nullptr;
284   // Read the value for the form into value and follow and DW_FORM_indirect
285   // instances we run into
286   do {
287     Indirect = false;
288     switch (Form) {
289     case DW_FORM_addr:
290     case DW_FORM_ref_addr: {
291       if (!U)
292         return false;
293       uint16_t Size = (Form == DW_FORM_addr) ? U->getAddressByteSize()
294                                              : U->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_sdata:
344       Value.sval = Data.getSLEB128(OffsetPtr);
345       break;
346     case DW_FORM_udata:
347     case DW_FORM_ref_udata:
348       Value.uval = Data.getULEB128(OffsetPtr);
349       break;
350     case DW_FORM_string:
351       Value.cstr = Data.getCStr(OffsetPtr);
352       break;
353     case DW_FORM_indirect:
354       Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr));
355       Indirect = true;
356       break;
357     case DW_FORM_strp:
358     case DW_FORM_sec_offset:
359     case DW_FORM_GNU_ref_alt:
360     case DW_FORM_GNU_strp_alt:
361     case DW_FORM_line_strp:
362     case DW_FORM_strp_sup: {
363       if (!U)
364         return false;
365       Value.uval =
366           Data.getRelocatedValue(U->getDwarfOffsetByteSize(), OffsetPtr);
367       break;
368     }
369     case DW_FORM_flag_present:
370       Value.uval = 1;
371       break;
372     case DW_FORM_ref_sig8:
373       Value.uval = Data.getU64(OffsetPtr);
374       break;
375     case DW_FORM_GNU_addr_index:
376     case DW_FORM_GNU_str_index:
377     case DW_FORM_strx:
378       Value.uval = Data.getULEB128(OffsetPtr);
379       break;
380     default:
381       // DWARFFormValue::skipValue() will have caught this and caused all
382       // DWARF DIEs to fail to be parsed, so this code is not be reachable.
383       llvm_unreachable("unsupported form");
384     }
385   } while (Indirect);
386 
387   if (IsBlock) {
388     StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
389     Value.data = nullptr;
390     if (!Str.empty()) {
391       Value.data = reinterpret_cast<const uint8_t *>(Str.data());
392       *OffsetPtr += Value.uval;
393     }
394   }
395 
396   return true;
397 }
398 
399 void DWARFFormValue::dump(raw_ostream &OS) const {
400   uint64_t UValue = Value.uval;
401   bool CURelativeOffset = false;
402 
403   switch (Form) {
404   case DW_FORM_addr:
405     OS << format("0x%016" PRIx64, UValue);
406     break;
407   case DW_FORM_GNU_addr_index: {
408     OS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
409     uint64_t Address;
410     if (U == nullptr)
411       OS << "<invalid dwarf unit>";
412     else if (U->getAddrOffsetSectionItem(UValue, Address))
413       OS << format("0x%016" PRIx64, Address);
414     else
415       OS << "<no .debug_addr section>";
416     break;
417   }
418   case DW_FORM_flag_present:
419     OS << "true";
420     break;
421   case DW_FORM_flag:
422   case DW_FORM_data1:
423     OS << format("0x%02x", (uint8_t)UValue);
424     break;
425   case DW_FORM_data2:
426     OS << format("0x%04x", (uint16_t)UValue);
427     break;
428   case DW_FORM_data4:
429     OS << format("0x%08x", (uint32_t)UValue);
430     break;
431   case DW_FORM_ref_sig8:
432   case DW_FORM_data8:
433     OS << format("0x%016" PRIx64, UValue);
434     break;
435   case DW_FORM_string:
436     OS << '"';
437     OS.write_escaped(Value.cstr);
438     OS << '"';
439     break;
440   case DW_FORM_exprloc:
441   case DW_FORM_block:
442   case DW_FORM_block1:
443   case DW_FORM_block2:
444   case DW_FORM_block4:
445     if (UValue > 0) {
446       switch (Form) {
447       case DW_FORM_exprloc:
448       case DW_FORM_block:
449         OS << format("<0x%" PRIx64 "> ", UValue);
450         break;
451       case DW_FORM_block1:
452         OS << format("<0x%2.2x> ", (uint8_t)UValue);
453         break;
454       case DW_FORM_block2:
455         OS << format("<0x%4.4x> ", (uint16_t)UValue);
456         break;
457       case DW_FORM_block4:
458         OS << format("<0x%8.8x> ", (uint32_t)UValue);
459         break;
460       default:
461         break;
462       }
463 
464       const uint8_t *DataPtr = Value.data;
465       if (DataPtr) {
466         // UValue contains size of block
467         const uint8_t *EndDataPtr = DataPtr + UValue;
468         while (DataPtr < EndDataPtr) {
469           OS << format("%2.2x ", *DataPtr);
470           ++DataPtr;
471         }
472       } else
473         OS << "NULL";
474     }
475     break;
476 
477   case DW_FORM_sdata:
478     OS << Value.sval;
479     break;
480   case DW_FORM_udata:
481     OS << Value.uval;
482     break;
483   case DW_FORM_strp:
484     OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
485     dumpString(OS);
486     break;
487   case DW_FORM_strx:
488   case DW_FORM_strx1:
489   case DW_FORM_strx2:
490   case DW_FORM_strx3:
491   case DW_FORM_strx4:
492   case DW_FORM_GNU_str_index:
493     OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
494     dumpString(OS);
495     break;
496   case DW_FORM_GNU_strp_alt:
497     OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
498     dumpString(OS);
499     break;
500   case DW_FORM_ref_addr:
501     OS << format("0x%016" PRIx64, UValue);
502     break;
503   case DW_FORM_ref1:
504     CURelativeOffset = true;
505     OS << format("cu + 0x%2.2x", (uint8_t)UValue);
506     break;
507   case DW_FORM_ref2:
508     CURelativeOffset = true;
509     OS << format("cu + 0x%4.4x", (uint16_t)UValue);
510     break;
511   case DW_FORM_ref4:
512     CURelativeOffset = true;
513     OS << format("cu + 0x%4.4x", (uint32_t)UValue);
514     break;
515   case DW_FORM_ref8:
516     CURelativeOffset = true;
517     OS << format("cu + 0x%8.8" PRIx64, UValue);
518     break;
519   case DW_FORM_ref_udata:
520     CURelativeOffset = true;
521     OS << format("cu + 0x%" PRIx64, UValue);
522     break;
523   case DW_FORM_GNU_ref_alt:
524     OS << format("<alt 0x%" PRIx64 ">", UValue);
525     break;
526 
527   // All DW_FORM_indirect attributes should be resolved prior to calling
528   // this function
529   case DW_FORM_indirect:
530     OS << "DW_FORM_indirect";
531     break;
532 
533   // Should be formatted to 64-bit for DWARF64.
534   case DW_FORM_sec_offset:
535     OS << format("0x%08x", (uint32_t)UValue);
536     break;
537 
538   default:
539     OS << format("DW_FORM(0x%4.4x)", Form);
540     break;
541   }
542 
543   if (CURelativeOffset) {
544     OS << " => {";
545     WithColor(OS, syntax::Address).get()
546         << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
547     OS << "}";
548   }
549 }
550 
551 void DWARFFormValue::dumpString(raw_ostream &OS) const {
552   Optional<const char *> DbgStr = getAsCString();
553   if (DbgStr.hasValue()) {
554     raw_ostream &COS = WithColor(OS, syntax::String);
555     COS << '"';
556     COS.write_escaped(DbgStr.getValue());
557     COS << '"';
558   }
559 }
560 
561 Optional<const char *> DWARFFormValue::getAsCString() const {
562   if (!isFormClass(FC_String))
563     return None;
564   if (Form == DW_FORM_string)
565     return Value.cstr;
566   // FIXME: Add support for DW_FORM_GNU_strp_alt
567   if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
568     return None;
569   uint32_t Offset = Value.uval;
570   if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
571       Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
572       Form == DW_FORM_strx4) {
573     uint64_t StrOffset;
574     if (!U->getStringOffsetSectionItem(Offset, StrOffset))
575       return None;
576     Offset = StrOffset;
577   }
578   if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
579     return Str;
580   }
581   return None;
582 }
583 
584 Optional<uint64_t> DWARFFormValue::getAsAddress() const {
585   if (!isFormClass(FC_Address))
586     return None;
587   if (Form == DW_FORM_GNU_addr_index) {
588     uint32_t Index = Value.uval;
589     uint64_t Result;
590     if (!U || !U->getAddrOffsetSectionItem(Index, Result))
591       return None;
592     return Result;
593   }
594   return Value.uval;
595 }
596 
597 Optional<uint64_t> DWARFFormValue::getAsReference() const {
598   if (!isFormClass(FC_Reference))
599     return None;
600   switch (Form) {
601   case DW_FORM_ref1:
602   case DW_FORM_ref2:
603   case DW_FORM_ref4:
604   case DW_FORM_ref8:
605   case DW_FORM_ref_udata:
606     if (!U)
607       return None;
608     return Value.uval + U->getOffset();
609   case DW_FORM_ref_addr:
610   case DW_FORM_ref_sig8:
611   case DW_FORM_GNU_ref_alt:
612     return Value.uval;
613   default:
614     return None;
615   }
616 }
617 
618 Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
619   if (!isFormClass(FC_SectionOffset))
620     return None;
621   return Value.uval;
622 }
623 
624 Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
625   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
626       Form == DW_FORM_sdata)
627     return None;
628   return Value.uval;
629 }
630 
631 Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
632   if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
633       (Form == DW_FORM_udata &&
634        uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
635     return None;
636   switch (Form) {
637   case DW_FORM_data4:
638     return int32_t(Value.uval);
639   case DW_FORM_data2:
640     return int16_t(Value.uval);
641   case DW_FORM_data1:
642     return int8_t(Value.uval);
643   case DW_FORM_sdata:
644   case DW_FORM_data8:
645   default:
646     return Value.sval;
647   }
648 }
649 
650 Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
651   if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
652     return None;
653   return makeArrayRef(Value.data, Value.uval);
654 }
655 
656 Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
657   if (!isFormClass(FC_String) && Form == DW_FORM_string)
658     return None;
659   return Value.uval;
660 }
661 
662 Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
663   if (!isFormClass(FC_Reference))
664     return None;
665   return Value.uval;
666 }
667