• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/Optional.h"
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/Support/Casting.h"
17 #include "llvm/Support/DataTypes.h"
18 #include "llvm/Support/Dwarf.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/Format.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 using namespace llvm;
27 using namespace dwarf;
28 
29 
30 /// \brief Abstract frame entry defining the common interface concrete
31 /// entries implement.
32 class llvm::FrameEntry {
33 public:
34   enum FrameKind {FK_CIE, FK_FDE};
FrameEntry(FrameKind K,uint64_t Offset,uint64_t Length)35   FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
36       : Kind(K), Offset(Offset), Length(Length) {}
37 
~FrameEntry()38   virtual ~FrameEntry() {
39   }
40 
getKind() const41   FrameKind getKind() const { return Kind; }
getOffset() const42   virtual uint64_t getOffset() const { return Offset; }
43 
44   /// \brief Parse and store a sequence of CFI instructions from Data,
45   /// starting at *Offset and ending at EndOffset. If everything
46   /// goes well, *Offset should be equal to EndOffset when this method
47   /// returns. Otherwise, an error occurred.
48   virtual void parseInstructions(DataExtractor Data, uint32_t *Offset,
49                                  uint32_t EndOffset);
50 
51   /// \brief Dump the entry header to the given output stream.
52   virtual void dumpHeader(raw_ostream &OS) const = 0;
53 
54   /// \brief Dump the entry's instructions to the given output stream.
55   virtual void dumpInstructions(raw_ostream &OS) const;
56 
57 protected:
58   const FrameKind Kind;
59 
60   /// \brief Offset of this entry in the section.
61   uint64_t Offset;
62 
63   /// \brief Entry length as specified in DWARF.
64   uint64_t Length;
65 
66   /// An entry may contain CFI instructions. An instruction consists of an
67   /// opcode and an optional sequence of operands.
68   typedef std::vector<uint64_t> Operands;
69   struct Instruction {
Instructionllvm::FrameEntry::Instruction70     Instruction(uint8_t Opcode)
71       : Opcode(Opcode)
72     {}
73 
74     uint8_t Opcode;
75     Operands Ops;
76   };
77 
78   std::vector<Instruction> Instructions;
79 
80   /// Convenience methods to add a new instruction with the given opcode and
81   /// operands to the Instructions vector.
addInstruction(uint8_t Opcode)82   void addInstruction(uint8_t Opcode) {
83     Instructions.push_back(Instruction(Opcode));
84   }
85 
addInstruction(uint8_t Opcode,uint64_t Operand1)86   void addInstruction(uint8_t Opcode, uint64_t Operand1) {
87     Instructions.push_back(Instruction(Opcode));
88     Instructions.back().Ops.push_back(Operand1);
89   }
90 
addInstruction(uint8_t Opcode,uint64_t Operand1,uint64_t Operand2)91   void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {
92     Instructions.push_back(Instruction(Opcode));
93     Instructions.back().Ops.push_back(Operand1);
94     Instructions.back().Ops.push_back(Operand2);
95   }
96 };
97 
98 
99 // See DWARF standard v3, section 7.23
100 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
101 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
102 
parseInstructions(DataExtractor Data,uint32_t * Offset,uint32_t EndOffset)103 void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
104                                    uint32_t EndOffset) {
105   while (*Offset < EndOffset) {
106     uint8_t Opcode = Data.getU8(Offset);
107     // Some instructions have a primary opcode encoded in the top bits.
108     uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
109 
110     if (Primary) {
111       // If it's a primary opcode, the first operand is encoded in the bottom
112       // bits of the opcode itself.
113       uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
114       switch (Primary) {
115         default: llvm_unreachable("Impossible primary CFI opcode");
116         case DW_CFA_advance_loc:
117         case DW_CFA_restore:
118           addInstruction(Primary, Op1);
119           break;
120         case DW_CFA_offset:
121           addInstruction(Primary, Op1, Data.getULEB128(Offset));
122           break;
123       }
124     } else {
125       // Extended opcode - its value is Opcode itself.
126       switch (Opcode) {
127         default: llvm_unreachable("Invalid extended CFI opcode");
128         case DW_CFA_nop:
129         case DW_CFA_remember_state:
130         case DW_CFA_restore_state:
131         case DW_CFA_GNU_window_save:
132           // No operands
133           addInstruction(Opcode);
134           break;
135         case DW_CFA_set_loc:
136           // Operands: Address
137           addInstruction(Opcode, Data.getAddress(Offset));
138           break;
139         case DW_CFA_advance_loc1:
140           // Operands: 1-byte delta
141           addInstruction(Opcode, Data.getU8(Offset));
142           break;
143         case DW_CFA_advance_loc2:
144           // Operands: 2-byte delta
145           addInstruction(Opcode, Data.getU16(Offset));
146           break;
147         case DW_CFA_advance_loc4:
148           // Operands: 4-byte delta
149           addInstruction(Opcode, Data.getU32(Offset));
150           break;
151         case DW_CFA_restore_extended:
152         case DW_CFA_undefined:
153         case DW_CFA_same_value:
154         case DW_CFA_def_cfa_register:
155         case DW_CFA_def_cfa_offset:
156           // Operands: ULEB128
157           addInstruction(Opcode, Data.getULEB128(Offset));
158           break;
159         case DW_CFA_def_cfa_offset_sf:
160           // Operands: SLEB128
161           addInstruction(Opcode, Data.getSLEB128(Offset));
162           break;
163         case DW_CFA_offset_extended:
164         case DW_CFA_register:
165         case DW_CFA_def_cfa:
166         case DW_CFA_val_offset: {
167           // Operands: ULEB128, ULEB128
168           // Note: We can not embed getULEB128 directly into function
169           // argument list. getULEB128 changes Offset and order of evaluation
170           // for arguments is unspecified.
171           auto op1 = Data.getULEB128(Offset);
172           auto op2 = Data.getULEB128(Offset);
173           addInstruction(Opcode, op1, op2);
174           break;
175         }
176         case DW_CFA_offset_extended_sf:
177         case DW_CFA_def_cfa_sf:
178         case DW_CFA_val_offset_sf: {
179           // Operands: ULEB128, SLEB128
180           // Note: see comment for the previous case
181           auto op1 = Data.getULEB128(Offset);
182           auto op2 = (uint64_t)Data.getSLEB128(Offset);
183           addInstruction(Opcode, op1, op2);
184           break;
185         }
186         case DW_CFA_def_cfa_expression:
187         case DW_CFA_expression:
188         case DW_CFA_val_expression:
189           // TODO: implement this
190           report_fatal_error("Values with expressions not implemented yet!");
191       }
192     }
193   }
194 }
195 
196 namespace {
197 /// \brief DWARF Common Information Entry (CIE)
198 class CIE : public FrameEntry {
199 public:
200   // CIEs (and FDEs) are simply container classes, so the only sensible way to
201   // create them is by providing the full parsed contents in the constructor.
CIE(uint64_t Offset,uint64_t Length,uint8_t Version,SmallString<8> Augmentation,uint8_t AddressSize,uint8_t SegmentDescriptorSize,uint64_t CodeAlignmentFactor,int64_t DataAlignmentFactor,uint64_t ReturnAddressRegister,SmallString<8> AugmentationData,uint32_t FDEPointerEncoding,uint32_t LSDAPointerEncoding)202   CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
203       SmallString<8> Augmentation, uint8_t AddressSize,
204       uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
205       int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
206       SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
207       uint32_t LSDAPointerEncoding)
208       : FrameEntry(FK_CIE, Offset, Length), Version(Version),
209         Augmentation(std::move(Augmentation)), AddressSize(AddressSize),
210         SegmentDescriptorSize(SegmentDescriptorSize),
211         CodeAlignmentFactor(CodeAlignmentFactor),
212         DataAlignmentFactor(DataAlignmentFactor),
213         ReturnAddressRegister(ReturnAddressRegister),
214         AugmentationData(std::move(AugmentationData)),
215         FDEPointerEncoding(FDEPointerEncoding),
216         LSDAPointerEncoding(LSDAPointerEncoding) {}
217 
~CIE()218   ~CIE() override {}
219 
getAugmentationString() const220   StringRef getAugmentationString() const { return Augmentation; }
getCodeAlignmentFactor() const221   uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
getDataAlignmentFactor() const222   int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
getFDEPointerEncoding() const223   uint32_t getFDEPointerEncoding() const {
224     return FDEPointerEncoding;
225   }
getLSDAPointerEncoding() const226   uint32_t getLSDAPointerEncoding() const {
227     return LSDAPointerEncoding;
228   }
229 
dumpHeader(raw_ostream & OS) const230   void dumpHeader(raw_ostream &OS) const override {
231     OS << format("%08x %08x %08x CIE",
232                  (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)
233        << "\n";
234     OS << format("  Version:               %d\n", Version);
235     OS << "  Augmentation:          \"" << Augmentation << "\"\n";
236     if (Version >= 4) {
237       OS << format("  Address size:          %u\n",
238                    (uint32_t)AddressSize);
239       OS << format("  Segment desc size:     %u\n",
240                    (uint32_t)SegmentDescriptorSize);
241     }
242     OS << format("  Code alignment factor: %u\n",
243                  (uint32_t)CodeAlignmentFactor);
244     OS << format("  Data alignment factor: %d\n",
245                  (int32_t)DataAlignmentFactor);
246     OS << format("  Return address column: %d\n",
247                  (int32_t)ReturnAddressRegister);
248     if (!AugmentationData.empty()) {
249       OS << "  Augmentation data:    ";
250       for (uint8_t Byte : AugmentationData)
251         OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
252       OS << "\n";
253     }
254     OS << "\n";
255   }
256 
classof(const FrameEntry * FE)257   static bool classof(const FrameEntry *FE) {
258     return FE->getKind() == FK_CIE;
259   }
260 
261 private:
262   /// The following fields are defined in section 6.4.1 of the DWARF standard v4
263   uint8_t Version;
264   SmallString<8> Augmentation;
265   uint8_t AddressSize;
266   uint8_t SegmentDescriptorSize;
267   uint64_t CodeAlignmentFactor;
268   int64_t DataAlignmentFactor;
269   uint64_t ReturnAddressRegister;
270 
271   // The following are used when the CIE represents an EH frame entry.
272   SmallString<8> AugmentationData;
273   uint32_t FDEPointerEncoding;
274   uint32_t LSDAPointerEncoding;
275 };
276 
277 
278 /// \brief DWARF Frame Description Entry (FDE)
279 class FDE : public FrameEntry {
280 public:
281   // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
282   // an offset to the CIE (provided by parsing the FDE header). The CIE itself
283   // is obtained lazily once it's actually required.
FDE(uint64_t Offset,uint64_t Length,int64_t LinkedCIEOffset,uint64_t InitialLocation,uint64_t AddressRange,CIE * Cie)284   FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
285       uint64_t InitialLocation, uint64_t AddressRange,
286       CIE *Cie)
287       : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
288         InitialLocation(InitialLocation), AddressRange(AddressRange),
289         LinkedCIE(Cie) {}
290 
~FDE()291   ~FDE() override {}
292 
getLinkedCIE() const293   CIE *getLinkedCIE() const { return LinkedCIE; }
294 
dumpHeader(raw_ostream & OS) const295   void dumpHeader(raw_ostream &OS) const override {
296     OS << format("%08x %08x %08x FDE ",
297                  (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset);
298     OS << format("cie=%08x pc=%08x...%08x\n",
299                  (int32_t)LinkedCIEOffset,
300                  (uint32_t)InitialLocation,
301                  (uint32_t)InitialLocation + (uint32_t)AddressRange);
302   }
303 
classof(const FrameEntry * FE)304   static bool classof(const FrameEntry *FE) {
305     return FE->getKind() == FK_FDE;
306   }
307 
308 private:
309   /// The following fields are defined in section 6.4.1 of the DWARF standard v3
310   uint64_t LinkedCIEOffset;
311   uint64_t InitialLocation;
312   uint64_t AddressRange;
313   CIE *LinkedCIE;
314 };
315 
316 /// \brief Types of operands to CF instructions.
317 enum OperandType {
318   OT_Unset,
319   OT_None,
320   OT_Address,
321   OT_Offset,
322   OT_FactoredCodeOffset,
323   OT_SignedFactDataOffset,
324   OT_UnsignedFactDataOffset,
325   OT_Register,
326   OT_Expression
327 };
328 
329 } // end anonymous namespace
330 
331 /// \brief Initialize the array describing the types of operands.
getOperandTypes()332 static ArrayRef<OperandType[2]> getOperandTypes() {
333   static OperandType OpTypes[DW_CFA_restore+1][2];
334 
335 #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)       \
336   do {                                          \
337     OpTypes[OP][0] = OPTYPE0;                   \
338     OpTypes[OP][1] = OPTYPE1;                   \
339   } while (0)
340 #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
341 #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
342 
343   DECLARE_OP1(DW_CFA_set_loc, OT_Address);
344   DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
345   DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
346   DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
347   DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
348   DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
349   DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
350   DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
351   DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
352   DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
353   DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
354   DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
355   DECLARE_OP1(DW_CFA_undefined, OT_Register);
356   DECLARE_OP1(DW_CFA_same_value, OT_Register);
357   DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
358   DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
359   DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
360   DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
361   DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
362   DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
363   DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
364   DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
365   DECLARE_OP1(DW_CFA_restore, OT_Register);
366   DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
367   DECLARE_OP0(DW_CFA_remember_state);
368   DECLARE_OP0(DW_CFA_restore_state);
369   DECLARE_OP0(DW_CFA_GNU_window_save);
370   DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
371   DECLARE_OP0(DW_CFA_nop);
372 
373 #undef DECLARE_OP0
374 #undef DECLARE_OP1
375 #undef DECLARE_OP2
376   return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
377 }
378 
379 static ArrayRef<OperandType[2]> OpTypes = getOperandTypes();
380 
381 /// \brief Print \p Opcode's operand number \p OperandIdx which has
382 /// value \p Operand.
printOperand(raw_ostream & OS,uint8_t Opcode,unsigned OperandIdx,uint64_t Operand,uint64_t CodeAlignmentFactor,int64_t DataAlignmentFactor)383 static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx,
384                          uint64_t Operand, uint64_t CodeAlignmentFactor,
385                          int64_t DataAlignmentFactor) {
386   assert(OperandIdx < 2);
387   OperandType Type = OpTypes[Opcode][OperandIdx];
388 
389   switch (Type) {
390   case OT_Unset:
391     OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
392     if (const char *OpcodeName = CallFrameString(Opcode))
393       OS << " " << OpcodeName;
394     else
395       OS << format(" Opcode %x",  Opcode);
396     break;
397   case OT_None:
398     break;
399   case OT_Address:
400     OS << format(" %" PRIx64, Operand);
401     break;
402   case OT_Offset:
403     // The offsets are all encoded in a unsigned form, but in practice
404     // consumers use them signed. It's most certainly legacy due to
405     // the lack of signed variants in the first Dwarf standards.
406     OS << format(" %+" PRId64, int64_t(Operand));
407     break;
408   case OT_FactoredCodeOffset: // Always Unsigned
409     if (CodeAlignmentFactor)
410       OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
411     else
412       OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
413     break;
414   case OT_SignedFactDataOffset:
415     if (DataAlignmentFactor)
416       OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
417     else
418       OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
419     break;
420   case OT_UnsignedFactDataOffset:
421     if (DataAlignmentFactor)
422       OS << format(" %" PRId64, Operand * DataAlignmentFactor);
423     else
424       OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
425     break;
426   case OT_Register:
427     OS << format(" reg%" PRId64, Operand);
428     break;
429   case OT_Expression:
430     OS << " expression";
431     break;
432   }
433 }
434 
dumpInstructions(raw_ostream & OS) const435 void FrameEntry::dumpInstructions(raw_ostream &OS) const {
436   uint64_t CodeAlignmentFactor = 0;
437   int64_t DataAlignmentFactor = 0;
438   const CIE *Cie = dyn_cast<CIE>(this);
439 
440   if (!Cie)
441     Cie = cast<FDE>(this)->getLinkedCIE();
442   if (Cie) {
443     CodeAlignmentFactor = Cie->getCodeAlignmentFactor();
444     DataAlignmentFactor = Cie->getDataAlignmentFactor();
445   }
446 
447   for (const auto &Instr : Instructions) {
448     uint8_t Opcode = Instr.Opcode;
449     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
450       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
451     OS << "  " << CallFrameString(Opcode) << ":";
452     for (unsigned i = 0; i < Instr.Ops.size(); ++i)
453       printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor,
454                    DataAlignmentFactor);
455     OS << '\n';
456   }
457 }
458 
DWARFDebugFrame(bool IsEH)459 DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {
460 }
461 
~DWARFDebugFrame()462 DWARFDebugFrame::~DWARFDebugFrame() {
463 }
464 
dumpDataAux(DataExtractor Data,uint32_t Offset,int Length)465 static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
466                                               uint32_t Offset, int Length) {
467   errs() << "DUMP: ";
468   for (int i = 0; i < Length; ++i) {
469     uint8_t c = Data.getU8(&Offset);
470     errs().write_hex(c); errs() << " ";
471   }
472   errs() << "\n";
473 }
474 
getSizeForEncoding(const DataExtractor & Data,unsigned symbolEncoding)475 static unsigned getSizeForEncoding(const DataExtractor &Data,
476                                    unsigned symbolEncoding) {
477   unsigned format = symbolEncoding & 0x0f;
478   switch (format) {
479     default: llvm_unreachable("Unknown Encoding");
480     case dwarf::DW_EH_PE_absptr:
481     case dwarf::DW_EH_PE_signed:
482       return Data.getAddressSize();
483     case dwarf::DW_EH_PE_udata2:
484     case dwarf::DW_EH_PE_sdata2:
485       return 2;
486     case dwarf::DW_EH_PE_udata4:
487     case dwarf::DW_EH_PE_sdata4:
488       return 4;
489     case dwarf::DW_EH_PE_udata8:
490     case dwarf::DW_EH_PE_sdata8:
491       return 8;
492   }
493 }
494 
readPointer(const DataExtractor & Data,uint32_t & Offset,unsigned Encoding)495 static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset,
496                             unsigned Encoding) {
497   switch (getSizeForEncoding(Data, Encoding)) {
498     case 2:
499       return Data.getU16(&Offset);
500     case 4:
501       return Data.getU32(&Offset);
502     case 8:
503       return Data.getU64(&Offset);
504     default:
505       llvm_unreachable("Illegal data size");
506   }
507 }
508 
parse(DataExtractor Data)509 void DWARFDebugFrame::parse(DataExtractor Data) {
510   uint32_t Offset = 0;
511   DenseMap<uint32_t, CIE *> CIEs;
512 
513   while (Data.isValidOffset(Offset)) {
514     uint32_t StartOffset = Offset;
515 
516     auto ReportError = [StartOffset](const char *ErrorMsg) {
517       std::string Str;
518       raw_string_ostream OS(Str);
519       OS << format(ErrorMsg, StartOffset);
520       OS.flush();
521       report_fatal_error(Str);
522     };
523 
524     bool IsDWARF64 = false;
525     uint64_t Length = Data.getU32(&Offset);
526     uint64_t Id;
527 
528     if (Length == UINT32_MAX) {
529       // DWARF-64 is distinguished by the first 32 bits of the initial length
530       // field being 0xffffffff. Then, the next 64 bits are the actual entry
531       // length.
532       IsDWARF64 = true;
533       Length = Data.getU64(&Offset);
534     }
535 
536     // At this point, Offset points to the next field after Length.
537     // Length is the structure size excluding itself. Compute an offset one
538     // past the end of the structure (needed to know how many instructions to
539     // read).
540     // TODO: For honest DWARF64 support, DataExtractor will have to treat
541     //       offset_ptr as uint64_t*
542     uint32_t StartStructureOffset = Offset;
543     uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
544 
545     // The Id field's size depends on the DWARF format
546     Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
547     bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) ||
548                   Id == DW_CIE_ID ||
549                   (IsEH && !Id));
550 
551     if (IsCIE) {
552       uint8_t Version = Data.getU8(&Offset);
553       const char *Augmentation = Data.getCStr(&Offset);
554       StringRef AugmentationString(Augmentation ? Augmentation : "");
555       uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
556                                           Data.getU8(&Offset);
557       Data.setAddressSize(AddressSize);
558       uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
559       uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
560       int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
561       uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
562 
563       // Parse the augmentation data for EH CIEs
564       StringRef AugmentationData("");
565       uint32_t FDEPointerEncoding = DW_EH_PE_omit;
566       uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
567       if (IsEH) {
568         Optional<uint32_t> PersonalityEncoding;
569         Optional<uint64_t> Personality;
570 
571         Optional<uint64_t> AugmentationLength;
572         uint32_t StartAugmentationOffset;
573         uint32_t EndAugmentationOffset;
574 
575         // Walk the augmentation string to get all the augmentation data.
576         for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
577           switch (AugmentationString[i]) {
578             default:
579               ReportError("Unknown augmentation character in entry at %lx");
580             case 'L':
581               LSDAPointerEncoding = Data.getU8(&Offset);
582               break;
583             case 'P': {
584               if (Personality)
585                 ReportError("Duplicate personality in entry at %lx");
586               PersonalityEncoding = Data.getU8(&Offset);
587               Personality = readPointer(Data, Offset, *PersonalityEncoding);
588               break;
589             }
590             case 'R':
591               FDEPointerEncoding = Data.getU8(&Offset);
592               break;
593             case 'z':
594               if (i)
595                 ReportError("'z' must be the first character at %lx");
596               // Parse the augmentation length first.  We only parse it if
597               // the string contains a 'z'.
598               AugmentationLength = Data.getULEB128(&Offset);
599               StartAugmentationOffset = Offset;
600               EndAugmentationOffset = Offset +
601                 static_cast<uint32_t>(*AugmentationLength);
602           }
603         }
604 
605         if (AugmentationLength.hasValue()) {
606           if (Offset != EndAugmentationOffset)
607             ReportError("Parsing augmentation data at %lx failed");
608 
609           AugmentationData = Data.getData().slice(StartAugmentationOffset,
610                                                   EndAugmentationOffset);
611         }
612       }
613 
614       auto Cie = make_unique<CIE>(StartOffset, Length, Version,
615                                   AugmentationString, AddressSize,
616                                   SegmentDescriptorSize, CodeAlignmentFactor,
617                                   DataAlignmentFactor, ReturnAddressRegister,
618                                   AugmentationData, FDEPointerEncoding,
619                                   LSDAPointerEncoding);
620       CIEs[StartOffset] = Cie.get();
621       Entries.emplace_back(std::move(Cie));
622     } else {
623       // FDE
624       uint64_t CIEPointer = Id;
625       uint64_t InitialLocation = 0;
626       uint64_t AddressRange = 0;
627       CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
628 
629       if (IsEH) {
630         // The address size is encoded in the CIE we reference.
631         if (!Cie)
632           ReportError("Parsing FDE data at %lx failed due to missing CIE");
633 
634         InitialLocation = readPointer(Data, Offset,
635                                       Cie->getFDEPointerEncoding());
636         AddressRange = readPointer(Data, Offset,
637                                    Cie->getFDEPointerEncoding());
638 
639         StringRef AugmentationString = Cie->getAugmentationString();
640         if (!AugmentationString.empty()) {
641           // Parse the augmentation length and data for this FDE.
642           uint64_t AugmentationLength = Data.getULEB128(&Offset);
643 
644           uint32_t EndAugmentationOffset =
645             Offset + static_cast<uint32_t>(AugmentationLength);
646 
647           // Decode the LSDA if the CIE augmentation string said we should.
648           if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit)
649             readPointer(Data, Offset, Cie->getLSDAPointerEncoding());
650 
651           if (Offset != EndAugmentationOffset)
652             ReportError("Parsing augmentation data at %lx failed");
653         }
654       } else {
655         InitialLocation = Data.getAddress(&Offset);
656         AddressRange = Data.getAddress(&Offset);
657       }
658 
659       Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
660                                    InitialLocation, AddressRange,
661                                    Cie));
662     }
663 
664     Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
665 
666     if (Offset != EndStructureOffset)
667       ReportError("Parsing entry instructions at %lx failed");
668   }
669 }
670 
671 
dump(raw_ostream & OS) const672 void DWARFDebugFrame::dump(raw_ostream &OS) const {
673   OS << "\n";
674   for (const auto &Entry : Entries) {
675     Entry->dumpHeader(OS);
676     Entry->dumpInstructions(OS);
677     OS << "\n";
678   }
679 }
680 
681