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