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