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