1 //===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===//
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/DWARFDebugFrame.h"
10 #include "llvm/ADT/DenseMap.h"
11 #include "llvm/ADT/Optional.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/BinaryFormat/Dwarf.h"
15 #include "llvm/MC/MCRegisterInfo.h"
16 #include "llvm/Support/Casting.h"
17 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/DataExtractor.h"
19 #include "llvm/Support/Errc.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <algorithm>
24 #include <cassert>
25 #include <cinttypes>
26 #include <cstdint>
27 #include <string>
28 #include <vector>
29 
30 using namespace llvm;
31 using namespace dwarf;
32 
33 static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
34                           unsigned RegNum) {
35   if (MRI) {
36     if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) {
37       if (const char *RegName = MRI->getName(*LLVMRegNum)) {
38         OS << RegName;
39         return;
40       }
41     }
42   }
43   OS << "reg" << RegNum;
44 }
45 
46 // See DWARF standard v3, section 7.23
47 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
48 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
49 
50 Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
51                         uint64_t EndOffset) {
52   DataExtractor::Cursor C(*Offset);
53   while (C && C.tell() < EndOffset) {
54     uint8_t Opcode = Data.getRelocatedValue(C, 1);
55     if (!C)
56       break;
57 
58     // Some instructions have a primary opcode encoded in the top bits.
59     if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
60       // If it's a primary opcode, the first operand is encoded in the bottom
61       // bits of the opcode itself.
62       uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
63       switch (Primary) {
64       case DW_CFA_advance_loc:
65       case DW_CFA_restore:
66         addInstruction(Primary, Op1);
67         break;
68       case DW_CFA_offset:
69         addInstruction(Primary, Op1, Data.getULEB128(C));
70         break;
71       default:
72         llvm_unreachable("invalid primary CFI opcode");
73       }
74       continue;
75     }
76 
77     // Extended opcode - its value is Opcode itself.
78     switch (Opcode) {
79     default:
80       return createStringError(errc::illegal_byte_sequence,
81                                "invalid extended CFI opcode 0x%" PRIx8, Opcode);
82     case DW_CFA_nop:
83     case DW_CFA_remember_state:
84     case DW_CFA_restore_state:
85     case DW_CFA_GNU_window_save:
86       // No operands
87       addInstruction(Opcode);
88       break;
89     case DW_CFA_set_loc:
90       // Operands: Address
91       addInstruction(Opcode, Data.getRelocatedAddress(C));
92       break;
93     case DW_CFA_advance_loc1:
94       // Operands: 1-byte delta
95       addInstruction(Opcode, Data.getRelocatedValue(C, 1));
96       break;
97     case DW_CFA_advance_loc2:
98       // Operands: 2-byte delta
99       addInstruction(Opcode, Data.getRelocatedValue(C, 2));
100       break;
101     case DW_CFA_advance_loc4:
102       // Operands: 4-byte delta
103       addInstruction(Opcode, Data.getRelocatedValue(C, 4));
104       break;
105     case DW_CFA_restore_extended:
106     case DW_CFA_undefined:
107     case DW_CFA_same_value:
108     case DW_CFA_def_cfa_register:
109     case DW_CFA_def_cfa_offset:
110     case DW_CFA_GNU_args_size:
111       // Operands: ULEB128
112       addInstruction(Opcode, Data.getULEB128(C));
113       break;
114     case DW_CFA_def_cfa_offset_sf:
115       // Operands: SLEB128
116       addInstruction(Opcode, Data.getSLEB128(C));
117       break;
118     case DW_CFA_offset_extended:
119     case DW_CFA_register:
120     case DW_CFA_def_cfa:
121     case DW_CFA_val_offset: {
122       // Operands: ULEB128, ULEB128
123       // Note: We can not embed getULEB128 directly into function
124       // argument list. getULEB128 changes Offset and order of evaluation
125       // for arguments is unspecified.
126       uint64_t op1 = Data.getULEB128(C);
127       uint64_t op2 = Data.getULEB128(C);
128       addInstruction(Opcode, op1, op2);
129       break;
130     }
131     case DW_CFA_offset_extended_sf:
132     case DW_CFA_def_cfa_sf:
133     case DW_CFA_val_offset_sf: {
134       // Operands: ULEB128, SLEB128
135       // Note: see comment for the previous case
136       uint64_t op1 = Data.getULEB128(C);
137       uint64_t op2 = (uint64_t)Data.getSLEB128(C);
138       addInstruction(Opcode, op1, op2);
139       break;
140     }
141     case DW_CFA_def_cfa_expression: {
142       uint64_t ExprLength = Data.getULEB128(C);
143       addInstruction(Opcode, 0);
144       StringRef Expression = Data.getBytes(C, ExprLength);
145 
146       DataExtractor Extractor(Expression, Data.isLittleEndian(),
147                               Data.getAddressSize());
148       // Note. We do not pass the DWARF format to DWARFExpression, because
149       // DW_OP_call_ref, the only operation which depends on the format, is
150       // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
151       Instructions.back().Expression =
152           DWARFExpression(Extractor, Data.getAddressSize());
153       break;
154     }
155     case DW_CFA_expression:
156     case DW_CFA_val_expression: {
157       uint64_t RegNum = Data.getULEB128(C);
158       addInstruction(Opcode, RegNum, 0);
159 
160       uint64_t BlockLength = Data.getULEB128(C);
161       StringRef Expression = Data.getBytes(C, BlockLength);
162       DataExtractor Extractor(Expression, Data.isLittleEndian(),
163                               Data.getAddressSize());
164       // Note. We do not pass the DWARF format to DWARFExpression, because
165       // DW_OP_call_ref, the only operation which depends on the format, is
166       // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
167       Instructions.back().Expression =
168           DWARFExpression(Extractor, Data.getAddressSize());
169       break;
170     }
171     }
172   }
173 
174   *Offset = C.tell();
175   return C.takeError();
176 }
177 
178 namespace {
179 
180 
181 } // end anonymous namespace
182 
183 ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
184   static OperandType OpTypes[DW_CFA_restore+1][2];
185   static bool Initialized = false;
186   if (Initialized) {
187     return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
188   }
189   Initialized = true;
190 
191 #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)       \
192   do {                                          \
193     OpTypes[OP][0] = OPTYPE0;                   \
194     OpTypes[OP][1] = OPTYPE1;                   \
195   } while (false)
196 #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
197 #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
198 
199   DECLARE_OP1(DW_CFA_set_loc, OT_Address);
200   DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
201   DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
202   DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
203   DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
204   DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
205   DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
206   DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
207   DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
208   DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
209   DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
210   DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
211   DECLARE_OP1(DW_CFA_undefined, OT_Register);
212   DECLARE_OP1(DW_CFA_same_value, OT_Register);
213   DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
214   DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
215   DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
216   DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
217   DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
218   DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
219   DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
220   DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
221   DECLARE_OP1(DW_CFA_restore, OT_Register);
222   DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
223   DECLARE_OP0(DW_CFA_remember_state);
224   DECLARE_OP0(DW_CFA_restore_state);
225   DECLARE_OP0(DW_CFA_GNU_window_save);
226   DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
227   DECLARE_OP0(DW_CFA_nop);
228 
229 #undef DECLARE_OP0
230 #undef DECLARE_OP1
231 #undef DECLARE_OP2
232 
233   return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
234 }
235 
236 /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
237 void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
238                               const MCRegisterInfo *MRI, bool IsEH,
239                               const Instruction &Instr, unsigned OperandIdx,
240                               uint64_t Operand) const {
241   assert(OperandIdx < 2);
242   uint8_t Opcode = Instr.Opcode;
243   OperandType Type = getOperandTypes()[Opcode][OperandIdx];
244 
245   switch (Type) {
246   case OT_Unset: {
247     OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
248     auto OpcodeName = CallFrameString(Opcode, Arch);
249     if (!OpcodeName.empty())
250       OS << " " << OpcodeName;
251     else
252       OS << format(" Opcode %x",  Opcode);
253     break;
254   }
255   case OT_None:
256     break;
257   case OT_Address:
258     OS << format(" %" PRIx64, Operand);
259     break;
260   case OT_Offset:
261     // The offsets are all encoded in a unsigned form, but in practice
262     // consumers use them signed. It's most certainly legacy due to
263     // the lack of signed variants in the first Dwarf standards.
264     OS << format(" %+" PRId64, int64_t(Operand));
265     break;
266   case OT_FactoredCodeOffset: // Always Unsigned
267     if (CodeAlignmentFactor)
268       OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
269     else
270       OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
271     break;
272   case OT_SignedFactDataOffset:
273     if (DataAlignmentFactor)
274       OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
275     else
276       OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
277     break;
278   case OT_UnsignedFactDataOffset:
279     if (DataAlignmentFactor)
280       OS << format(" %" PRId64, Operand * DataAlignmentFactor);
281     else
282       OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
283     break;
284   case OT_Register:
285     OS << ' ';
286     printRegister(OS, MRI, IsEH, Operand);
287     break;
288   case OT_Expression:
289     assert(Instr.Expression && "missing DWARFExpression object");
290     OS << " ";
291     Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH);
292     break;
293   }
294 }
295 
296 void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
297                       const MCRegisterInfo *MRI, bool IsEH,
298                       unsigned IndentLevel) const {
299   for (const auto &Instr : Instructions) {
300     uint8_t Opcode = Instr.Opcode;
301     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
302       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
303     OS.indent(2 * IndentLevel);
304     OS << CallFrameString(Opcode, Arch) << ":";
305     for (unsigned i = 0; i < Instr.Ops.size(); ++i)
306       printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]);
307     OS << '\n';
308   }
309 }
310 
311 // Returns the CIE identifier to be used by the requested format.
312 // CIE ids for .debug_frame sections are defined in Section 7.24 of DWARFv5.
313 // For CIE ID in .eh_frame sections see
314 // https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
315 constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
316   if (IsEH)
317     return 0;
318   if (IsDWARF64)
319     return DW64_CIE_ID;
320   return DW_CIE_ID;
321 }
322 
323 void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
324                const MCRegisterInfo *MRI, bool IsEH) const {
325   // A CIE with a zero length is a terminator entry in the .eh_frame section.
326   if (IsEH && Length == 0) {
327     OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
328     return;
329   }
330 
331   OS << format("%08" PRIx64, Offset)
332      << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
333      << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8,
334                getCIEId(IsDWARF64, IsEH))
335      << " CIE\n"
336      << "  Format:                " << FormatString(IsDWARF64) << "\n"
337      << format("  Version:               %d\n", Version)
338      << "  Augmentation:          \"" << Augmentation << "\"\n";
339   if (Version >= 4) {
340     OS << format("  Address size:          %u\n", (uint32_t)AddressSize);
341     OS << format("  Segment desc size:     %u\n",
342                  (uint32_t)SegmentDescriptorSize);
343   }
344   OS << format("  Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);
345   OS << format("  Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
346   OS << format("  Return address column: %d\n", (int32_t)ReturnAddressRegister);
347   if (Personality)
348     OS << format("  Personality Address: %016" PRIx64 "\n", *Personality);
349   if (!AugmentationData.empty()) {
350     OS << "  Augmentation data:    ";
351     for (uint8_t Byte : AugmentationData)
352       OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
353     OS << "\n";
354   }
355   OS << "\n";
356   CFIs.dump(OS, DumpOpts, MRI, IsEH);
357   OS << "\n";
358 }
359 
360 void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
361                const MCRegisterInfo *MRI, bool IsEH) const {
362   OS << format("%08" PRIx64, Offset)
363      << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
364      << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
365      << " FDE cie=";
366   if (LinkedCIE)
367     OS << format("%08" PRIx64, LinkedCIE->getOffset());
368   else
369     OS << "<invalid offset>";
370   OS << format(" pc=%08" PRIx64 "...%08" PRIx64 "\n", InitialLocation,
371                InitialLocation + AddressRange);
372   OS << "  Format:       " << FormatString(IsDWARF64) << "\n";
373   if (LSDAAddress)
374     OS << format("  LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
375   CFIs.dump(OS, DumpOpts, MRI, IsEH);
376   OS << "\n";
377 }
378 
379 DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
380     bool IsEH, uint64_t EHFrameAddress)
381     : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
382 
383 DWARFDebugFrame::~DWARFDebugFrame() = default;
384 
385 static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
386                                               uint64_t Offset, int Length) {
387   errs() << "DUMP: ";
388   for (int i = 0; i < Length; ++i) {
389     uint8_t c = Data.getU8(&Offset);
390     errs().write_hex(c); errs() << " ";
391   }
392   errs() << "\n";
393 }
394 
395 Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
396   uint64_t Offset = 0;
397   DenseMap<uint64_t, CIE *> CIEs;
398 
399   while (Data.isValidOffset(Offset)) {
400     uint64_t StartOffset = Offset;
401 
402     uint64_t Length;
403     DwarfFormat Format;
404     std::tie(Length, Format) = Data.getInitialLength(&Offset);
405     bool IsDWARF64 = Format == DWARF64;
406 
407     // If the Length is 0, then this CIE is a terminator. We add it because some
408     // dumper tools might need it to print something special for such entries
409     // (e.g. llvm-objdump --dwarf=frames prints "ZERO terminator").
410     if (Length == 0) {
411       auto Cie = std::make_unique<CIE>(
412           IsDWARF64, StartOffset, 0, 0, SmallString<8>(), 0, 0, 0, 0, 0,
413           SmallString<8>(), 0, 0, None, None, Arch);
414       CIEs[StartOffset] = Cie.get();
415       Entries.push_back(std::move(Cie));
416       break;
417     }
418 
419     // At this point, Offset points to the next field after Length.
420     // Length is the structure size excluding itself. Compute an offset one
421     // past the end of the structure (needed to know how many instructions to
422     // read).
423     uint64_t StartStructureOffset = Offset;
424     uint64_t EndStructureOffset = Offset + Length;
425 
426     // The Id field's size depends on the DWARF format
427     Error Err = Error::success();
428     uint64_t Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &Offset,
429                                          /*SectionIndex=*/nullptr, &Err);
430     if (Err)
431       return Err;
432 
433     if (Id == getCIEId(IsDWARF64, IsEH)) {
434       uint8_t Version = Data.getU8(&Offset);
435       const char *Augmentation = Data.getCStr(&Offset);
436       StringRef AugmentationString(Augmentation ? Augmentation : "");
437       // TODO: we should provide a way to report a warning and continue dumping.
438       if (IsEH && Version != 1)
439         return createStringError(errc::not_supported,
440                                  "unsupported CIE version: %" PRIu8, Version);
441 
442       uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
443                                           Data.getU8(&Offset);
444       Data.setAddressSize(AddressSize);
445       uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
446       uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
447       int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
448       uint64_t ReturnAddressRegister =
449           Version == 1 ? Data.getU8(&Offset) : Data.getULEB128(&Offset);
450 
451       // Parse the augmentation data for EH CIEs
452       StringRef AugmentationData("");
453       uint32_t FDEPointerEncoding = DW_EH_PE_absptr;
454       uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
455       Optional<uint64_t> Personality;
456       Optional<uint32_t> PersonalityEncoding;
457       if (IsEH) {
458         Optional<uint64_t> AugmentationLength;
459         uint64_t StartAugmentationOffset;
460         uint64_t EndAugmentationOffset;
461 
462         // Walk the augmentation string to get all the augmentation data.
463         for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
464           switch (AugmentationString[i]) {
465           default:
466             return createStringError(
467                 errc::invalid_argument,
468                 "unknown augmentation character in entry at 0x%" PRIx64,
469                 StartOffset);
470           case 'L':
471             LSDAPointerEncoding = Data.getU8(&Offset);
472             break;
473           case 'P': {
474             if (Personality)
475               return createStringError(
476                   errc::invalid_argument,
477                   "duplicate personality in entry at 0x%" PRIx64, StartOffset);
478             PersonalityEncoding = Data.getU8(&Offset);
479             Personality = Data.getEncodedPointer(
480                 &Offset, *PersonalityEncoding,
481                 EHFrameAddress ? EHFrameAddress + Offset : 0);
482             break;
483           }
484           case 'R':
485             FDEPointerEncoding = Data.getU8(&Offset);
486             break;
487           case 'S':
488             // Current frame is a signal trampoline.
489             break;
490           case 'z':
491             if (i)
492               return createStringError(
493                   errc::invalid_argument,
494                   "'z' must be the first character at 0x%" PRIx64, StartOffset);
495             // Parse the augmentation length first.  We only parse it if
496             // the string contains a 'z'.
497             AugmentationLength = Data.getULEB128(&Offset);
498             StartAugmentationOffset = Offset;
499             EndAugmentationOffset = Offset + *AugmentationLength;
500             break;
501           case 'B':
502             // B-Key is used for signing functions associated with this
503             // augmentation string
504             break;
505           }
506         }
507 
508         if (AugmentationLength.hasValue()) {
509           if (Offset != EndAugmentationOffset)
510             return createStringError(errc::invalid_argument,
511                                      "parsing augmentation data at 0x%" PRIx64
512                                      " failed",
513                                      StartOffset);
514           AugmentationData = Data.getData().slice(StartAugmentationOffset,
515                                                   EndAugmentationOffset);
516         }
517       }
518 
519       auto Cie = std::make_unique<CIE>(
520           IsDWARF64, StartOffset, Length, Version, AugmentationString,
521           AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
522           DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
523           FDEPointerEncoding, LSDAPointerEncoding, Personality,
524           PersonalityEncoding, Arch);
525       CIEs[StartOffset] = Cie.get();
526       Entries.emplace_back(std::move(Cie));
527     } else {
528       // FDE
529       uint64_t CIEPointer = Id;
530       uint64_t InitialLocation = 0;
531       uint64_t AddressRange = 0;
532       Optional<uint64_t> LSDAAddress;
533       CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
534 
535       if (IsEH) {
536         // The address size is encoded in the CIE we reference.
537         if (!Cie)
538           return createStringError(errc::invalid_argument,
539                                    "parsing FDE data at 0x%" PRIx64
540                                    " failed due to missing CIE",
541                                    StartOffset);
542         if (auto Val =
543                 Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(),
544                                        EHFrameAddress + Offset)) {
545           InitialLocation = *Val;
546         }
547         if (auto Val = Data.getEncodedPointer(
548                 &Offset, Cie->getFDEPointerEncoding(), 0)) {
549           AddressRange = *Val;
550         }
551 
552         StringRef AugmentationString = Cie->getAugmentationString();
553         if (!AugmentationString.empty()) {
554           // Parse the augmentation length and data for this FDE.
555           uint64_t AugmentationLength = Data.getULEB128(&Offset);
556 
557           uint64_t EndAugmentationOffset = Offset + AugmentationLength;
558 
559           // Decode the LSDA if the CIE augmentation string said we should.
560           if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
561             LSDAAddress = Data.getEncodedPointer(
562                 &Offset, Cie->getLSDAPointerEncoding(),
563                 EHFrameAddress ? Offset + EHFrameAddress : 0);
564           }
565 
566           if (Offset != EndAugmentationOffset)
567             return createStringError(errc::invalid_argument,
568                                      "parsing augmentation data at 0x%" PRIx64
569                                      " failed",
570                                      StartOffset);
571         }
572       } else {
573         InitialLocation = Data.getRelocatedAddress(&Offset);
574         AddressRange = Data.getRelocatedAddress(&Offset);
575       }
576 
577       Entries.emplace_back(new FDE(IsDWARF64, StartOffset, Length, CIEPointer,
578                                    InitialLocation, AddressRange, Cie,
579                                    LSDAAddress, Arch));
580     }
581 
582     if (Error E =
583             Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset))
584       return E;
585 
586     if (Offset != EndStructureOffset)
587       return createStringError(
588           errc::invalid_argument,
589           "parsing entry instructions at 0x%" PRIx64 " failed", StartOffset);
590   }
591 
592   return Error::success();
593 }
594 
595 FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
596   auto It = partition_point(Entries, [=](const std::unique_ptr<FrameEntry> &E) {
597     return E->getOffset() < Offset;
598   });
599   if (It != Entries.end() && (*It)->getOffset() == Offset)
600     return It->get();
601   return nullptr;
602 }
603 
604 void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
605                            const MCRegisterInfo *MRI,
606                            Optional<uint64_t> Offset) const {
607   if (Offset) {
608     if (auto *Entry = getEntryAtOffset(*Offset))
609       Entry->dump(OS, DumpOpts, MRI, IsEH);
610     return;
611   }
612 
613   OS << "\n";
614   for (const auto &Entry : Entries)
615     Entry->dump(OS, DumpOpts, MRI, IsEH);
616 }
617