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, const MCRegisterInfo *MRI,
238                               bool IsEH, const Instruction &Instr,
239                               unsigned OperandIdx, 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, MRI, nullptr, IsEH);
291     break;
292   }
293 }
294 
295 void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
296                       unsigned IndentLevel) const {
297   for (const auto &Instr : Instructions) {
298     uint8_t Opcode = Instr.Opcode;
299     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
300       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
301     OS.indent(2 * IndentLevel);
302     OS << CallFrameString(Opcode, Arch) << ":";
303     for (unsigned i = 0; i < Instr.Ops.size(); ++i)
304       printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
305     OS << '\n';
306   }
307 }
308 
309 // Returns the CIE identifier to be used by the requested format.
310 // CIE ids for .debug_frame sections are defined in Section 7.24 of DWARFv5.
311 // For CIE ID in .eh_frame sections see
312 // https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
313 constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
314   if (IsEH)
315     return 0;
316   if (IsDWARF64)
317     return DW64_CIE_ID;
318   return DW_CIE_ID;
319 }
320 
321 void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
322   // A CIE with a zero length is a terminator entry in the .eh_frame section.
323   if (IsEH && Length == 0) {
324     OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
325     return;
326   }
327 
328   OS << format("%08" PRIx64, Offset)
329      << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
330      << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8,
331                getCIEId(IsDWARF64, IsEH))
332      << " CIE\n"
333      << "  Format:                " << FormatString(IsDWARF64) << "\n"
334      << format("  Version:               %d\n", Version)
335      << "  Augmentation:          \"" << Augmentation << "\"\n";
336   if (Version >= 4) {
337     OS << format("  Address size:          %u\n", (uint32_t)AddressSize);
338     OS << format("  Segment desc size:     %u\n",
339                  (uint32_t)SegmentDescriptorSize);
340   }
341   OS << format("  Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);
342   OS << format("  Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
343   OS << format("  Return address column: %d\n", (int32_t)ReturnAddressRegister);
344   if (Personality)
345     OS << format("  Personality Address: %016" PRIx64 "\n", *Personality);
346   if (!AugmentationData.empty()) {
347     OS << "  Augmentation data:    ";
348     for (uint8_t Byte : AugmentationData)
349       OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
350     OS << "\n";
351   }
352   OS << "\n";
353   CFIs.dump(OS, MRI, IsEH);
354   OS << "\n";
355 }
356 
357 void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
358   OS << format("%08" PRIx64, Offset)
359      << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
360      << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
361      << " FDE cie=";
362   if (LinkedCIE)
363     OS << format("%08" PRIx64, LinkedCIE->getOffset());
364   else
365     OS << "<invalid offset>";
366   OS << format(" pc=%08" PRIx64 "...%08" PRIx64 "\n", InitialLocation,
367                InitialLocation + AddressRange);
368   OS << "  Format:       " << FormatString(IsDWARF64) << "\n";
369   if (LSDAAddress)
370     OS << format("  LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
371   CFIs.dump(OS, MRI, IsEH);
372   OS << "\n";
373 }
374 
375 DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
376     bool IsEH, uint64_t EHFrameAddress)
377     : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
378 
379 DWARFDebugFrame::~DWARFDebugFrame() = default;
380 
381 static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
382                                               uint64_t Offset, int Length) {
383   errs() << "DUMP: ";
384   for (int i = 0; i < Length; ++i) {
385     uint8_t c = Data.getU8(&Offset);
386     errs().write_hex(c); errs() << " ";
387   }
388   errs() << "\n";
389 }
390 
391 Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
392   uint64_t Offset = 0;
393   DenseMap<uint64_t, CIE *> CIEs;
394 
395   while (Data.isValidOffset(Offset)) {
396     uint64_t StartOffset = Offset;
397 
398     uint64_t Length;
399     DwarfFormat Format;
400     std::tie(Length, Format) = Data.getInitialLength(&Offset);
401     bool IsDWARF64 = Format == DWARF64;
402 
403     // If the Length is 0, then this CIE is a terminator. We add it because some
404     // dumper tools might need it to print something special for such entries
405     // (e.g. llvm-objdump --dwarf=frames prints "ZERO terminator").
406     if (Length == 0) {
407       auto Cie = std::make_unique<CIE>(
408           IsDWARF64, StartOffset, 0, 0, SmallString<8>(), 0, 0, 0, 0, 0,
409           SmallString<8>(), 0, 0, None, None, Arch);
410       CIEs[StartOffset] = Cie.get();
411       Entries.push_back(std::move(Cie));
412       break;
413     }
414 
415     // At this point, Offset points to the next field after Length.
416     // Length is the structure size excluding itself. Compute an offset one
417     // past the end of the structure (needed to know how many instructions to
418     // read).
419     uint64_t StartStructureOffset = Offset;
420     uint64_t EndStructureOffset = Offset + Length;
421 
422     // The Id field's size depends on the DWARF format
423     Error Err = Error::success();
424     uint64_t Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &Offset,
425                                          /*SectionIndex=*/nullptr, &Err);
426     if (Err)
427       return Err;
428 
429     if (Id == getCIEId(IsDWARF64, IsEH)) {
430       uint8_t Version = Data.getU8(&Offset);
431       const char *Augmentation = Data.getCStr(&Offset);
432       StringRef AugmentationString(Augmentation ? Augmentation : "");
433       // TODO: we should provide a way to report a warning and continue dumping.
434       if (IsEH && Version != 1)
435         return createStringError(errc::not_supported,
436                                  "unsupported CIE version: %" PRIu8, Version);
437 
438       uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
439                                           Data.getU8(&Offset);
440       Data.setAddressSize(AddressSize);
441       uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
442       uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
443       int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
444       uint64_t ReturnAddressRegister =
445           Version == 1 ? Data.getU8(&Offset) : Data.getULEB128(&Offset);
446 
447       // Parse the augmentation data for EH CIEs
448       StringRef AugmentationData("");
449       uint32_t FDEPointerEncoding = DW_EH_PE_absptr;
450       uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
451       Optional<uint64_t> Personality;
452       Optional<uint32_t> PersonalityEncoding;
453       if (IsEH) {
454         Optional<uint64_t> AugmentationLength;
455         uint64_t StartAugmentationOffset;
456         uint64_t EndAugmentationOffset;
457 
458         // Walk the augmentation string to get all the augmentation data.
459         for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
460           switch (AugmentationString[i]) {
461           default:
462             return createStringError(
463                 errc::invalid_argument,
464                 "unknown augmentation character in entry at 0x%" PRIx64,
465                 StartOffset);
466           case 'L':
467             LSDAPointerEncoding = Data.getU8(&Offset);
468             break;
469           case 'P': {
470             if (Personality)
471               return createStringError(
472                   errc::invalid_argument,
473                   "duplicate personality in entry at 0x%" PRIx64, StartOffset);
474             PersonalityEncoding = Data.getU8(&Offset);
475             Personality = Data.getEncodedPointer(
476                 &Offset, *PersonalityEncoding,
477                 EHFrameAddress ? EHFrameAddress + Offset : 0);
478             break;
479           }
480           case 'R':
481             FDEPointerEncoding = Data.getU8(&Offset);
482             break;
483           case 'S':
484             // Current frame is a signal trampoline.
485             break;
486           case 'z':
487             if (i)
488               return createStringError(
489                   errc::invalid_argument,
490                   "'z' must be the first character at 0x%" PRIx64, StartOffset);
491             // Parse the augmentation length first.  We only parse it if
492             // the string contains a 'z'.
493             AugmentationLength = Data.getULEB128(&Offset);
494             StartAugmentationOffset = Offset;
495             EndAugmentationOffset = Offset + *AugmentationLength;
496             break;
497           case 'B':
498             // B-Key is used for signing functions associated with this
499             // augmentation string
500             break;
501           }
502         }
503 
504         if (AugmentationLength.hasValue()) {
505           if (Offset != EndAugmentationOffset)
506             return createStringError(errc::invalid_argument,
507                                      "parsing augmentation data at 0x%" PRIx64
508                                      " failed",
509                                      StartOffset);
510           AugmentationData = Data.getData().slice(StartAugmentationOffset,
511                                                   EndAugmentationOffset);
512         }
513       }
514 
515       auto Cie = std::make_unique<CIE>(
516           IsDWARF64, StartOffset, Length, Version, AugmentationString,
517           AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
518           DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
519           FDEPointerEncoding, LSDAPointerEncoding, Personality,
520           PersonalityEncoding, Arch);
521       CIEs[StartOffset] = Cie.get();
522       Entries.emplace_back(std::move(Cie));
523     } else {
524       // FDE
525       uint64_t CIEPointer = Id;
526       uint64_t InitialLocation = 0;
527       uint64_t AddressRange = 0;
528       Optional<uint64_t> LSDAAddress;
529       CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
530 
531       if (IsEH) {
532         // The address size is encoded in the CIE we reference.
533         if (!Cie)
534           return createStringError(errc::invalid_argument,
535                                    "parsing FDE data at 0x%" PRIx64
536                                    " failed due to missing CIE",
537                                    StartOffset);
538         if (auto Val =
539                 Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(),
540                                        EHFrameAddress + Offset)) {
541           InitialLocation = *Val;
542         }
543         if (auto Val = Data.getEncodedPointer(
544                 &Offset, Cie->getFDEPointerEncoding(), 0)) {
545           AddressRange = *Val;
546         }
547 
548         StringRef AugmentationString = Cie->getAugmentationString();
549         if (!AugmentationString.empty()) {
550           // Parse the augmentation length and data for this FDE.
551           uint64_t AugmentationLength = Data.getULEB128(&Offset);
552 
553           uint64_t EndAugmentationOffset = Offset + AugmentationLength;
554 
555           // Decode the LSDA if the CIE augmentation string said we should.
556           if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
557             LSDAAddress = Data.getEncodedPointer(
558                 &Offset, Cie->getLSDAPointerEncoding(),
559                 EHFrameAddress ? Offset + EHFrameAddress : 0);
560           }
561 
562           if (Offset != EndAugmentationOffset)
563             return createStringError(errc::invalid_argument,
564                                      "parsing augmentation data at 0x%" PRIx64
565                                      " failed",
566                                      StartOffset);
567         }
568       } else {
569         InitialLocation = Data.getRelocatedAddress(&Offset);
570         AddressRange = Data.getRelocatedAddress(&Offset);
571       }
572 
573       Entries.emplace_back(new FDE(IsDWARF64, StartOffset, Length, CIEPointer,
574                                    InitialLocation, AddressRange, Cie,
575                                    LSDAAddress, Arch));
576     }
577 
578     if (Error E =
579             Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset))
580       return E;
581 
582     if (Offset != EndStructureOffset)
583       return createStringError(
584           errc::invalid_argument,
585           "parsing entry instructions at 0x%" PRIx64 " failed", StartOffset);
586   }
587 
588   return Error::success();
589 }
590 
591 FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
592   auto It = partition_point(Entries, [=](const std::unique_ptr<FrameEntry> &E) {
593     return E->getOffset() < Offset;
594   });
595   if (It != Entries.end() && (*It)->getOffset() == Offset)
596     return It->get();
597   return nullptr;
598 }
599 
600 void DWARFDebugFrame::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
601                            Optional<uint64_t> Offset) const {
602   if (Offset) {
603     if (auto *Entry = getEntryAtOffset(*Offset))
604       Entry->dump(OS, MRI, IsEH);
605     return;
606   }
607 
608   OS << "\n";
609   for (const auto &Entry : Entries)
610     Entry->dump(OS, MRI, IsEH);
611 }
612