1 //===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the declaration of the MCDwarfFile to support the dwarf 11 // .file directive and the .loc directive. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_MC_MCDWARF_H 16 #define LLVM_MC_MCDWARF_H 17 18 #include "llvm/ADT/MapVector.h" 19 #include "llvm/ADT/Optional.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/StringMap.h" 22 #include "llvm/ADT/StringRef.h" 23 #include "llvm/MC/MCSection.h" 24 #include "llvm/Support/Error.h" 25 #include "llvm/Support/MD5.h" 26 #include <cassert> 27 #include <cstdint> 28 #include <string> 29 #include <utility> 30 #include <vector> 31 32 namespace llvm { 33 34 template <typename T> class ArrayRef; 35 class MCAsmBackend; 36 class MCContext; 37 class MCDwarfLineStr; 38 class MCObjectStreamer; 39 class MCStreamer; 40 class MCSymbol; 41 class raw_ostream; 42 class SMLoc; 43 class SourceMgr; 44 45 /// Instances of this class represent the name of the dwarf 46 /// .file directive and its associated dwarf file number in the MC file, 47 /// and MCDwarfFile's are created and uniqued by the MCContext class where 48 /// the file number for each is its index into the vector of DwarfFiles (note 49 /// index 0 is not used and not a valid dwarf file number). 50 struct MCDwarfFile { 51 // The base name of the file without its directory path. 52 std::string Name; 53 54 // The index into the list of directory names for this file name. 55 unsigned DirIndex; 56 57 /// The MD5 checksum, if there is one. Non-owning pointer to data allocated 58 /// in MCContext. 59 MD5::MD5Result *Checksum = nullptr; 60 61 /// The source code of the file. Non-owning reference to data allocated in 62 /// MCContext. 63 Optional<StringRef> Source; 64 }; 65 66 /// Instances of this class represent the information from a 67 /// dwarf .loc directive. 68 class MCDwarfLoc { 69 uint32_t FileNum; 70 uint32_t Line; 71 uint16_t Column; 72 // Flags (see #define's below) 73 uint8_t Flags; 74 uint8_t Isa; 75 uint32_t Discriminator; 76 77 // Flag that indicates the initial value of the is_stmt_start flag. 78 #define DWARF2_LINE_DEFAULT_IS_STMT 1 79 80 #define DWARF2_FLAG_IS_STMT (1 << 0) 81 #define DWARF2_FLAG_BASIC_BLOCK (1 << 1) 82 #define DWARF2_FLAG_PROLOGUE_END (1 << 2) 83 #define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3) 84 85 private: // MCContext manages these 86 friend class MCContext; 87 friend class MCDwarfLineEntry; 88 MCDwarfLoc(unsigned fileNum,unsigned line,unsigned column,unsigned flags,unsigned isa,unsigned discriminator)89 MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags, 90 unsigned isa, unsigned discriminator) 91 : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa), 92 Discriminator(discriminator) {} 93 94 // Allow the default copy constructor and assignment operator to be used 95 // for an MCDwarfLoc object. 96 97 public: 98 /// Get the FileNum of this MCDwarfLoc. getFileNum()99 unsigned getFileNum() const { return FileNum; } 100 101 /// Get the Line of this MCDwarfLoc. getLine()102 unsigned getLine() const { return Line; } 103 104 /// Get the Column of this MCDwarfLoc. getColumn()105 unsigned getColumn() const { return Column; } 106 107 /// Get the Flags of this MCDwarfLoc. getFlags()108 unsigned getFlags() const { return Flags; } 109 110 /// Get the Isa of this MCDwarfLoc. getIsa()111 unsigned getIsa() const { return Isa; } 112 113 /// Get the Discriminator of this MCDwarfLoc. getDiscriminator()114 unsigned getDiscriminator() const { return Discriminator; } 115 116 /// Set the FileNum of this MCDwarfLoc. setFileNum(unsigned fileNum)117 void setFileNum(unsigned fileNum) { FileNum = fileNum; } 118 119 /// Set the Line of this MCDwarfLoc. setLine(unsigned line)120 void setLine(unsigned line) { Line = line; } 121 122 /// Set the Column of this MCDwarfLoc. setColumn(unsigned column)123 void setColumn(unsigned column) { 124 assert(column <= UINT16_MAX); 125 Column = column; 126 } 127 128 /// Set the Flags of this MCDwarfLoc. setFlags(unsigned flags)129 void setFlags(unsigned flags) { 130 assert(flags <= UINT8_MAX); 131 Flags = flags; 132 } 133 134 /// Set the Isa of this MCDwarfLoc. setIsa(unsigned isa)135 void setIsa(unsigned isa) { 136 assert(isa <= UINT8_MAX); 137 Isa = isa; 138 } 139 140 /// Set the Discriminator of this MCDwarfLoc. setDiscriminator(unsigned discriminator)141 void setDiscriminator(unsigned discriminator) { 142 Discriminator = discriminator; 143 } 144 }; 145 146 /// Instances of this class represent the line information for 147 /// the dwarf line table entries. Which is created after a machine 148 /// instruction is assembled and uses an address from a temporary label 149 /// created at the current address in the current section and the info from 150 /// the last .loc directive seen as stored in the context. 151 class MCDwarfLineEntry : public MCDwarfLoc { 152 MCSymbol *Label; 153 154 private: 155 // Allow the default copy constructor and assignment operator to be used 156 // for an MCDwarfLineEntry object. 157 158 public: 159 // Constructor to create an MCDwarfLineEntry given a symbol and the dwarf loc. MCDwarfLineEntry(MCSymbol * label,const MCDwarfLoc loc)160 MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc) 161 : MCDwarfLoc(loc), Label(label) {} 162 getLabel()163 MCSymbol *getLabel() const { return Label; } 164 165 // This is called when an instruction is assembled into the specified 166 // section and if there is information from the last .loc directive that 167 // has yet to have a line entry made for it is made. 168 static void Make(MCObjectStreamer *MCOS, MCSection *Section); 169 }; 170 171 /// Instances of this class represent the line information for a compile 172 /// unit where machine instructions have been assembled after seeing .loc 173 /// directives. This is the information used to build the dwarf line 174 /// table for a section. 175 class MCLineSection { 176 public: 177 // Add an entry to this MCLineSection's line entries. addLineEntry(const MCDwarfLineEntry & LineEntry,MCSection * Sec)178 void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) { 179 MCLineDivisions[Sec].push_back(LineEntry); 180 } 181 182 using MCDwarfLineEntryCollection = std::vector<MCDwarfLineEntry>; 183 using iterator = MCDwarfLineEntryCollection::iterator; 184 using const_iterator = MCDwarfLineEntryCollection::const_iterator; 185 using MCLineDivisionMap = MapVector<MCSection *, MCDwarfLineEntryCollection>; 186 187 private: 188 // A collection of MCDwarfLineEntry for each section. 189 MCLineDivisionMap MCLineDivisions; 190 191 public: 192 // Returns the collection of MCDwarfLineEntry for a given Compile Unit ID. getMCLineEntries()193 const MCLineDivisionMap &getMCLineEntries() const { 194 return MCLineDivisions; 195 } 196 }; 197 198 struct MCDwarfLineTableParams { 199 /// First special line opcode - leave room for the standard opcodes. 200 /// Note: If you want to change this, you'll have to update the 201 /// "StandardOpcodeLengths" table that is emitted in 202 /// \c Emit(). 203 uint8_t DWARF2LineOpcodeBase = 13; 204 /// Minimum line offset in a special line info. opcode. The value 205 /// -5 was chosen to give a reasonable range of values. 206 int8_t DWARF2LineBase = -5; 207 /// Range of line offsets in a special line info. opcode. 208 uint8_t DWARF2LineRange = 14; 209 }; 210 211 struct MCDwarfLineTableHeader { 212 MCSymbol *Label = nullptr; 213 SmallVector<std::string, 3> MCDwarfDirs; 214 SmallVector<MCDwarfFile, 3> MCDwarfFiles; 215 StringMap<unsigned> SourceIdMap; 216 std::string CompilationDir; 217 MCDwarfFile RootFile; 218 bool HasSource = false; 219 private: 220 bool HasAllMD5 = true; 221 bool HasAnyMD5 = false; 222 223 public: 224 MCDwarfLineTableHeader() = default; 225 226 Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName, 227 MD5::MD5Result *Checksum, 228 Optional<StringRef> &Source, 229 unsigned FileNumber = 0); 230 std::pair<MCSymbol *, MCSymbol *> 231 Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, 232 Optional<MCDwarfLineStr> &LineStr) const; 233 std::pair<MCSymbol *, MCSymbol *> 234 Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, 235 ArrayRef<char> SpecialOpcodeLengths, 236 Optional<MCDwarfLineStr> &LineStr) const; resetMD5UsageMCDwarfLineTableHeader237 void resetMD5Usage() { 238 HasAllMD5 = true; 239 HasAnyMD5 = false; 240 } trackMD5UsageMCDwarfLineTableHeader241 void trackMD5Usage(bool MD5Used) { 242 HasAllMD5 &= MD5Used; 243 HasAnyMD5 |= MD5Used; 244 } isMD5UsageConsistentMCDwarfLineTableHeader245 bool isMD5UsageConsistent() const { 246 return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5); 247 } 248 249 private: 250 void emitV2FileDirTables(MCStreamer *MCOS) const; 251 void emitV5FileDirTables(MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr, 252 StringRef CtxCompilationDir) const; 253 }; 254 255 class MCDwarfDwoLineTable { 256 MCDwarfLineTableHeader Header; 257 258 public: maybeSetRootFile(StringRef Directory,StringRef FileName,MD5::MD5Result * Checksum,Optional<StringRef> Source)259 void maybeSetRootFile(StringRef Directory, StringRef FileName, 260 MD5::MD5Result *Checksum, Optional<StringRef> Source) { 261 if (!Header.RootFile.Name.empty()) 262 return; 263 Header.CompilationDir = Directory; 264 Header.RootFile.Name = FileName; 265 Header.RootFile.DirIndex = 0; 266 Header.RootFile.Checksum = Checksum; 267 Header.RootFile.Source = Source; 268 Header.trackMD5Usage(Checksum); 269 Header.HasSource = Source.hasValue(); 270 } 271 getFile(StringRef Directory,StringRef FileName,MD5::MD5Result * Checksum,Optional<StringRef> Source)272 unsigned getFile(StringRef Directory, StringRef FileName, 273 MD5::MD5Result *Checksum, Optional<StringRef> Source) { 274 return cantFail(Header.tryGetFile(Directory, FileName, Checksum, Source)); 275 } 276 277 void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, 278 MCSection *Section) const; 279 }; 280 281 class MCDwarfLineTable { 282 MCDwarfLineTableHeader Header; 283 MCLineSection MCLineSections; 284 285 public: 286 // This emits the Dwarf file and the line tables for all Compile Units. 287 static void Emit(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params); 288 289 // This emits the Dwarf file and the line tables for a given Compile Unit. 290 void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params, 291 Optional<MCDwarfLineStr> &LineStr) const; 292 293 Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName, 294 MD5::MD5Result *Checksum, 295 Optional<StringRef> Source, 296 unsigned FileNumber = 0); 297 unsigned getFile(StringRef &Directory, StringRef &FileName, 298 MD5::MD5Result *Checksum, Optional<StringRef> &Source, 299 unsigned FileNumber = 0) { 300 return cantFail(tryGetFile(Directory, FileName, Checksum, Source, 301 FileNumber)); 302 } 303 setRootFile(StringRef Directory,StringRef FileName,MD5::MD5Result * Checksum,Optional<StringRef> Source)304 void setRootFile(StringRef Directory, StringRef FileName, 305 MD5::MD5Result *Checksum, Optional<StringRef> Source) { 306 Header.CompilationDir = Directory; 307 Header.RootFile.Name = FileName; 308 Header.RootFile.DirIndex = 0; 309 Header.RootFile.Checksum = Checksum; 310 Header.RootFile.Source = Source; 311 Header.trackMD5Usage(Checksum); 312 Header.HasSource = Source.hasValue(); 313 } 314 resetRootFile()315 void resetRootFile() { 316 assert(Header.MCDwarfFiles.empty()); 317 Header.RootFile.Name.clear(); 318 Header.resetMD5Usage(); 319 Header.HasSource = false; 320 } 321 hasRootFile()322 bool hasRootFile() const { return !Header.RootFile.Name.empty(); } 323 324 // Report whether MD5 usage has been consistent (all-or-none). isMD5UsageConsistent()325 bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); } 326 getLabel()327 MCSymbol *getLabel() const { 328 return Header.Label; 329 } 330 setLabel(MCSymbol * Label)331 void setLabel(MCSymbol *Label) { 332 Header.Label = Label; 333 } 334 getMCDwarfDirs()335 const SmallVectorImpl<std::string> &getMCDwarfDirs() const { 336 return Header.MCDwarfDirs; 337 } 338 getMCDwarfDirs()339 SmallVectorImpl<std::string> &getMCDwarfDirs() { 340 return Header.MCDwarfDirs; 341 } 342 getMCDwarfFiles()343 const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const { 344 return Header.MCDwarfFiles; 345 } 346 getMCDwarfFiles()347 SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() { 348 return Header.MCDwarfFiles; 349 } 350 getMCLineSections()351 const MCLineSection &getMCLineSections() const { 352 return MCLineSections; 353 } getMCLineSections()354 MCLineSection &getMCLineSections() { 355 return MCLineSections; 356 } 357 }; 358 359 class MCDwarfLineAddr { 360 public: 361 /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas. 362 static void Encode(MCContext &Context, MCDwarfLineTableParams Params, 363 int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS); 364 365 /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas using 366 /// fixed length operands. 367 static bool FixedEncode(MCContext &Context, 368 MCDwarfLineTableParams Params, 369 int64_t LineDelta, uint64_t AddrDelta, 370 raw_ostream &OS, uint32_t *Offset, uint32_t *Size); 371 372 /// Utility function to emit the encoding to a streamer. 373 static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, 374 int64_t LineDelta, uint64_t AddrDelta); 375 }; 376 377 class MCGenDwarfInfo { 378 public: 379 // 380 // When generating dwarf for assembly source files this emits the Dwarf 381 // sections. 382 // 383 static void Emit(MCStreamer *MCOS); 384 }; 385 386 // When generating dwarf for assembly source files this is the info that is 387 // needed to be gathered for each symbol that will have a dwarf label. 388 class MCGenDwarfLabelEntry { 389 private: 390 // Name of the symbol without a leading underbar, if any. 391 StringRef Name; 392 // The dwarf file number this symbol is in. 393 unsigned FileNumber; 394 // The line number this symbol is at. 395 unsigned LineNumber; 396 // The low_pc for the dwarf label is taken from this symbol. 397 MCSymbol *Label; 398 399 public: MCGenDwarfLabelEntry(StringRef name,unsigned fileNumber,unsigned lineNumber,MCSymbol * label)400 MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber, 401 MCSymbol *label) 402 : Name(name), FileNumber(fileNumber), LineNumber(lineNumber), 403 Label(label) {} 404 getName()405 StringRef getName() const { return Name; } getFileNumber()406 unsigned getFileNumber() const { return FileNumber; } getLineNumber()407 unsigned getLineNumber() const { return LineNumber; } getLabel()408 MCSymbol *getLabel() const { return Label; } 409 410 // This is called when label is created when we are generating dwarf for 411 // assembly source files. 412 static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, 413 SMLoc &Loc); 414 }; 415 416 class MCCFIInstruction { 417 public: 418 enum OpType { 419 OpSameValue, 420 OpRememberState, 421 OpRestoreState, 422 OpOffset, 423 OpDefCfaRegister, 424 OpDefCfaOffset, 425 OpDefCfa, 426 OpRelOffset, 427 OpAdjustCfaOffset, 428 OpEscape, 429 OpRestore, 430 OpUndefined, 431 OpRegister, 432 OpWindowSave, 433 OpGnuArgsSize 434 }; 435 436 private: 437 OpType Operation; 438 MCSymbol *Label; 439 unsigned Register; 440 union { 441 int Offset; 442 unsigned Register2; 443 }; 444 std::vector<char> Values; 445 MCCFIInstruction(OpType Op,MCSymbol * L,unsigned R,int O,StringRef V)446 MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) 447 : Operation(Op), Label(L), Register(R), Offset(O), 448 Values(V.begin(), V.end()) { 449 assert(Op != OpRegister); 450 } 451 MCCFIInstruction(OpType Op,MCSymbol * L,unsigned R1,unsigned R2)452 MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) 453 : Operation(Op), Label(L), Register(R1), Register2(R2) { 454 assert(Op == OpRegister); 455 } 456 457 public: 458 /// .cfi_def_cfa defines a rule for computing CFA as: take address from 459 /// Register and add Offset to it. createDefCfa(MCSymbol * L,unsigned Register,int Offset)460 static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register, 461 int Offset) { 462 return MCCFIInstruction(OpDefCfa, L, Register, -Offset, ""); 463 } 464 465 /// .cfi_def_cfa_register modifies a rule for computing CFA. From now 466 /// on Register will be used instead of the old one. Offset remains the same. createDefCfaRegister(MCSymbol * L,unsigned Register)467 static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) { 468 return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, ""); 469 } 470 471 /// .cfi_def_cfa_offset modifies a rule for computing CFA. Register 472 /// remains the same, but offset is new. Note that it is the absolute offset 473 /// that will be added to a defined register to the compute CFA address. createDefCfaOffset(MCSymbol * L,int Offset)474 static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) { 475 return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, ""); 476 } 477 478 /// .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but 479 /// Offset is a relative value that is added/subtracted from the previous 480 /// offset. createAdjustCfaOffset(MCSymbol * L,int Adjustment)481 static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) { 482 return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, ""); 483 } 484 485 /// .cfi_offset Previous value of Register is saved at offset Offset 486 /// from CFA. createOffset(MCSymbol * L,unsigned Register,int Offset)487 static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, 488 int Offset) { 489 return MCCFIInstruction(OpOffset, L, Register, Offset, ""); 490 } 491 492 /// .cfi_rel_offset Previous value of Register is saved at offset 493 /// Offset from the current CFA register. This is transformed to .cfi_offset 494 /// using the known displacement of the CFA register from the CFA. createRelOffset(MCSymbol * L,unsigned Register,int Offset)495 static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register, 496 int Offset) { 497 return MCCFIInstruction(OpRelOffset, L, Register, Offset, ""); 498 } 499 500 /// .cfi_register Previous value of Register1 is saved in 501 /// register Register2. createRegister(MCSymbol * L,unsigned Register1,unsigned Register2)502 static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, 503 unsigned Register2) { 504 return MCCFIInstruction(OpRegister, L, Register1, Register2); 505 } 506 507 /// .cfi_window_save SPARC register window is saved. createWindowSave(MCSymbol * L)508 static MCCFIInstruction createWindowSave(MCSymbol *L) { 509 return MCCFIInstruction(OpWindowSave, L, 0, 0, ""); 510 } 511 512 /// .cfi_restore says that the rule for Register is now the same as it 513 /// was at the beginning of the function, after all initial instructions added 514 /// by .cfi_startproc were executed. createRestore(MCSymbol * L,unsigned Register)515 static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) { 516 return MCCFIInstruction(OpRestore, L, Register, 0, ""); 517 } 518 519 /// .cfi_undefined From now on the previous value of Register can't be 520 /// restored anymore. createUndefined(MCSymbol * L,unsigned Register)521 static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) { 522 return MCCFIInstruction(OpUndefined, L, Register, 0, ""); 523 } 524 525 /// .cfi_same_value Current value of Register is the same as in the 526 /// previous frame. I.e., no restoration is needed. createSameValue(MCSymbol * L,unsigned Register)527 static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) { 528 return MCCFIInstruction(OpSameValue, L, Register, 0, ""); 529 } 530 531 /// .cfi_remember_state Save all current rules for all registers. createRememberState(MCSymbol * L)532 static MCCFIInstruction createRememberState(MCSymbol *L) { 533 return MCCFIInstruction(OpRememberState, L, 0, 0, ""); 534 } 535 536 /// .cfi_restore_state Restore the previously saved state. createRestoreState(MCSymbol * L)537 static MCCFIInstruction createRestoreState(MCSymbol *L) { 538 return MCCFIInstruction(OpRestoreState, L, 0, 0, ""); 539 } 540 541 /// .cfi_escape Allows the user to add arbitrary bytes to the unwind 542 /// info. createEscape(MCSymbol * L,StringRef Vals)543 static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) { 544 return MCCFIInstruction(OpEscape, L, 0, 0, Vals); 545 } 546 547 /// A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE createGnuArgsSize(MCSymbol * L,int Size)548 static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size) { 549 return MCCFIInstruction(OpGnuArgsSize, L, 0, Size, ""); 550 } 551 getOperation()552 OpType getOperation() const { return Operation; } getLabel()553 MCSymbol *getLabel() const { return Label; } 554 getRegister()555 unsigned getRegister() const { 556 assert(Operation == OpDefCfa || Operation == OpOffset || 557 Operation == OpRestore || Operation == OpUndefined || 558 Operation == OpSameValue || Operation == OpDefCfaRegister || 559 Operation == OpRelOffset || Operation == OpRegister); 560 return Register; 561 } 562 getRegister2()563 unsigned getRegister2() const { 564 assert(Operation == OpRegister); 565 return Register2; 566 } 567 getOffset()568 int getOffset() const { 569 assert(Operation == OpDefCfa || Operation == OpOffset || 570 Operation == OpRelOffset || Operation == OpDefCfaOffset || 571 Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize); 572 return Offset; 573 } 574 getValues()575 StringRef getValues() const { 576 assert(Operation == OpEscape); 577 return StringRef(&Values[0], Values.size()); 578 } 579 }; 580 581 struct MCDwarfFrameInfo { 582 MCDwarfFrameInfo() = default; 583 584 MCSymbol *Begin = nullptr; 585 MCSymbol *End = nullptr; 586 const MCSymbol *Personality = nullptr; 587 const MCSymbol *Lsda = nullptr; 588 std::vector<MCCFIInstruction> Instructions; 589 unsigned CurrentCfaRegister = 0; 590 unsigned PersonalityEncoding = 0; 591 unsigned LsdaEncoding = 0; 592 uint32_t CompactUnwindEncoding = 0; 593 bool IsSignalFrame = false; 594 bool IsSimple = false; 595 unsigned RAReg = static_cast<unsigned>(INT_MAX); 596 }; 597 598 class MCDwarfFrameEmitter { 599 public: 600 // 601 // This emits the frame info section. 602 // 603 static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH); 604 static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta); 605 static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, 606 raw_ostream &OS); 607 }; 608 609 } // end namespace llvm 610 611 #endif // LLVM_MC_MCDWARF_H 612