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
29using namespace llvm;
30using namespace dwarf;
31
32
33// See DWARF standard v3, section 7.23
34const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
35const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
36
37Error 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
165namespace {
166
167
168} // end anonymous namespace
169
170ArrayRef<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.
224void 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
281void 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
299constexpr 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
307void 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
343void 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
361DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
362    bool IsEH, uint64_t EHFrameAddress)
363    : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
364
365DWARFDebugFrame::~DWARFDebugFrame() = default;
366
367static 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
377Error 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
577FrameEntry *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
586void 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