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