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