LLVM  8.0.1
DWARFDebugFrame.h
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 
10 #ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
11 #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
12 
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/iterator.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/Error.h"
20 #include <memory>
21 #include <vector>
22 
23 namespace llvm {
24 
25 class raw_ostream;
26 
27 namespace dwarf {
28 
29 /// Represent a sequence of Call Frame Information instructions that, when read
30 /// in order, construct a table mapping PC to frame state. This can also be
31 /// referred to as "CFI rules" in DWARF literature to avoid confusion with
32 /// computer programs in the broader sense, and in this context each instruction
33 /// would be a rule to establish the mapping. Refer to pg. 172 in the DWARF5
34 /// manual, "6.4.1 Structure of Call Frame Information".
35 class CFIProgram {
36 public:
38 
39  /// An instruction consists of a DWARF CFI opcode and an optional sequence of
40  /// operands. If it refers to an expression, then this expression has its own
41  /// sequence of operations and operands handled separately by DWARFExpression.
42  struct Instruction {
43  Instruction(uint8_t Opcode) : Opcode(Opcode) {}
44 
45  uint8_t Opcode;
46  Operands Ops;
47  // Associated DWARF expression in case this instruction refers to one
49  };
50 
51  using InstrList = std::vector<Instruction>;
52  using iterator = InstrList::iterator;
53  using const_iterator = InstrList::const_iterator;
54 
55  iterator begin() { return Instructions.begin(); }
56  const_iterator begin() const { return Instructions.begin(); }
57  iterator end() { return Instructions.end(); }
58  const_iterator end() const { return Instructions.end(); }
59 
60  unsigned size() const { return (unsigned)Instructions.size(); }
61  bool empty() const { return Instructions.empty(); }
62 
63  CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor,
64  Triple::ArchType Arch)
65  : CodeAlignmentFactor(CodeAlignmentFactor),
66  DataAlignmentFactor(DataAlignmentFactor),
67  Arch(Arch) {}
68 
69  /// Parse and store a sequence of CFI instructions from Data,
70  /// starting at *Offset and ending at EndOffset. *Offset is updated
71  /// to EndOffset upon successful parsing, or indicates the offset
72  /// where a problem occurred in case an error is returned.
74 
75  void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
76  unsigned IndentLevel = 1) const;
77 
78 private:
79  std::vector<Instruction> Instructions;
80  const uint64_t CodeAlignmentFactor;
81  const int64_t DataAlignmentFactor;
82  Triple::ArchType Arch;
83 
84  /// Convenience method to add a new instruction with the given opcode.
85  void addInstruction(uint8_t Opcode) {
86  Instructions.push_back(Instruction(Opcode));
87  }
88 
89  /// Add a new single-operand instruction.
90  void addInstruction(uint8_t Opcode, uint64_t Operand1) {
91  Instructions.push_back(Instruction(Opcode));
92  Instructions.back().Ops.push_back(Operand1);
93  }
94 
95  /// Add a new instruction that has two operands.
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  /// Types of operands to CFI instructions
103  /// In DWARF, this type is implicitly tied to a CFI instruction opcode and
104  /// thus this type doesn't need to be explictly written to the file (this is
105  /// not a DWARF encoding). The relationship of instrs to operand types can
106  /// be obtained from getOperandTypes() and is only used to simplify
107  /// instruction printing.
108  enum OperandType {
109  OT_Unset,
110  OT_None,
111  OT_Address,
112  OT_Offset,
113  OT_FactoredCodeOffset,
114  OT_SignedFactDataOffset,
115  OT_UnsignedFactDataOffset,
116  OT_Register,
117  OT_Expression
118  };
119 
120  /// Retrieve the array describing the types of operands according to the enum
121  /// above. This is indexed by opcode.
122  static ArrayRef<OperandType[2]> getOperandTypes();
123 
124  /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
125  void printOperand(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
126  const Instruction &Instr, unsigned OperandIdx,
127  uint64_t Operand) const;
128 };
129 
130 /// An entry in either debug_frame or eh_frame. This entry can be a CIE or an
131 /// FDE.
132 class FrameEntry {
133 public:
134  enum FrameKind { FK_CIE, FK_FDE };
135 
136  FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign,
137  int64_t DataAlign, Triple::ArchType Arch)
138  : Kind(K), Offset(Offset), Length(Length),
139  CFIs(CodeAlign, DataAlign, Arch) {}
140 
141  virtual ~FrameEntry() {}
142 
143  FrameKind getKind() const { return Kind; }
144  uint64_t getOffset() const { return Offset; }
145  uint64_t getLength() const { return Length; }
146  const CFIProgram &cfis() const { return CFIs; }
147  CFIProgram &cfis() { return CFIs; }
148 
149  /// Dump the instructions in this CFI fragment
150  virtual void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
151  bool IsEH) const = 0;
152 
153 protected:
155 
156  /// Offset of this entry in the section.
157  const uint64_t Offset;
158 
159  /// Entry length as specified in DWARF.
160  const uint64_t Length;
161 
163 };
164 
165 /// DWARF Common Information Entry (CIE)
166 class CIE : public FrameEntry {
167 public:
168  // CIEs (and FDEs) are simply container classes, so the only sensible way to
169  // create them is by providing the full parsed contents in the constructor.
170  CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
171  SmallString<8> Augmentation, uint8_t AddressSize,
172  uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
173  int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
174  SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
175  uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality,
176  Optional<uint32_t> PersonalityEnc, Triple::ArchType Arch)
177  : FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor,
178  DataAlignmentFactor, Arch),
179  Version(Version), Augmentation(std::move(Augmentation)),
180  AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
181  CodeAlignmentFactor(CodeAlignmentFactor),
182  DataAlignmentFactor(DataAlignmentFactor),
183  ReturnAddressRegister(ReturnAddressRegister),
184  AugmentationData(std::move(AugmentationData)),
185  FDEPointerEncoding(FDEPointerEncoding),
186  LSDAPointerEncoding(LSDAPointerEncoding), Personality(Personality),
187  PersonalityEnc(PersonalityEnc) {}
188 
189  static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_CIE; }
190 
191  StringRef getAugmentationString() const { return Augmentation; }
192  uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
193  int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
194  uint8_t getVersion() const { return Version; }
195  uint64_t getReturnAddressRegister() const { return ReturnAddressRegister; }
196  Optional<uint64_t> getPersonalityAddress() const { return Personality; }
197  Optional<uint32_t> getPersonalityEncoding() const { return PersonalityEnc; }
198 
199  uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; }
200 
201  uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }
202 
203  void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
204  bool IsEH) const override;
205 
206 private:
207  /// The following fields are defined in section 6.4.1 of the DWARF standard v4
208  const uint8_t Version;
209  const SmallString<8> Augmentation;
210  const uint8_t AddressSize;
211  const uint8_t SegmentDescriptorSize;
212  const uint64_t CodeAlignmentFactor;
213  const int64_t DataAlignmentFactor;
214  const uint64_t ReturnAddressRegister;
215 
216  // The following are used when the CIE represents an EH frame entry.
217  const SmallString<8> AugmentationData;
218  const uint32_t FDEPointerEncoding;
219  const uint32_t LSDAPointerEncoding;
220  const Optional<uint64_t> Personality;
221  const Optional<uint32_t> PersonalityEnc;
222 };
223 
224 /// DWARF Frame Description Entry (FDE)
225 class FDE : public FrameEntry {
226 public:
227  // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
228  // an offset to the CIE (provided by parsing the FDE header). The CIE itself
229  // is obtained lazily once it's actually required.
230  FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
231  uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
232  Optional<uint64_t> LSDAAddress, Triple::ArchType Arch)
233  : FrameEntry(FK_FDE, Offset, Length,
234  Cie ? Cie->getCodeAlignmentFactor() : 0,
235  Cie ? Cie->getDataAlignmentFactor() : 0,
236  Arch),
237  LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation),
238  AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
239 
240  ~FDE() override = default;
241 
242  const CIE *getLinkedCIE() const { return LinkedCIE; }
243  uint64_t getInitialLocation() const { return InitialLocation; }
244  uint64_t getAddressRange() const { return AddressRange; }
245  Optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }
246 
247  void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
248  bool IsEH) const override;
249 
250  static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
251 
252 private:
253  /// The following fields are defined in section 6.4.1 of the DWARF standard v3
254  const uint64_t LinkedCIEOffset;
255  const uint64_t InitialLocation;
256  const uint64_t AddressRange;
257  const CIE *LinkedCIE;
258  const Optional<uint64_t> LSDAAddress;
259 };
260 
261 } // end namespace dwarf
262 
263 /// A parsed .debug_frame or .eh_frame section
265  const Triple::ArchType Arch;
266  // True if this is parsing an eh_frame section.
267  const bool IsEH;
268  // Not zero for sane pointer values coming out of eh_frame
269  const uint64_t EHFrameAddress;
270 
271  std::vector<std::unique_ptr<dwarf::FrameEntry>> Entries;
273 
274  /// Return the entry at the given offset or nullptr.
275  dwarf::FrameEntry *getEntryAtOffset(uint64_t Offset) const;
276 
277 public:
278  // If IsEH is true, assume it is a .eh_frame section. Otherwise,
279  // it is a .debug_frame section. EHFrameAddress should be different
280  // than zero for correct parsing of .eh_frame addresses when they
281  // use a PC-relative encoding.
283  bool IsEH = false, uint64_t EHFrameAddress = 0);
284  ~DWARFDebugFrame();
285 
286  /// Dump the section data into the given stream.
287  void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
288  Optional<uint64_t> Offset) const;
289 
290  /// Parse the section from raw data. \p Data is assumed to contain the whole
291  /// frame section contents to be parsed.
293 
294  /// Return whether the section has any entries.
295  bool empty() const { return Entries.empty(); }
296 
297  /// DWARF Frame entries accessors
298  iterator begin() const { return Entries.begin(); }
299  iterator end() const { return Entries.end(); }
301  return iterator_range<iterator>(Entries.begin(), Entries.end());
302  }
303 
304  uint64_t getEHFrameAddress() const { return EHFrameAddress; }
305 };
306 
307 } // end namespace llvm
308 
309 #endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
int64_t getDataAlignmentFactor() const
iterator_range< iterator > entries() const
static int getDataAlignmentFactor(MCStreamer &streamer)
Definition: MCDwarf.cpp:1229
InstrList::iterator iterator
iterator begin() const
DWARF Frame entries accessors.
InstrList::const_iterator const_iterator
static bool classof(const FrameEntry *FE)
A parsed .debug_frame or .eh_frame section.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
Optional< uint64_t > getPersonalityAddress() const
FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie, Optional< uint64_t > LSDAAddress, Triple::ArchType Arch)
Error parse(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...
An entry in either debug_frame or eh_frame.
uint8_t getVersion() const
uint64_t getEHFrameAddress() const
iterator end() const
uint32_t getLSDAPointerEncoding() const
uint64_t getCodeAlignmentFactor() const
Definition: BitVector.h:938
uint64_t getInitialLocation() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor, Triple::ArchType Arch)
unsigned const MachineRegisterInfo * MRI
DWARF Frame Description Entry (FDE)
unsigned size() const
uint32_t getFDEPointerEncoding() const
const uint64_t Offset
Offset of this entry in the section.
uint64_t getLength() const
Represent a sequence of Call Frame Information instructions that, when read in order, construct a table mapping PC to frame state.
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, Optional< uint64_t > Personality, Optional< uint32_t > PersonalityEnc, Triple::ArchType Arch)
static bool classof(const FrameEntry *FE)
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, unsigned IndentLevel=1) const
const CIE * getLinkedCIE() const
Optional< uint32_t > getPersonalityEncoding() const
std::vector< Instruction > InstrList
bool empty() const
Return whether the section has any entries.
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
An iterator type that allows iterating over the pointees via some other iterator. ...
Definition: iterator.h:287
DWARF Common Information Entry (CIE)
SmallVector< uint64_t, 2 > Operands
A range adaptor for a pair of iterators.
const_iterator end() const
const CFIProgram & cfis() const
StringRef getAugmentationString() const
const uint64_t Length
Entry length as specified in DWARF.
FrameKind getKind() const
Optional< uint64_t > getLSDAAddress() const
An instruction consists of a DWARF CFI opcode and an optional sequence of operands.
const unsigned Kind
uint64_t getOffset() const
const_iterator begin() const
FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign, int64_t DataAlign, Triple::ArchType Arch)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
Optional< DWARFExpression > Expression
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
const uint64_t Version
Definition: InstrProf.h:895
uint64_t getReturnAddressRegister() const
uint64_t getAddressRange() const