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/iterator.h" 15 #include "llvm/DebugInfo/DWARF/DWARFExpression.h" 16 #include "llvm/Support/Error.h" 17 #include "llvm/TargetParser/Triple.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 std::optional<uint32_t> AddrSpace; /// The address space for Kind == 71 /// RegPlusOffset for CFA. 72 std::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), 81 AddrSpace(std::nullopt), Dereference(false) {} 82 83 UnwindLocation(Location K, uint32_t Reg, int32_t Off, 84 std::optional<uint32_t> AS, 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 std::optional<uint32_t> AddrSpace = std::nullopt); 121 static UnwindLocation 122 createAtRegisterPlusOffset(uint32_t Reg, int32_t Off, 123 std::optional<uint32_t> AddrSpace = std::nullopt); 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 std::optional<DWARFExpression> getDWARFExpressionBytes() const { 153 return Expr; 154 } 155 /// Dump a location expression as text and use the register information if 156 /// some is provided. 157 /// 158 /// \param OS the stream to use for output. 159 /// 160 /// \param MRI register information that helps emit register names insteead 161 /// of raw register numbers. 162 /// 163 /// \param IsEH true if the DWARF Call Frame Information is from .eh_frame 164 /// instead of from .debug_frame. This is needed for register number 165 /// conversion because some register numbers differ between the two sections 166 /// for certain architectures like x86. 167 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const; 168 169 bool operator==(const UnwindLocation &RHS) const; 170 }; 171 172 raw_ostream &operator<<(raw_ostream &OS, const UnwindLocation &R); 173 174 /// A class that can track all registers with locations in a UnwindRow object. 175 /// 176 /// Register locations use a map where the key is the register number and the 177 /// the value is a UnwindLocation. 178 /// 179 /// The register maps are put into a class so that all register locations can 180 /// be copied when parsing the unwind opcodes DW_CFA_remember_state and 181 /// DW_CFA_restore_state. 182 class RegisterLocations { 183 std::map<uint32_t, UnwindLocation> Locations; 184 185 public: 186 /// Return the location for the register in \a RegNum if there is a location. 187 /// 188 /// \param RegNum the register number to find a location for. 189 /// 190 /// \returns A location if one is available for \a RegNum, or std::nullopt 191 /// otherwise. 192 std::optional<UnwindLocation> getRegisterLocation(uint32_t RegNum) const { 193 auto Pos = Locations.find(RegNum); 194 if (Pos == Locations.end()) 195 return std::nullopt; 196 return Pos->second; 197 } 198 199 /// Set the location for the register in \a RegNum to \a Location. 200 /// 201 /// \param RegNum the register number to set the location for. 202 /// 203 /// \param Location the UnwindLocation that describes how to unwind the value. 204 void setRegisterLocation(uint32_t RegNum, const UnwindLocation &Location) { 205 Locations.erase(RegNum); 206 Locations.insert(std::make_pair(RegNum, Location)); 207 } 208 209 /// Removes any rule for the register in \a RegNum. 210 /// 211 /// \param RegNum the register number to remove the location for. 212 void removeRegisterLocation(uint32_t RegNum) { Locations.erase(RegNum); } 213 214 /// Dump all registers + locations that are currently defined in this object. 215 /// 216 /// \param OS the stream to use for output. 217 /// 218 /// \param MRI register information that helps emit register names insteead 219 /// of raw register numbers. 220 /// 221 /// \param IsEH true if the DWARF Call Frame Information is from .eh_frame 222 /// instead of from .debug_frame. This is needed for register number 223 /// conversion because some register numbers differ between the two sections 224 /// for certain architectures like x86. 225 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const; 226 227 /// Returns true if we have any register locations in this object. 228 bool hasLocations() const { return !Locations.empty(); } 229 230 size_t size() const { return Locations.size(); } 231 232 bool operator==(const RegisterLocations &RHS) const { 233 return Locations == RHS.Locations; 234 } 235 }; 236 237 raw_ostream &operator<<(raw_ostream &OS, const RegisterLocations &RL); 238 239 /// A class that represents a single row in the unwind table that is decoded by 240 /// parsing the DWARF Call Frame Information opcodes. 241 /// 242 /// The row consists of an optional address, the rule to unwind the CFA and all 243 /// rules to unwind any registers. If the address doesn't have a value, this 244 /// row represents the initial instructions for a CIE. If the address has a 245 /// value the UnwindRow represents a row in the UnwindTable for a FDE. The 246 /// address is the first address for which the CFA location and register rules 247 /// are valid within a function. 248 /// 249 /// UnwindRow objects are created by parsing opcodes in the DWARF Call Frame 250 /// Information and UnwindRow objects are lazily populated and pushed onto a 251 /// stack in the UnwindTable when evaluating this state machine. Accessors are 252 /// needed for the address, CFA value, and register locations as the opcodes 253 /// encode a state machine that produces a sorted array of UnwindRow objects 254 /// \see UnwindTable. 255 class UnwindRow { 256 /// The address will be valid when parsing the instructions in a FDE. If 257 /// invalid, this object represents the initial instructions of a CIE. 258 std::optional<uint64_t> Address; ///< Address for row in FDE, invalid for CIE. 259 UnwindLocation CFAValue; ///< How to unwind the Call Frame Address (CFA). 260 RegisterLocations RegLocs; ///< How to unwind all registers in this list. 261 262 public: 263 UnwindRow() : CFAValue(UnwindLocation::createUnspecified()) {} 264 265 /// Returns true if the address is valid in this object. 266 bool hasAddress() const { return Address.has_value(); } 267 268 /// Get the address for this row. 269 /// 270 /// Clients should only call this function after verifying it has a valid 271 /// address with a call to \see hasAddress(). 272 uint64_t getAddress() const { return *Address; } 273 274 /// Set the address for this UnwindRow. 275 /// 276 /// The address represents the first address for which the CFAValue and 277 /// RegLocs are valid within a function. 278 void setAddress(uint64_t Addr) { Address = Addr; } 279 280 /// Offset the address for this UnwindRow. 281 /// 282 /// The address represents the first address for which the CFAValue and 283 /// RegLocs are valid within a function. Clients must ensure that this object 284 /// already has an address (\see hasAddress()) prior to calling this 285 /// function. 286 void slideAddress(uint64_t Offset) { *Address += Offset; } 287 UnwindLocation &getCFAValue() { return CFAValue; } 288 const UnwindLocation &getCFAValue() const { return CFAValue; } 289 RegisterLocations &getRegisterLocations() { return RegLocs; } 290 const RegisterLocations &getRegisterLocations() const { return RegLocs; } 291 292 /// Dump the UnwindRow to the stream. 293 /// 294 /// \param OS the stream to use for output. 295 /// 296 /// \param MRI register information that helps emit register names insteead 297 /// of raw register numbers. 298 /// 299 /// \param IsEH true if the DWARF Call Frame Information is from .eh_frame 300 /// instead of from .debug_frame. This is needed for register number 301 /// conversion because some register numbers differ between the two sections 302 /// for certain architectures like x86. 303 /// 304 /// \param IndentLevel specify the indent level as an integer. The UnwindRow 305 /// will be output to the stream preceded by 2 * IndentLevel number of spaces. 306 void dump(raw_ostream &OS, DIDumpOptions DumpOpts, 307 unsigned IndentLevel = 0) const; 308 }; 309 310 raw_ostream &operator<<(raw_ostream &OS, const UnwindRow &Row); 311 312 class CFIProgram; 313 class CIE; 314 class FDE; 315 316 /// A class that contains all UnwindRow objects for an FDE or a single unwind 317 /// row for a CIE. To unwind an address the rows, which are sorted by start 318 /// address, can be searched to find the UnwindRow with the lowest starting 319 /// address that is greater than or equal to the address that is being looked 320 /// up. 321 class UnwindTable { 322 public: 323 using RowContainer = std::vector<UnwindRow>; 324 using iterator = RowContainer::iterator; 325 using const_iterator = RowContainer::const_iterator; 326 327 size_t size() const { return Rows.size(); } 328 iterator begin() { return Rows.begin(); } 329 const_iterator begin() const { return Rows.begin(); } 330 iterator end() { return Rows.end(); } 331 const_iterator end() const { return Rows.end(); } 332 const UnwindRow &operator[](size_t Index) const { 333 assert(Index < size()); 334 return Rows[Index]; 335 } 336 337 /// Dump the UnwindTable to the stream. 338 /// 339 /// \param OS the stream to use for output. 340 /// 341 /// \param MRI register information that helps emit register names insteead 342 /// of raw register numbers. 343 /// 344 /// \param IsEH true if the DWARF Call Frame Information is from .eh_frame 345 /// instead of from .debug_frame. This is needed for register number 346 /// conversion because some register numbers differ between the two sections 347 /// for certain architectures like x86. 348 /// 349 /// \param IndentLevel specify the indent level as an integer. The UnwindRow 350 /// will be output to the stream preceded by 2 * IndentLevel number of spaces. 351 void dump(raw_ostream &OS, DIDumpOptions DumpOpts, 352 unsigned IndentLevel = 0) const; 353 354 /// Create an UnwindTable from a Common Information Entry (CIE). 355 /// 356 /// \param Cie The Common Information Entry to extract the table from. The 357 /// CFIProgram is retrieved from the \a Cie object and used to create the 358 /// UnwindTable. 359 /// 360 /// \returns An error if the DWARF Call Frame Information opcodes have state 361 /// machine errors, or a valid UnwindTable otherwise. 362 static Expected<UnwindTable> create(const CIE *Cie); 363 364 /// Create an UnwindTable from a Frame Descriptor Entry (FDE). 365 /// 366 /// \param Fde The Frame Descriptor Entry to extract the table from. The 367 /// CFIProgram is retrieved from the \a Fde object and used to create the 368 /// UnwindTable. 369 /// 370 /// \returns An error if the DWARF Call Frame Information opcodes have state 371 /// machine errors, or a valid UnwindTable otherwise. 372 static Expected<UnwindTable> create(const FDE *Fde); 373 374 private: 375 RowContainer Rows; 376 /// The end address when data is extracted from a FDE. This value will be 377 /// invalid when a UnwindTable is extracted from a CIE. 378 std::optional<uint64_t> EndAddress; 379 380 /// Parse the information in the CFIProgram and update the CurrRow object 381 /// that the state machine describes. 382 /// 383 /// This is an internal implementation that emulates the state machine 384 /// described in the DWARF Call Frame Information opcodes and will push 385 /// CurrRow onto the Rows container when needed. 386 /// 387 /// \param CFIP the CFI program that contains the opcodes from a CIE or FDE. 388 /// 389 /// \param CurrRow the current row to modify while parsing the state machine. 390 /// 391 /// \param InitialLocs If non-NULL, we are parsing a FDE and this contains 392 /// the initial register locations from the CIE. If NULL, then a CIE's 393 /// opcodes are being parsed and this is not needed. This is used for the 394 /// DW_CFA_restore and DW_CFA_restore_extended opcodes. 395 Error parseRows(const CFIProgram &CFIP, UnwindRow &CurrRow, 396 const RegisterLocations *InitialLocs); 397 }; 398 399 raw_ostream &operator<<(raw_ostream &OS, const UnwindTable &Rows); 400 401 /// Represent a sequence of Call Frame Information instructions that, when read 402 /// in order, construct a table mapping PC to frame state. This can also be 403 /// referred to as "CFI rules" in DWARF literature to avoid confusion with 404 /// computer programs in the broader sense, and in this context each instruction 405 /// would be a rule to establish the mapping. Refer to pg. 172 in the DWARF5 406 /// manual, "6.4.1 Structure of Call Frame Information". 407 class CFIProgram { 408 public: 409 static constexpr size_t MaxOperands = 3; 410 typedef SmallVector<uint64_t, MaxOperands> Operands; 411 412 /// An instruction consists of a DWARF CFI opcode and an optional sequence of 413 /// operands. If it refers to an expression, then this expression has its own 414 /// sequence of operations and operands handled separately by DWARFExpression. 415 struct Instruction { 416 Instruction(uint8_t Opcode) : Opcode(Opcode) {} 417 418 uint8_t Opcode; 419 Operands Ops; 420 // Associated DWARF expression in case this instruction refers to one 421 std::optional<DWARFExpression> Expression; 422 423 Expected<uint64_t> getOperandAsUnsigned(const CFIProgram &CFIP, 424 uint32_t OperandIdx) const; 425 426 Expected<int64_t> getOperandAsSigned(const CFIProgram &CFIP, 427 uint32_t OperandIdx) const; 428 }; 429 430 using InstrList = std::vector<Instruction>; 431 using iterator = InstrList::iterator; 432 using const_iterator = InstrList::const_iterator; 433 434 iterator begin() { return Instructions.begin(); } 435 const_iterator begin() const { return Instructions.begin(); } 436 iterator end() { return Instructions.end(); } 437 const_iterator end() const { return Instructions.end(); } 438 439 unsigned size() const { return (unsigned)Instructions.size(); } 440 bool empty() const { return Instructions.empty(); } 441 uint64_t codeAlign() const { return CodeAlignmentFactor; } 442 int64_t dataAlign() const { return DataAlignmentFactor; } 443 Triple::ArchType triple() const { return Arch; } 444 445 CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor, 446 Triple::ArchType Arch) 447 : CodeAlignmentFactor(CodeAlignmentFactor), 448 DataAlignmentFactor(DataAlignmentFactor), 449 Arch(Arch) {} 450 451 /// Parse and store a sequence of CFI instructions from Data, 452 /// starting at *Offset and ending at EndOffset. *Offset is updated 453 /// to EndOffset upon successful parsing, or indicates the offset 454 /// where a problem occurred in case an error is returned. 455 Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset); 456 457 void dump(raw_ostream &OS, DIDumpOptions DumpOpts, 458 unsigned IndentLevel = 1) const; 459 460 void addInstruction(const Instruction &I) { Instructions.push_back(I); } 461 462 /// Get a DWARF CFI call frame string for the given DW_CFA opcode. 463 StringRef callFrameString(unsigned Opcode) const; 464 465 private: 466 std::vector<Instruction> Instructions; 467 const uint64_t CodeAlignmentFactor; 468 const int64_t DataAlignmentFactor; 469 Triple::ArchType Arch; 470 471 /// Convenience method to add a new instruction with the given opcode. 472 void addInstruction(uint8_t Opcode) { 473 Instructions.push_back(Instruction(Opcode)); 474 } 475 476 /// Add a new single-operand instruction. 477 void addInstruction(uint8_t Opcode, uint64_t Operand1) { 478 Instructions.push_back(Instruction(Opcode)); 479 Instructions.back().Ops.push_back(Operand1); 480 } 481 482 /// Add a new instruction that has two operands. 483 void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) { 484 Instructions.push_back(Instruction(Opcode)); 485 Instructions.back().Ops.push_back(Operand1); 486 Instructions.back().Ops.push_back(Operand2); 487 } 488 489 /// Add a new instruction that has three operands. 490 void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2, 491 uint64_t Operand3) { 492 Instructions.push_back(Instruction(Opcode)); 493 Instructions.back().Ops.push_back(Operand1); 494 Instructions.back().Ops.push_back(Operand2); 495 Instructions.back().Ops.push_back(Operand3); 496 } 497 498 /// Types of operands to CFI instructions 499 /// In DWARF, this type is implicitly tied to a CFI instruction opcode and 500 /// thus this type doesn't need to be explictly written to the file (this is 501 /// not a DWARF encoding). The relationship of instrs to operand types can 502 /// be obtained from getOperandTypes() and is only used to simplify 503 /// instruction printing. 504 enum OperandType { 505 OT_Unset, 506 OT_None, 507 OT_Address, 508 OT_Offset, 509 OT_FactoredCodeOffset, 510 OT_SignedFactDataOffset, 511 OT_UnsignedFactDataOffset, 512 OT_Register, 513 OT_AddressSpace, 514 OT_Expression 515 }; 516 517 /// Get the OperandType as a "const char *". 518 static const char *operandTypeString(OperandType OT); 519 520 /// Retrieve the array describing the types of operands according to the enum 521 /// above. This is indexed by opcode. 522 static ArrayRef<OperandType[MaxOperands]> getOperandTypes(); 523 524 /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand. 525 void printOperand(raw_ostream &OS, DIDumpOptions DumpOpts, 526 const Instruction &Instr, unsigned OperandIdx, 527 uint64_t Operand) const; 528 }; 529 530 /// An entry in either debug_frame or eh_frame. This entry can be a CIE or an 531 /// FDE. 532 class FrameEntry { 533 public: 534 enum FrameKind { FK_CIE, FK_FDE }; 535 536 FrameEntry(FrameKind K, bool IsDWARF64, uint64_t Offset, uint64_t Length, 537 uint64_t CodeAlign, int64_t DataAlign, Triple::ArchType Arch) 538 : Kind(K), IsDWARF64(IsDWARF64), Offset(Offset), Length(Length), 539 CFIs(CodeAlign, DataAlign, Arch) {} 540 541 virtual ~FrameEntry() = default; 542 543 FrameKind getKind() const { return Kind; } 544 uint64_t getOffset() const { return Offset; } 545 uint64_t getLength() const { return Length; } 546 const CFIProgram &cfis() const { return CFIs; } 547 CFIProgram &cfis() { return CFIs; } 548 549 /// Dump the instructions in this CFI fragment 550 virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) 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, std::optional<uint64_t> Personality, 577 std::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 std::optional<uint64_t> getPersonalityAddress() const { return Personality; } 598 std::optional<uint32_t> getPersonalityEncoding() const { 599 return PersonalityEnc; 600 } 601 602 StringRef getAugmentationData() const { return AugmentationData; } 603 604 uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; } 605 606 uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; } 607 608 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override; 609 610 private: 611 /// The following fields are defined in section 6.4.1 of the DWARF standard v4 612 const uint8_t Version; 613 const SmallString<8> Augmentation; 614 const uint8_t AddressSize; 615 const uint8_t SegmentDescriptorSize; 616 const uint64_t CodeAlignmentFactor; 617 const int64_t DataAlignmentFactor; 618 const uint64_t ReturnAddressRegister; 619 620 // The following are used when the CIE represents an EH frame entry. 621 const SmallString<8> AugmentationData; 622 const uint32_t FDEPointerEncoding; 623 const uint32_t LSDAPointerEncoding; 624 const std::optional<uint64_t> Personality; 625 const std::optional<uint32_t> PersonalityEnc; 626 }; 627 628 /// DWARF Frame Description Entry (FDE) 629 class FDE : public FrameEntry { 630 public: 631 FDE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint64_t CIEPointer, 632 uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie, 633 std::optional<uint64_t> LSDAAddress, Triple::ArchType Arch) 634 : FrameEntry(FK_FDE, IsDWARF64, Offset, Length, 635 Cie ? Cie->getCodeAlignmentFactor() : 0, 636 Cie ? Cie->getDataAlignmentFactor() : 0, Arch), 637 CIEPointer(CIEPointer), InitialLocation(InitialLocation), 638 AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {} 639 640 ~FDE() override = default; 641 642 const CIE *getLinkedCIE() const { return LinkedCIE; } 643 uint64_t getCIEPointer() const { return CIEPointer; } 644 uint64_t getInitialLocation() const { return InitialLocation; } 645 uint64_t getAddressRange() const { return AddressRange; } 646 std::optional<uint64_t> getLSDAAddress() const { return LSDAAddress; } 647 648 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override; 649 650 static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; } 651 652 private: 653 /// The following fields are defined in section 6.4.1 of the DWARFv3 standard. 654 /// Note that CIE pointers in EH FDEs, unlike DWARF FDEs, contain relative 655 /// offsets to the linked CIEs. See the following link for more info: 656 /// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html 657 const uint64_t CIEPointer; 658 const uint64_t InitialLocation; 659 const uint64_t AddressRange; 660 const CIE *LinkedCIE; 661 const std::optional<uint64_t> LSDAAddress; 662 }; 663 664 } // end namespace dwarf 665 666 /// A parsed .debug_frame or .eh_frame section 667 class DWARFDebugFrame { 668 const Triple::ArchType Arch; 669 // True if this is parsing an eh_frame section. 670 const bool IsEH; 671 // Not zero for sane pointer values coming out of eh_frame 672 const uint64_t EHFrameAddress; 673 674 std::vector<std::unique_ptr<dwarf::FrameEntry>> Entries; 675 using iterator = pointee_iterator<decltype(Entries)::const_iterator>; 676 677 /// Return the entry at the given offset or nullptr. 678 dwarf::FrameEntry *getEntryAtOffset(uint64_t Offset) const; 679 680 public: 681 // If IsEH is true, assume it is a .eh_frame section. Otherwise, 682 // it is a .debug_frame section. EHFrameAddress should be different 683 // than zero for correct parsing of .eh_frame addresses when they 684 // use a PC-relative encoding. 685 DWARFDebugFrame(Triple::ArchType Arch, 686 bool IsEH = false, uint64_t EHFrameAddress = 0); 687 ~DWARFDebugFrame(); 688 689 /// Dump the section data into the given stream. 690 void dump(raw_ostream &OS, DIDumpOptions DumpOpts, 691 std::optional<uint64_t> Offset) const; 692 693 /// Parse the section from raw data. \p Data is assumed to contain the whole 694 /// frame section contents to be parsed. 695 Error parse(DWARFDataExtractor Data); 696 697 /// Return whether the section has any entries. 698 bool empty() const { return Entries.empty(); } 699 700 /// DWARF Frame entries accessors 701 iterator begin() const { return Entries.begin(); } 702 iterator end() const { return Entries.end(); } 703 iterator_range<iterator> entries() const { 704 return iterator_range<iterator>(Entries.begin(), Entries.end()); 705 } 706 707 uint64_t getEHFrameAddress() const { return EHFrameAddress; } 708 }; 709 710 } // end namespace llvm 711 712 #endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H 713