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