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