xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h (revision af23369a6deaaeb612ab266eb88b8bb8d560c322)
1 //===- DWARFDebugFrame.h - Parsing of .debug_frame --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
10 #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/Triple.h"
15 #include "llvm/ADT/iterator.h"
16 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
17 #include "llvm/Support/Error.h"
18 #include <map>
19 #include <memory>
20 #include <vector>
21 
22 namespace llvm {
23 
24 class raw_ostream;
25 class DWARFDataExtractor;
26 class MCRegisterInfo;
27 struct DIDumpOptions;
28 
29 namespace dwarf {
30 
31 constexpr uint32_t InvalidRegisterNumber = UINT32_MAX;
32 
33 /// A class that represents a location for the Call Frame Address (CFA) or a
34 /// register. This is decoded from the DWARF Call Frame Information
35 /// instructions and put into an UnwindRow.
36 class UnwindLocation {
37 public:
38   enum Location {
39     /// Not specified.
40     Unspecified,
41     /// Register is not available and can't be recovered.
42     Undefined,
43     /// Register value is in the register, nothing needs to be done to unwind
44     /// it:
45     ///   reg = reg
46     Same,
47     /// Register is in or at the CFA plus an offset:
48     ///   reg = CFA + offset
49     ///   reg = defef(CFA + offset)
50     CFAPlusOffset,
51     /// Register or CFA is in or at a register plus offset, optionally in
52     /// an address space:
53     ///   reg = reg + offset [in addrspace]
54     ///   reg = deref(reg + offset [in addrspace])
55     RegPlusOffset,
56     /// Register or CFA value is in or at a value found by evaluating a DWARF
57     /// expression:
58     ///   reg = eval(dwarf_expr)
59     ///   reg = deref(eval(dwarf_expr))
60     DWARFExpr,
61     /// Value is a constant value contained in "Offset":
62     ///   reg = Offset
63     Constant,
64   };
65 
66 private:
67   Location Kind;   /// The type of the location that describes how to unwind it.
68   uint32_t RegNum; /// The register number for Kind == RegPlusOffset.
69   int32_t Offset;  /// The offset for Kind == CFAPlusOffset or RegPlusOffset.
70   Optional<uint32_t> AddrSpace; /// The address space for Kind == RegPlusOffset
71                                 /// for CFA.
72   Optional<DWARFExpression> Expr; /// The DWARF expression for Kind ==
73                                   /// DWARFExpression.
74   bool Dereference; /// If true, the resulting location must be dereferenced
75                     /// after the location value is computed.
76 
77   // Constructors are private to force people to use the create static
78   // functions.
79   UnwindLocation(Location K)
80       : Kind(K), RegNum(InvalidRegisterNumber), Offset(0), AddrSpace(None),
81         Dereference(false) {}
82 
83   UnwindLocation(Location K, uint32_t Reg, int32_t Off, Optional<uint32_t> AS,
84                  bool Deref)
85       : Kind(K), RegNum(Reg), Offset(Off), AddrSpace(AS), Dereference(Deref) {}
86 
87   UnwindLocation(DWARFExpression E, bool Deref)
88       : Kind(DWARFExpr), RegNum(InvalidRegisterNumber), Offset(0), Expr(E),
89         Dereference(Deref) {}
90 
91 public:
92   /// Create a location whose rule is set to Unspecified. This means the
93   /// register value might be in the same register but it wasn't specified in
94   /// the unwind opcodes.
95   static UnwindLocation createUnspecified();
96   /// Create a location where the value is undefined and not available. This can
97   /// happen when a register is volatile and can't be recovered.
98   static UnwindLocation createUndefined();
99   /// Create a location where the value is known to be in the register itself.
100   static UnwindLocation createSame();
101   /// Create a location that is in (Deref == false) or at (Deref == true) the
102   /// CFA plus an offset. Most registers that are spilled onto the stack use
103   /// this rule. The rule for the register will use this rule and specify a
104   /// unique offset from the CFA with \a Deref set to true. This value will be
105   /// relative to a CFA value which is typically defined using the register
106   /// plus offset location. \see createRegisterPlusOffset(...) for more
107   /// information.
108   static UnwindLocation createIsCFAPlusOffset(int32_t Off);
109   static UnwindLocation createAtCFAPlusOffset(int32_t Off);
110   /// Create a location where the saved value is in (Deref == false) or at
111   /// (Deref == true) a regiser plus an offset and, optionally, in the specified
112   /// address space (used mostly for the CFA).
113   ///
114   /// The CFA is usually defined using this rule by using the stack pointer or
115   /// frame pointer as the register, with an offset that accounts for all
116   /// spilled registers and all local variables in a function, and Deref ==
117   /// false.
118   static UnwindLocation
119   createIsRegisterPlusOffset(uint32_t Reg, int32_t Off,
120                              Optional<uint32_t> AddrSpace = None);
121   static UnwindLocation
122   createAtRegisterPlusOffset(uint32_t Reg, int32_t Off,
123                              Optional<uint32_t> AddrSpace = None);
124   /// Create a location whose value is the result of evaluating a DWARF
125   /// expression. This allows complex expressions to be evaluated in order to
126   /// unwind a register or CFA value.
127   static UnwindLocation createIsDWARFExpression(DWARFExpression Expr);
128   static UnwindLocation createAtDWARFExpression(DWARFExpression Expr);
129   static UnwindLocation createIsConstant(int32_t Value);
130 
131   Location getLocation() const { return Kind; }
132   uint32_t getRegister() const { return RegNum; }
133   int32_t getOffset() const { return Offset; }
134   uint32_t getAddressSpace() const {
135     assert(Kind == RegPlusOffset && AddrSpace);
136     return *AddrSpace;
137   }
138   int32_t getConstant() const { return Offset; }
139   /// Some opcodes will modify the CFA location's register only, so we need
140   /// to be able to modify the CFA register when evaluating DWARF Call Frame
141   /// Information opcodes.
142   void setRegister(uint32_t NewRegNum) { RegNum = NewRegNum; }
143   /// Some opcodes will modify the CFA location's offset only, so we need
144   /// to be able to modify the CFA offset when evaluating DWARF Call Frame
145   /// Information opcodes.
146   void setOffset(int32_t NewOffset) { Offset = NewOffset; }
147   /// Some opcodes modify a constant value and we need to be able to update
148   /// the constant value (DW_CFA_GNU_window_save which is also known as
149   // DW_CFA_AARCH64_negate_ra_state).
150   void setConstant(int32_t Value) { Offset = Value; }
151 
152   Optional<DWARFExpression> getDWARFExpressionBytes() const { return Expr; }
153   /// Dump a location expression as text and use the register information if
154   /// some is provided.
155   ///
156   /// \param OS the stream to use for output.
157   ///
158   /// \param MRI register information that helps emit register names insteead
159   /// of raw register numbers.
160   ///
161   /// \param IsEH true if the DWARF Call Frame Information is from .eh_frame
162   /// instead of from .debug_frame. This is needed for register number
163   /// conversion because some register numbers differ between the two sections
164   /// for certain architectures like x86.
165   void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const;
166 
167   bool operator==(const UnwindLocation &RHS) const;
168 };
169 
170 raw_ostream &operator<<(raw_ostream &OS, const UnwindLocation &R);
171 
172 /// A class that can track all registers with locations in a UnwindRow object.
173 ///
174 /// Register locations use a map where the key is the register number and the
175 /// the value is a UnwindLocation.
176 ///
177 /// The register maps are put into a class so that all register locations can
178 /// be copied when parsing the unwind opcodes DW_CFA_remember_state and
179 /// DW_CFA_restore_state.
180 class RegisterLocations {
181   std::map<uint32_t, UnwindLocation> Locations;
182 
183 public:
184   /// Return the location for the register in \a RegNum if there is a location.
185   ///
186   /// \param RegNum the register number to find a location for.
187   ///
188   /// \returns A location if one is available for \a RegNum, or llvm::None
189   /// otherwise.
190   Optional<UnwindLocation> getRegisterLocation(uint32_t RegNum) const {
191     auto Pos = Locations.find(RegNum);
192     if (Pos == Locations.end())
193       return llvm::None;
194     return Pos->second;
195   }
196 
197   /// Set the location for the register in \a RegNum to \a Location.
198   ///
199   /// \param RegNum the register number to set the location for.
200   ///
201   /// \param Location the UnwindLocation that describes how to unwind the value.
202   void setRegisterLocation(uint32_t RegNum, const UnwindLocation &Location) {
203     Locations.erase(RegNum);
204     Locations.insert(std::make_pair(RegNum, Location));
205   }
206 
207   /// Removes any rule for the register in \a RegNum.
208   ///
209   /// \param RegNum the register number to remove the location for.
210   void removeRegisterLocation(uint32_t RegNum) { Locations.erase(RegNum); }
211 
212   /// Dump all registers + locations that are currently defined in this object.
213   ///
214   /// \param OS the stream to use for output.
215   ///
216   /// \param MRI register information that helps emit register names insteead
217   /// of raw register numbers.
218   ///
219   /// \param IsEH true if the DWARF Call Frame Information is from .eh_frame
220   /// instead of from .debug_frame. This is needed for register number
221   /// conversion because some register numbers differ between the two sections
222   /// for certain architectures like x86.
223   void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const;
224 
225   /// Returns true if we have any register locations in this object.
226   bool hasLocations() const { return !Locations.empty(); }
227 
228   size_t size() const { return Locations.size(); }
229 
230   bool operator==(const RegisterLocations &RHS) const {
231     return Locations == RHS.Locations;
232   }
233 };
234 
235 raw_ostream &operator<<(raw_ostream &OS, const RegisterLocations &RL);
236 
237 /// A class that represents a single row in the unwind table that is decoded by
238 /// parsing the DWARF Call Frame Information opcodes.
239 ///
240 /// The row consists of an optional address, the rule to unwind the CFA and all
241 /// rules to unwind any registers. If the address doesn't have a value, this
242 /// row represents the initial instructions for a CIE. If the address has a
243 /// value the UnwindRow represents a row in the UnwindTable for a FDE. The
244 /// address is the first address for which the CFA location and register rules
245 /// are valid within a function.
246 ///
247 /// UnwindRow objects are created by parsing opcodes in the DWARF Call Frame
248 /// Information and UnwindRow objects are lazily populated and pushed onto a
249 /// stack in the UnwindTable when evaluating this state machine. Accessors are
250 /// needed for the address, CFA value, and register locations as the opcodes
251 /// encode a state machine that produces a sorted array of UnwindRow objects
252 /// \see UnwindTable.
253 class UnwindRow {
254   /// The address will be valid when parsing the instructions in a FDE. If
255   /// invalid, this object represents the initial instructions of a CIE.
256   Optional<uint64_t> Address; ///< Address for row in FDE, invalid for CIE.
257   UnwindLocation CFAValue;    ///< How to unwind the Call Frame Address (CFA).
258   RegisterLocations RegLocs;  ///< How to unwind all registers in this list.
259 
260 public:
261   UnwindRow() : CFAValue(UnwindLocation::createUnspecified()) {}
262 
263   /// Returns true if the address is valid in this object.
264   bool hasAddress() const { return Address.has_value(); }
265 
266   /// Get the address for this row.
267   ///
268   /// Clients should only call this function after verifying it has a valid
269   /// address with a call to \see hasAddress().
270   uint64_t getAddress() const { return *Address; }
271 
272   /// Set the address for this UnwindRow.
273   ///
274   /// The address represents the first address for which the CFAValue and
275   /// RegLocs are valid within a function.
276   void setAddress(uint64_t Addr) { Address = Addr; }
277 
278   /// Offset the address for this UnwindRow.
279   ///
280   /// The address represents the first address for which the CFAValue and
281   /// RegLocs are valid within a function. Clients must ensure that this object
282   /// already has an address (\see hasAddress()) prior to calling this
283   /// function.
284   void slideAddress(uint64_t Offset) { *Address += Offset; }
285   UnwindLocation &getCFAValue() { return CFAValue; }
286   const UnwindLocation &getCFAValue() const { return CFAValue; }
287   RegisterLocations &getRegisterLocations() { return RegLocs; }
288   const RegisterLocations &getRegisterLocations() const { return RegLocs; }
289 
290   /// Dump the UnwindRow to the stream.
291   ///
292   /// \param OS the stream to use for output.
293   ///
294   /// \param MRI register information that helps emit register names insteead
295   /// of raw register numbers.
296   ///
297   /// \param IsEH true if the DWARF Call Frame Information is from .eh_frame
298   /// instead of from .debug_frame. This is needed for register number
299   /// conversion because some register numbers differ between the two sections
300   /// for certain architectures like x86.
301   ///
302   /// \param IndentLevel specify the indent level as an integer. The UnwindRow
303   /// will be output to the stream preceded by 2 * IndentLevel number of spaces.
304   void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
305             unsigned IndentLevel = 0) const;
306 };
307 
308 raw_ostream &operator<<(raw_ostream &OS, const UnwindRow &Row);
309 
310 class CFIProgram;
311 class CIE;
312 class FDE;
313 
314 /// A class that contains all UnwindRow objects for an FDE or a single unwind
315 /// row for a CIE. To unwind an address the rows, which are sorted by start
316 /// address, can be searched to find the UnwindRow with the lowest starting
317 /// address that is greater than or equal to the address that is being looked
318 /// up.
319 class UnwindTable {
320 public:
321   using RowContainer = std::vector<UnwindRow>;
322   using iterator = RowContainer::iterator;
323   using const_iterator = RowContainer::const_iterator;
324 
325   size_t size() const { return Rows.size(); }
326   iterator begin() { return Rows.begin(); }
327   const_iterator begin() const { return Rows.begin(); }
328   iterator end() { return Rows.end(); }
329   const_iterator end() const { return Rows.end(); }
330   const UnwindRow &operator[](size_t Index) const {
331     assert(Index < size());
332     return Rows[Index];
333   }
334 
335   /// Dump the UnwindTable to the stream.
336   ///
337   /// \param OS the stream to use for output.
338   ///
339   /// \param MRI register information that helps emit register names insteead
340   /// of raw register numbers.
341   ///
342   /// \param IsEH true if the DWARF Call Frame Information is from .eh_frame
343   /// instead of from .debug_frame. This is needed for register number
344   /// conversion because some register numbers differ between the two sections
345   /// for certain architectures like x86.
346   ///
347   /// \param IndentLevel specify the indent level as an integer. The UnwindRow
348   /// will be output to the stream preceded by 2 * IndentLevel number of spaces.
349   void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
350             unsigned IndentLevel = 0) const;
351 
352   /// Create an UnwindTable from a Common Information Entry (CIE).
353   ///
354   /// \param Cie The Common Information Entry to extract the table from. The
355   /// CFIProgram is retrieved from the \a Cie object and used to create the
356   /// UnwindTable.
357   ///
358   /// \returns An error if the DWARF Call Frame Information opcodes have state
359   /// machine errors, or a valid UnwindTable otherwise.
360   static Expected<UnwindTable> create(const CIE *Cie);
361 
362   /// Create an UnwindTable from a Frame Descriptor Entry (FDE).
363   ///
364   /// \param Fde The Frame Descriptor Entry to extract the table from. The
365   /// CFIProgram is retrieved from the \a Fde object and used to create the
366   /// UnwindTable.
367   ///
368   /// \returns An error if the DWARF Call Frame Information opcodes have state
369   /// machine errors, or a valid UnwindTable otherwise.
370   static Expected<UnwindTable> create(const FDE *Fde);
371 
372 private:
373   RowContainer Rows;
374   /// The end address when data is extracted from a FDE. This value will be
375   /// invalid when a UnwindTable is extracted from a CIE.
376   Optional<uint64_t> EndAddress;
377 
378   /// Parse the information in the CFIProgram and update the CurrRow object
379   /// that the state machine describes.
380   ///
381   /// This is an internal implementation that emulates the state machine
382   /// described in the DWARF Call Frame Information opcodes and will push
383   /// CurrRow onto the Rows container when needed.
384   ///
385   /// \param CFIP the CFI program that contains the opcodes from a CIE or FDE.
386   ///
387   /// \param CurrRow the current row to modify while parsing the state machine.
388   ///
389   /// \param InitialLocs If non-NULL, we are parsing a FDE and this contains
390   /// the initial register locations from the CIE. If NULL, then a CIE's
391   /// opcodes are being parsed and this is not needed. This is used for the
392   /// DW_CFA_restore and DW_CFA_restore_extended opcodes.
393   Error parseRows(const CFIProgram &CFIP, UnwindRow &CurrRow,
394                   const RegisterLocations *InitialLocs);
395 };
396 
397 raw_ostream &operator<<(raw_ostream &OS, const UnwindTable &Rows);
398 
399 /// Represent a sequence of Call Frame Information instructions that, when read
400 /// in order, construct a table mapping PC to frame state. This can also be
401 /// referred to as "CFI rules" in DWARF literature to avoid confusion with
402 /// computer programs in the broader sense, and in this context each instruction
403 /// would be a rule to establish the mapping. Refer to pg. 172 in the DWARF5
404 /// manual, "6.4.1 Structure of Call Frame Information".
405 class CFIProgram {
406 public:
407   static constexpr size_t MaxOperands = 3;
408   typedef SmallVector<uint64_t, MaxOperands> Operands;
409 
410   /// An instruction consists of a DWARF CFI opcode and an optional sequence of
411   /// operands. If it refers to an expression, then this expression has its own
412   /// sequence of operations and operands handled separately by DWARFExpression.
413   struct Instruction {
414     Instruction(uint8_t Opcode) : Opcode(Opcode) {}
415 
416     uint8_t Opcode;
417     Operands Ops;
418     // Associated DWARF expression in case this instruction refers to one
419     Optional<DWARFExpression> Expression;
420 
421     Expected<uint64_t> getOperandAsUnsigned(const CFIProgram &CFIP,
422                                             uint32_t OperandIdx) const;
423 
424     Expected<int64_t> getOperandAsSigned(const CFIProgram &CFIP,
425                                          uint32_t OperandIdx) const;
426   };
427 
428   using InstrList = std::vector<Instruction>;
429   using iterator = InstrList::iterator;
430   using const_iterator = InstrList::const_iterator;
431 
432   iterator begin() { return Instructions.begin(); }
433   const_iterator begin() const { return Instructions.begin(); }
434   iterator end() { return Instructions.end(); }
435   const_iterator end() const { return Instructions.end(); }
436 
437   unsigned size() const { return (unsigned)Instructions.size(); }
438   bool empty() const { return Instructions.empty(); }
439   uint64_t codeAlign() const { return CodeAlignmentFactor; }
440   int64_t dataAlign() const { return DataAlignmentFactor; }
441   Triple::ArchType triple() const { return Arch; }
442 
443   CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor,
444              Triple::ArchType Arch)
445       : CodeAlignmentFactor(CodeAlignmentFactor),
446         DataAlignmentFactor(DataAlignmentFactor),
447         Arch(Arch) {}
448 
449   /// Parse and store a sequence of CFI instructions from Data,
450   /// starting at *Offset and ending at EndOffset. *Offset is updated
451   /// to EndOffset upon successful parsing, or indicates the offset
452   /// where a problem occurred in case an error is returned.
453   Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset);
454 
455   void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
456             bool IsEH, unsigned IndentLevel = 1) const;
457 
458   void addInstruction(const Instruction &I) { Instructions.push_back(I); }
459 
460   /// Get a DWARF CFI call frame string for the given DW_CFA opcode.
461   StringRef callFrameString(unsigned Opcode) const;
462 
463 private:
464   std::vector<Instruction> Instructions;
465   const uint64_t CodeAlignmentFactor;
466   const int64_t DataAlignmentFactor;
467   Triple::ArchType Arch;
468 
469   /// Convenience method to add a new instruction with the given opcode.
470   void addInstruction(uint8_t Opcode) {
471     Instructions.push_back(Instruction(Opcode));
472   }
473 
474   /// Add a new single-operand instruction.
475   void addInstruction(uint8_t Opcode, uint64_t Operand1) {
476     Instructions.push_back(Instruction(Opcode));
477     Instructions.back().Ops.push_back(Operand1);
478   }
479 
480   /// Add a new instruction that has two operands.
481   void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {
482     Instructions.push_back(Instruction(Opcode));
483     Instructions.back().Ops.push_back(Operand1);
484     Instructions.back().Ops.push_back(Operand2);
485   }
486 
487   /// Add a new instruction that has three operands.
488   void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2,
489                       uint64_t Operand3) {
490     Instructions.push_back(Instruction(Opcode));
491     Instructions.back().Ops.push_back(Operand1);
492     Instructions.back().Ops.push_back(Operand2);
493     Instructions.back().Ops.push_back(Operand3);
494   }
495 
496   /// Types of operands to CFI instructions
497   /// In DWARF, this type is implicitly tied to a CFI instruction opcode and
498   /// thus this type doesn't need to be explictly written to the file (this is
499   /// not a DWARF encoding). The relationship of instrs to operand types can
500   /// be obtained from getOperandTypes() and is only used to simplify
501   /// instruction printing.
502   enum OperandType {
503     OT_Unset,
504     OT_None,
505     OT_Address,
506     OT_Offset,
507     OT_FactoredCodeOffset,
508     OT_SignedFactDataOffset,
509     OT_UnsignedFactDataOffset,
510     OT_Register,
511     OT_AddressSpace,
512     OT_Expression
513   };
514 
515   /// Get the OperandType as a "const char *".
516   static const char *operandTypeString(OperandType OT);
517 
518   /// Retrieve the array describing the types of operands according to the enum
519   /// above. This is indexed by opcode.
520   static ArrayRef<OperandType[MaxOperands]> getOperandTypes();
521 
522   /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
523   void printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
524                     const MCRegisterInfo *MRI, bool IsEH,
525                     const Instruction &Instr, unsigned OperandIdx,
526                     uint64_t Operand) const;
527 };
528 
529 /// An entry in either debug_frame or eh_frame. This entry can be a CIE or an
530 /// FDE.
531 class FrameEntry {
532 public:
533   enum FrameKind { FK_CIE, FK_FDE };
534 
535   FrameEntry(FrameKind K, bool IsDWARF64, uint64_t Offset, uint64_t Length,
536              uint64_t CodeAlign, int64_t DataAlign, Triple::ArchType Arch)
537       : Kind(K), IsDWARF64(IsDWARF64), Offset(Offset), Length(Length),
538         CFIs(CodeAlign, DataAlign, Arch) {}
539 
540   virtual ~FrameEntry() = default;
541 
542   FrameKind getKind() const { return Kind; }
543   uint64_t getOffset() const { return Offset; }
544   uint64_t getLength() const { return Length; }
545   const CFIProgram &cfis() const { return CFIs; }
546   CFIProgram &cfis() { return CFIs; }
547 
548   /// Dump the instructions in this CFI fragment
549   virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
550                     const MCRegisterInfo *MRI, bool IsEH) const = 0;
551 
552 protected:
553   const FrameKind Kind;
554 
555   const bool IsDWARF64;
556 
557   /// Offset of this entry in the section.
558   const uint64_t Offset;
559 
560   /// Entry length as specified in DWARF.
561   const uint64_t Length;
562 
563   CFIProgram CFIs;
564 };
565 
566 /// DWARF Common Information Entry (CIE)
567 class CIE : public FrameEntry {
568 public:
569   // CIEs (and FDEs) are simply container classes, so the only sensible way to
570   // create them is by providing the full parsed contents in the constructor.
571   CIE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint8_t Version,
572       SmallString<8> Augmentation, uint8_t AddressSize,
573       uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
574       int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
575       SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
576       uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality,
577       Optional<uint32_t> PersonalityEnc, Triple::ArchType Arch)
578       : FrameEntry(FK_CIE, IsDWARF64, Offset, Length, CodeAlignmentFactor,
579                    DataAlignmentFactor, Arch),
580         Version(Version), Augmentation(std::move(Augmentation)),
581         AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
582         CodeAlignmentFactor(CodeAlignmentFactor),
583         DataAlignmentFactor(DataAlignmentFactor),
584         ReturnAddressRegister(ReturnAddressRegister),
585         AugmentationData(std::move(AugmentationData)),
586         FDEPointerEncoding(FDEPointerEncoding),
587         LSDAPointerEncoding(LSDAPointerEncoding), Personality(Personality),
588         PersonalityEnc(PersonalityEnc) {}
589 
590   static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_CIE; }
591 
592   StringRef getAugmentationString() const { return Augmentation; }
593   uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
594   int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
595   uint8_t getVersion() const { return Version; }
596   uint64_t getReturnAddressRegister() const { return ReturnAddressRegister; }
597   Optional<uint64_t> getPersonalityAddress() const { return Personality; }
598   Optional<uint32_t> getPersonalityEncoding() const { return PersonalityEnc; }
599 
600   uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; }
601 
602   uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }
603 
604   void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
605             bool IsEH) const override;
606 
607 private:
608   /// The following fields are defined in section 6.4.1 of the DWARF standard v4
609   const uint8_t Version;
610   const SmallString<8> Augmentation;
611   const uint8_t AddressSize;
612   const uint8_t SegmentDescriptorSize;
613   const uint64_t CodeAlignmentFactor;
614   const int64_t DataAlignmentFactor;
615   const uint64_t ReturnAddressRegister;
616 
617   // The following are used when the CIE represents an EH frame entry.
618   const SmallString<8> AugmentationData;
619   const uint32_t FDEPointerEncoding;
620   const uint32_t LSDAPointerEncoding;
621   const Optional<uint64_t> Personality;
622   const Optional<uint32_t> PersonalityEnc;
623 };
624 
625 /// DWARF Frame Description Entry (FDE)
626 class FDE : public FrameEntry {
627 public:
628   FDE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint64_t CIEPointer,
629       uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
630       Optional<uint64_t> LSDAAddress, Triple::ArchType Arch)
631       : FrameEntry(FK_FDE, IsDWARF64, Offset, Length,
632                    Cie ? Cie->getCodeAlignmentFactor() : 0,
633                    Cie ? Cie->getDataAlignmentFactor() : 0,
634                    Arch),
635         CIEPointer(CIEPointer), InitialLocation(InitialLocation),
636         AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
637 
638   ~FDE() override = default;
639 
640   const CIE *getLinkedCIE() const { return LinkedCIE; }
641   uint64_t getInitialLocation() const { return InitialLocation; }
642   uint64_t getAddressRange() const { return AddressRange; }
643   Optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }
644 
645   void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
646             bool IsEH) const override;
647 
648   static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
649 
650 private:
651   /// The following fields are defined in section 6.4.1 of the DWARFv3 standard.
652   /// Note that CIE pointers in EH FDEs, unlike DWARF FDEs, contain relative
653   /// offsets to the linked CIEs. See the following link for more info:
654   /// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
655   const uint64_t CIEPointer;
656   const uint64_t InitialLocation;
657   const uint64_t AddressRange;
658   const CIE *LinkedCIE;
659   const Optional<uint64_t> LSDAAddress;
660 };
661 
662 } // end namespace dwarf
663 
664 /// A parsed .debug_frame or .eh_frame section
665 class DWARFDebugFrame {
666   const Triple::ArchType Arch;
667   // True if this is parsing an eh_frame section.
668   const bool IsEH;
669   // Not zero for sane pointer values coming out of eh_frame
670   const uint64_t EHFrameAddress;
671 
672   std::vector<std::unique_ptr<dwarf::FrameEntry>> Entries;
673   using iterator = pointee_iterator<decltype(Entries)::const_iterator>;
674 
675   /// Return the entry at the given offset or nullptr.
676   dwarf::FrameEntry *getEntryAtOffset(uint64_t Offset) const;
677 
678 public:
679   // If IsEH is true, assume it is a .eh_frame section. Otherwise,
680   // it is a .debug_frame section. EHFrameAddress should be different
681   // than zero for correct parsing of .eh_frame addresses when they
682   // use a PC-relative encoding.
683   DWARFDebugFrame(Triple::ArchType Arch,
684                   bool IsEH = false, uint64_t EHFrameAddress = 0);
685   ~DWARFDebugFrame();
686 
687   /// Dump the section data into the given stream.
688   void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
689             Optional<uint64_t> Offset) const;
690 
691   /// Parse the section from raw data. \p Data is assumed to contain the whole
692   /// frame section contents to be parsed.
693   Error parse(DWARFDataExtractor Data);
694 
695   /// Return whether the section has any entries.
696   bool empty() const { return Entries.empty(); }
697 
698   /// DWARF Frame entries accessors
699   iterator begin() const { return Entries.begin(); }
700   iterator end() const { return Entries.end(); }
701   iterator_range<iterator> entries() const {
702     return iterator_range<iterator>(Entries.begin(), Entries.end());
703   }
704 
705   uint64_t getEHFrameAddress() const { return EHFrameAddress; }
706 };
707 
708 } // end namespace llvm
709 
710 #endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
711