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