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