1 //===- MCSection.h - Machine Code Sections ----------------------*- 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 declares the MCSection class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_MC_MCSECTION_H 14 #define LLVM_MC_MCSECTION_H 15 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/SmallString.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/MC/MCFixup.h" 21 #include "llvm/MC/MCInst.h" 22 #include "llvm/MC/SectionKind.h" 23 #include "llvm/Support/Alignment.h" 24 #include "llvm/Support/Compiler.h" 25 #include <cassert> 26 #include <utility> 27 28 namespace llvm { 29 30 class MCAsmInfo; 31 class MCAssembler; 32 class MCContext; 33 class MCExpr; 34 class MCFragment; 35 class MCObjectStreamer; 36 class MCSymbol; 37 class MCSection; 38 class MCSubtargetInfo; 39 class raw_ostream; 40 class Triple; 41 42 /// Instances of this class represent a uniqued identifier for a section in the 43 /// current translation unit. The MCContext class uniques and creates these. 44 class LLVM_ABI MCSection { 45 public: 46 friend MCAssembler; 47 friend MCObjectStreamer; 48 friend class MCFragment; 49 friend class MCEncodedFragment; 50 friend class MCRelaxableFragment; 51 static constexpr unsigned NonUniqueID = ~0U; 52 53 enum SectionVariant { 54 SV_COFF = 0, 55 SV_ELF, 56 SV_GOFF, 57 SV_MachO, 58 SV_Wasm, 59 SV_XCOFF, 60 SV_SPIRV, 61 SV_DXContainer, 62 }; 63 64 /// Express the state of bundle locked groups while emitting code. 65 enum BundleLockStateType { 66 NotBundleLocked, 67 BundleLocked, 68 BundleLockedAlignToEnd 69 }; 70 71 struct iterator { 72 MCFragment *F = nullptr; 73 iterator() = default; iteratoriterator74 explicit iterator(MCFragment *F) : F(F) {} 75 MCFragment &operator*() const { return *F; } 76 bool operator==(const iterator &O) const { return F == O.F; } 77 bool operator!=(const iterator &O) const { return F != O.F; } 78 iterator &operator++(); 79 }; 80 81 struct FragList { 82 MCFragment *Head = nullptr; 83 MCFragment *Tail = nullptr; 84 }; 85 86 private: 87 // At parse time, this holds the fragment list of the current subsection. At 88 // layout time, this holds the concatenated fragment lists of all subsections. 89 FragList *CurFragList; 90 MCSymbol *Begin; 91 MCSymbol *End = nullptr; 92 /// The alignment requirement of this section. 93 Align Alignment; 94 /// The section index in the assemblers section list. 95 unsigned Ordinal = 0; 96 97 /// Keeping track of bundle-locked state. 98 BundleLockStateType BundleLockState = NotBundleLocked; 99 100 /// Current nesting depth of bundle_lock directives. 101 unsigned BundleLockNestingDepth = 0; 102 103 /// We've seen a bundle_lock directive but not its first instruction 104 /// yet. 105 bool BundleGroupBeforeFirstInst : 1; 106 107 /// Whether this section has had instructions emitted into it. 108 bool HasInstructions : 1; 109 110 bool IsRegistered : 1; 111 112 bool IsText : 1; 113 114 bool IsVirtual : 1; 115 116 /// Whether the section contains linker-relaxable fragments. If true, the 117 /// offset between two locations may not be fully resolved. 118 bool LinkerRelaxable : 1; 119 120 // Mapping from subsection number to fragment list. At layout time, the 121 // subsection 0 list is replaced with concatenated fragments from all 122 // subsections. 123 SmallVector<std::pair<unsigned, FragList>, 1> Subsections; 124 125 // Content and fixup storage for fragments 126 SmallVector<char, 0> ContentStorage; 127 SmallVector<MCFixup, 0> FixupStorage; 128 SmallVector<MCOperand, 0> MCOperandStorage; 129 130 protected: 131 // TODO Make Name private when possible. 132 StringRef Name; 133 SectionVariant Variant; 134 135 MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsVirtual, 136 MCSymbol *Begin); 137 // Protected non-virtual dtor prevents destroy through a base class pointer. ~MCSection()138 ~MCSection() {} 139 140 public: 141 MCSection(const MCSection &) = delete; 142 MCSection &operator=(const MCSection &) = delete; 143 getName()144 StringRef getName() const { return Name; } isText()145 bool isText() const { return IsText; } 146 getVariant()147 SectionVariant getVariant() const { return Variant; } 148 getBeginSymbol()149 MCSymbol *getBeginSymbol() { return Begin; } getBeginSymbol()150 const MCSymbol *getBeginSymbol() const { 151 return const_cast<MCSection *>(this)->getBeginSymbol(); 152 } setBeginSymbol(MCSymbol * Sym)153 void setBeginSymbol(MCSymbol *Sym) { 154 assert(!Begin); 155 Begin = Sym; 156 } 157 MCSymbol *getEndSymbol(MCContext &Ctx); 158 bool hasEnded() const; 159 getAlign()160 Align getAlign() const { return Alignment; } setAlignment(Align Value)161 void setAlignment(Align Value) { Alignment = Value; } 162 163 /// Makes sure that Alignment is at least MinAlignment. ensureMinAlignment(Align MinAlignment)164 void ensureMinAlignment(Align MinAlignment) { 165 if (Alignment < MinAlignment) 166 Alignment = MinAlignment; 167 } 168 getOrdinal()169 unsigned getOrdinal() const { return Ordinal; } setOrdinal(unsigned Value)170 void setOrdinal(unsigned Value) { Ordinal = Value; } 171 getBundleLockState()172 BundleLockStateType getBundleLockState() const { return BundleLockState; } 173 void setBundleLockState(BundleLockStateType NewState); isBundleLocked()174 bool isBundleLocked() const { return BundleLockState != NotBundleLocked; } 175 isBundleGroupBeforeFirstInst()176 bool isBundleGroupBeforeFirstInst() const { 177 return BundleGroupBeforeFirstInst; 178 } setBundleGroupBeforeFirstInst(bool IsFirst)179 void setBundleGroupBeforeFirstInst(bool IsFirst) { 180 BundleGroupBeforeFirstInst = IsFirst; 181 } 182 hasInstructions()183 bool hasInstructions() const { return HasInstructions; } setHasInstructions(bool Value)184 void setHasInstructions(bool Value) { HasInstructions = Value; } 185 isRegistered()186 bool isRegistered() const { return IsRegistered; } setIsRegistered(bool Value)187 void setIsRegistered(bool Value) { IsRegistered = Value; } 188 isLinkerRelaxable()189 bool isLinkerRelaxable() const { return LinkerRelaxable; } setLinkerRelaxable()190 void setLinkerRelaxable() { LinkerRelaxable = true; } 191 getDummyFragment()192 MCFragment &getDummyFragment() { return *Subsections[0].second.Head; } 193 curFragList()194 FragList *curFragList() const { return CurFragList; } begin()195 iterator begin() const { return iterator(CurFragList->Head); } end()196 iterator end() const { return {}; } 197 198 void dump(DenseMap<const MCFragment *, SmallVector<const MCSymbol *, 0>> 199 *FragToSyms = nullptr) const; 200 201 virtual void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 202 raw_ostream &OS, 203 uint32_t Subsection) const = 0; 204 205 /// Return true if a .align directive should use "optimized nops" to fill 206 /// instead of 0s. 207 virtual bool useCodeAlign() const = 0; 208 209 /// Check whether this section is "virtual", that is has no actual object 210 /// file contents. isVirtualSection()211 bool isVirtualSection() const { return IsVirtual; } 212 213 virtual StringRef getVirtualSectionKind() const; 214 }; 215 216 // Represents a contiguous piece of code or data within a section. Its size is 217 // determined by MCAssembler::layout. All subclasses must have trivial 218 // destructors. 219 class MCFragment { 220 friend class MCAssembler; 221 friend class MCObjectStreamer; 222 friend class MCSection; 223 224 public: 225 enum FragmentType : uint8_t { 226 FT_Data, 227 FT_Relaxable, 228 FT_Align, 229 FT_Fill, 230 FT_LEB, 231 FT_Nops, 232 FT_Org, 233 FT_Dwarf, 234 FT_DwarfFrame, 235 FT_BoundaryAlign, 236 FT_SymbolId, 237 FT_CVInlineLines, 238 FT_CVDefRange, 239 FT_PseudoProbe, 240 }; 241 242 private: 243 // The next fragment within the section. 244 MCFragment *Next = nullptr; 245 246 /// The data for the section this fragment is in. 247 MCSection *Parent = nullptr; 248 249 /// The offset of this fragment in its section. 250 uint64_t Offset = 0; 251 252 /// The layout order of this fragment. 253 unsigned LayoutOrder = 0; 254 255 FragmentType Kind; 256 257 protected: 258 /// Used by subclasses for better packing. 259 /// 260 /// MCEncodedFragment 261 bool HasInstructions : 1; 262 bool AlignToBundleEnd : 1; 263 /// MCDataFragment 264 bool LinkerRelaxable : 1; 265 /// MCRelaxableFragment: x86-specific 266 bool AllowAutoPadding : 1; 267 268 LLVM_ABI MCFragment(FragmentType Kind, bool HasInstructions); 269 270 public: 271 MCFragment() = delete; 272 MCFragment(const MCFragment &) = delete; 273 MCFragment &operator=(const MCFragment &) = delete; 274 getNext()275 MCFragment *getNext() const { return Next; } 276 getKind()277 FragmentType getKind() const { return Kind; } 278 getParent()279 MCSection *getParent() const { return Parent; } setParent(MCSection * Value)280 void setParent(MCSection *Value) { Parent = Value; } 281 282 LLVM_ABI const MCSymbol *getAtom() const; 283 getLayoutOrder()284 unsigned getLayoutOrder() const { return LayoutOrder; } setLayoutOrder(unsigned Value)285 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 286 287 /// Does this fragment have instructions emitted into it? By default 288 /// this is false, but specific fragment types may set it to true. hasInstructions()289 bool hasInstructions() const { return HasInstructions; } 290 isLinkerRelaxable()291 bool isLinkerRelaxable() const { return LinkerRelaxable; } setLinkerRelaxable()292 void setLinkerRelaxable() { LinkerRelaxable = true; } 293 294 LLVM_ABI void dump() const; 295 }; 296 297 /// Interface implemented by fragments that contain encoded instructions and/or 298 /// data. 299 class MCEncodedFragment : public MCFragment { 300 uint8_t BundlePadding = 0; 301 uint32_t ContentSize = 0; 302 uint64_t ContentStart = 0; 303 uint32_t FixupStart = 0; 304 uint32_t FixupEnd = 0; 305 306 protected: MCEncodedFragment(MCFragment::FragmentType FType,bool HasInstructions)307 MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions) 308 : MCFragment(FType, HasInstructions) {} 309 310 /// The MCSubtargetInfo in effect when the instruction was encoded. 311 /// It must be non-null for instructions. 312 const MCSubtargetInfo *STI = nullptr; 313 314 public: classof(const MCFragment * F)315 static bool classof(const MCFragment *F) { 316 MCFragment::FragmentType Kind = F->getKind(); 317 switch (Kind) { 318 default: 319 return false; 320 case MCFragment::FT_Relaxable: 321 case MCFragment::FT_Data: 322 case MCFragment::FT_Dwarf: 323 case MCFragment::FT_DwarfFrame: 324 case MCFragment::FT_LEB: 325 case MCFragment::FT_PseudoProbe: 326 case MCFragment::FT_CVInlineLines: 327 case MCFragment::FT_CVDefRange: 328 return true; 329 } 330 } 331 332 /// Should this fragment be placed at the end of an aligned bundle? alignToBundleEnd()333 bool alignToBundleEnd() const { return AlignToBundleEnd; } setAlignToBundleEnd(bool V)334 void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } 335 336 /// Get the padding size that must be inserted before this fragment. 337 /// Used for bundling. By default, no padding is inserted. 338 /// Note that padding size is restricted to 8 bits. This is an optimization 339 /// to reduce the amount of space used for each fragment. In practice, larger 340 /// padding should never be required. getBundlePadding()341 uint8_t getBundlePadding() const { return BundlePadding; } 342 343 /// Set the padding size for this fragment. By default it's a no-op, 344 /// and only some fragments have a meaningful implementation. setBundlePadding(uint8_t N)345 void setBundlePadding(uint8_t N) { BundlePadding = N; } 346 347 /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded. 348 /// Guaranteed to be non-null if hasInstructions() == true getSubtargetInfo()349 const MCSubtargetInfo *getSubtargetInfo() const { return STI; } 350 351 /// Record that the fragment contains instructions with the MCSubtargetInfo in 352 /// effect when the instruction was encoded. setHasInstructions(const MCSubtargetInfo & STI)353 void setHasInstructions(const MCSubtargetInfo &STI) { 354 HasInstructions = true; 355 this->STI = &STI; 356 } 357 getAllowAutoPadding()358 bool getAllowAutoPadding() const { return AllowAutoPadding; } setAllowAutoPadding(bool V)359 void setAllowAutoPadding(bool V) { AllowAutoPadding = V; } 360 361 // Content-related functions manage parent's storage using ContentStart and 362 // ContentSize. clearContents()363 void clearContents() { ContentSize = 0; } 364 // Get a SmallVector reference. The caller should call doneAppending to update 365 // `ContentSize`. getContentsForAppending()366 SmallVectorImpl<char> &getContentsForAppending() { 367 SmallVectorImpl<char> &S = getParent()->ContentStorage; 368 if (LLVM_UNLIKELY(ContentStart + ContentSize != S.size())) { 369 // Move the elements to the end. Reserve space to avoid invalidating 370 // S.begin()+I for `append`. 371 auto I = std::exchange(ContentStart, S.size()); 372 S.reserve(S.size() + ContentSize); 373 S.append(S.begin() + I, S.begin() + I + ContentSize); 374 } 375 return S; 376 } doneAppending()377 void doneAppending() { 378 ContentSize = getParent()->ContentStorage.size() - ContentStart; 379 } appendContents(ArrayRef<char> Contents)380 void appendContents(ArrayRef<char> Contents) { 381 getContentsForAppending().append(Contents.begin(), Contents.end()); 382 doneAppending(); 383 } appendContents(size_t Num,char Elt)384 void appendContents(size_t Num, char Elt) { 385 getContentsForAppending().append(Num, Elt); 386 doneAppending(); 387 } 388 LLVM_ABI void setContents(ArrayRef<char> Contents); getContents()389 MutableArrayRef<char> getContents() { 390 return MutableArrayRef(getParent()->ContentStorage) 391 .slice(ContentStart, ContentSize); 392 } getContents()393 ArrayRef<char> getContents() const { 394 return ArrayRef(getParent()->ContentStorage) 395 .slice(ContentStart, ContentSize); 396 } 397 398 // Fixup-related functions manage parent's storage using FixupStart and 399 // FixupSize. clearFixups()400 void clearFixups() { FixupEnd = FixupStart; } 401 LLVM_ABI void addFixup(MCFixup Fixup); 402 LLVM_ABI void appendFixups(ArrayRef<MCFixup> Fixups); 403 LLVM_ABI void setFixups(ArrayRef<MCFixup> Fixups); getFixups()404 MutableArrayRef<MCFixup> getFixups() { 405 return MutableArrayRef(getParent()->FixupStorage) 406 .slice(FixupStart, FixupEnd - FixupStart); 407 } getFixups()408 ArrayRef<MCFixup> getFixups() const { 409 return ArrayRef(getParent()->FixupStorage) 410 .slice(FixupStart, FixupEnd - FixupStart); 411 } 412 getSize()413 size_t getSize() const { return ContentSize; } 414 }; 415 416 /// Fragment for data and encoded instructions. 417 /// 418 class MCDataFragment : public MCEncodedFragment { 419 public: MCDataFragment()420 MCDataFragment() : MCEncodedFragment(FT_Data, false) {} 421 classof(const MCFragment * F)422 static bool classof(const MCFragment *F) { 423 return F->getKind() == MCFragment::FT_Data; 424 } 425 }; 426 427 /// A relaxable fragment holds on to its MCInst, since it may need to be 428 /// relaxed during the assembler layout and relaxation stage. 429 /// 430 class MCRelaxableFragment : public MCEncodedFragment { 431 uint32_t Opcode = 0; 432 uint32_t Flags = 0; 433 uint32_t OperandStart = 0; 434 uint32_t OperandSize = 0; 435 436 public: MCRelaxableFragment(const MCSubtargetInfo & STI)437 MCRelaxableFragment(const MCSubtargetInfo &STI) 438 : MCEncodedFragment(FT_Relaxable, true) { 439 this->STI = &STI; 440 } 441 getOpcode()442 unsigned getOpcode() const { return Opcode; } getOperands()443 ArrayRef<MCOperand> getOperands() const { 444 return MutableArrayRef(getParent()->MCOperandStorage) 445 .slice(OperandStart, OperandSize); 446 } getInst()447 MCInst getInst() const { 448 MCInst Inst; 449 Inst.setOpcode(Opcode); 450 Inst.setFlags(Flags); 451 Inst.setOperands(ArrayRef(getParent()->MCOperandStorage) 452 .slice(OperandStart, OperandSize)); 453 return Inst; 454 } setInst(const MCInst & Inst)455 void setInst(const MCInst &Inst) { 456 Opcode = Inst.getOpcode(); 457 Flags = Inst.getFlags(); 458 auto &S = getParent()->MCOperandStorage; 459 if (Inst.getNumOperands() > OperandSize) { 460 OperandStart = S.size(); 461 S.resize_for_overwrite(S.size() + Inst.getNumOperands()); 462 } 463 OperandSize = Inst.getNumOperands(); 464 llvm::copy(Inst, S.begin() + OperandStart); 465 } 466 classof(const MCFragment * F)467 static bool classof(const MCFragment *F) { 468 return F->getKind() == MCFragment::FT_Relaxable; 469 } 470 }; 471 472 class MCAlignFragment : public MCFragment { 473 /// Flag to indicate that (optimal) NOPs should be emitted instead 474 /// of using the provided value. The exact interpretation of this flag is 475 /// target dependent. 476 bool EmitNops : 1; 477 478 /// The alignment to ensure, in bytes. 479 Align Alignment; 480 481 /// The size of the integer (in bytes) of \p Value. 482 uint8_t FillLen; 483 484 /// The maximum number of bytes to emit; if the alignment 485 /// cannot be satisfied in this width then this fragment is ignored. 486 unsigned MaxBytesToEmit; 487 488 /// Value to use for filling padding bytes. 489 int64_t Fill; 490 491 /// When emitting Nops some subtargets have specific nop encodings. 492 const MCSubtargetInfo *STI = nullptr; 493 494 public: MCAlignFragment(Align Alignment,int64_t Fill,uint8_t FillLen,unsigned MaxBytesToEmit)495 MCAlignFragment(Align Alignment, int64_t Fill, uint8_t FillLen, 496 unsigned MaxBytesToEmit) 497 : MCFragment(FT_Align, false), EmitNops(false), Alignment(Alignment), 498 FillLen(FillLen), MaxBytesToEmit(MaxBytesToEmit), Fill(Fill) {} 499 getAlignment()500 Align getAlignment() const { return Alignment; } getFill()501 int64_t getFill() const { return Fill; } getFillLen()502 uint8_t getFillLen() const { return FillLen; } getMaxBytesToEmit()503 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } 504 hasEmitNops()505 bool hasEmitNops() const { return EmitNops; } setEmitNops(bool Value,const MCSubtargetInfo * STI)506 void setEmitNops(bool Value, const MCSubtargetInfo *STI) { 507 EmitNops = Value; 508 this->STI = STI; 509 } 510 getSubtargetInfo()511 const MCSubtargetInfo *getSubtargetInfo() const { return STI; } 512 classof(const MCFragment * F)513 static bool classof(const MCFragment *F) { 514 return F->getKind() == MCFragment::FT_Align; 515 } 516 }; 517 518 class MCFillFragment : public MCFragment { 519 uint8_t ValueSize; 520 /// Value to use for filling bytes. 521 uint64_t Value; 522 /// The number of bytes to insert. 523 const MCExpr &NumValues; 524 uint64_t Size = 0; 525 526 /// Source location of the directive that this fragment was created for. 527 SMLoc Loc; 528 529 public: MCFillFragment(uint64_t Value,uint8_t VSize,const MCExpr & NumValues,SMLoc Loc)530 MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues, 531 SMLoc Loc) 532 : MCFragment(FT_Fill, false), ValueSize(VSize), Value(Value), 533 NumValues(NumValues), Loc(Loc) {} 534 getValue()535 uint64_t getValue() const { return Value; } getValueSize()536 uint8_t getValueSize() const { return ValueSize; } getNumValues()537 const MCExpr &getNumValues() const { return NumValues; } getSize()538 uint64_t getSize() const { return Size; } setSize(uint64_t Value)539 void setSize(uint64_t Value) { Size = Value; } 540 getLoc()541 SMLoc getLoc() const { return Loc; } 542 classof(const MCFragment * F)543 static bool classof(const MCFragment *F) { 544 return F->getKind() == MCFragment::FT_Fill; 545 } 546 }; 547 548 class MCNopsFragment : public MCFragment { 549 /// The number of bytes to insert. 550 int64_t Size; 551 /// Maximum number of bytes allowed in each NOP instruction. 552 int64_t ControlledNopLength; 553 554 /// Source location of the directive that this fragment was created for. 555 SMLoc Loc; 556 557 /// When emitting Nops some subtargets have specific nop encodings. 558 const MCSubtargetInfo &STI; 559 560 public: MCNopsFragment(int64_t NumBytes,int64_t ControlledNopLength,SMLoc L,const MCSubtargetInfo & STI)561 MCNopsFragment(int64_t NumBytes, int64_t ControlledNopLength, SMLoc L, 562 const MCSubtargetInfo &STI) 563 : MCFragment(FT_Nops, false), Size(NumBytes), 564 ControlledNopLength(ControlledNopLength), Loc(L), STI(STI) {} 565 getNumBytes()566 int64_t getNumBytes() const { return Size; } getControlledNopLength()567 int64_t getControlledNopLength() const { return ControlledNopLength; } 568 getLoc()569 SMLoc getLoc() const { return Loc; } 570 getSubtargetInfo()571 const MCSubtargetInfo *getSubtargetInfo() const { return &STI; } 572 classof(const MCFragment * F)573 static bool classof(const MCFragment *F) { 574 return F->getKind() == MCFragment::FT_Nops; 575 } 576 }; 577 578 class MCOrgFragment : public MCFragment { 579 /// Value to use for filling bytes. 580 int8_t Value; 581 582 /// The offset this fragment should start at. 583 const MCExpr *Offset; 584 585 /// Source location of the directive that this fragment was created for. 586 SMLoc Loc; 587 588 public: MCOrgFragment(const MCExpr & Offset,int8_t Value,SMLoc Loc)589 MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc) 590 : MCFragment(FT_Org, false), Value(Value), Offset(&Offset), Loc(Loc) {} 591 getOffset()592 const MCExpr &getOffset() const { return *Offset; } 593 getValue()594 uint8_t getValue() const { return Value; } 595 getLoc()596 SMLoc getLoc() const { return Loc; } 597 classof(const MCFragment * F)598 static bool classof(const MCFragment *F) { 599 return F->getKind() == MCFragment::FT_Org; 600 } 601 }; 602 603 class MCLEBFragment final : public MCEncodedFragment { 604 /// True if this is a sleb128, false if uleb128. 605 bool IsSigned; 606 607 /// The value this fragment should contain. 608 const MCExpr *Value; 609 610 public: MCLEBFragment(const MCExpr & Value,bool IsSigned)611 MCLEBFragment(const MCExpr &Value, bool IsSigned) 612 : MCEncodedFragment(FT_LEB, false), IsSigned(IsSigned), Value(&Value) {} 613 getValue()614 const MCExpr &getValue() const { return *Value; } setValue(const MCExpr * Expr)615 void setValue(const MCExpr *Expr) { Value = Expr; } 616 isSigned()617 bool isSigned() const { return IsSigned; } 618 classof(const MCFragment * F)619 static bool classof(const MCFragment *F) { 620 return F->getKind() == MCFragment::FT_LEB; 621 } 622 }; 623 624 class MCDwarfLineAddrFragment : public MCEncodedFragment { 625 /// The value of the difference between the two line numbers 626 /// between two .loc dwarf directives. 627 int64_t LineDelta; 628 629 /// The expression for the difference of the two symbols that 630 /// make up the address delta between two .loc dwarf directives. 631 const MCExpr *AddrDelta; 632 633 public: MCDwarfLineAddrFragment(int64_t LineDelta,const MCExpr & AddrDelta)634 MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta) 635 : MCEncodedFragment(FT_Dwarf, false), LineDelta(LineDelta), 636 AddrDelta(&AddrDelta) {} 637 getLineDelta()638 int64_t getLineDelta() const { return LineDelta; } 639 getAddrDelta()640 const MCExpr &getAddrDelta() const { return *AddrDelta; } 641 classof(const MCFragment * F)642 static bool classof(const MCFragment *F) { 643 return F->getKind() == MCFragment::FT_Dwarf; 644 } 645 }; 646 647 class MCDwarfCallFrameFragment : public MCEncodedFragment { 648 /// The expression for the difference of the two symbols that 649 /// make up the address delta between two .cfi_* dwarf directives. 650 const MCExpr *AddrDelta; 651 652 public: MCDwarfCallFrameFragment(const MCExpr & AddrDelta)653 MCDwarfCallFrameFragment(const MCExpr &AddrDelta) 654 : MCEncodedFragment(FT_DwarfFrame, false), AddrDelta(&AddrDelta) {} 655 getAddrDelta()656 const MCExpr &getAddrDelta() const { return *AddrDelta; } setAddrDelta(const MCExpr * E)657 void setAddrDelta(const MCExpr *E) { AddrDelta = E; } 658 classof(const MCFragment * F)659 static bool classof(const MCFragment *F) { 660 return F->getKind() == MCFragment::FT_DwarfFrame; 661 } 662 }; 663 664 /// Represents a symbol table index fragment. 665 class MCSymbolIdFragment : public MCFragment { 666 const MCSymbol *Sym; 667 668 public: MCSymbolIdFragment(const MCSymbol * Sym)669 MCSymbolIdFragment(const MCSymbol *Sym) 670 : MCFragment(FT_SymbolId, false), Sym(Sym) {} 671 getSymbol()672 const MCSymbol *getSymbol() { return Sym; } getSymbol()673 const MCSymbol *getSymbol() const { return Sym; } 674 classof(const MCFragment * F)675 static bool classof(const MCFragment *F) { 676 return F->getKind() == MCFragment::FT_SymbolId; 677 } 678 }; 679 680 /// Fragment representing the binary annotations produced by the 681 /// .cv_inline_linetable directive. 682 class MCCVInlineLineTableFragment : public MCEncodedFragment { 683 unsigned SiteFuncId; 684 unsigned StartFileId; 685 unsigned StartLineNum; 686 const MCSymbol *FnStartSym; 687 const MCSymbol *FnEndSym; 688 689 /// CodeViewContext has the real knowledge about this format, so let it access 690 /// our members. 691 friend class CodeViewContext; 692 693 public: MCCVInlineLineTableFragment(unsigned SiteFuncId,unsigned StartFileId,unsigned StartLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym)694 MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId, 695 unsigned StartLineNum, const MCSymbol *FnStartSym, 696 const MCSymbol *FnEndSym) 697 : MCEncodedFragment(FT_CVInlineLines, false), SiteFuncId(SiteFuncId), 698 StartFileId(StartFileId), StartLineNum(StartLineNum), 699 FnStartSym(FnStartSym), FnEndSym(FnEndSym) {} 700 getFnStartSym()701 const MCSymbol *getFnStartSym() const { return FnStartSym; } getFnEndSym()702 const MCSymbol *getFnEndSym() const { return FnEndSym; } 703 classof(const MCFragment * F)704 static bool classof(const MCFragment *F) { 705 return F->getKind() == MCFragment::FT_CVInlineLines; 706 } 707 }; 708 709 /// Fragment representing the .cv_def_range directive. 710 class MCCVDefRangeFragment : public MCEncodedFragment { 711 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges; 712 StringRef FixedSizePortion; 713 714 /// CodeViewContext has the real knowledge about this format, so let it access 715 /// our members. 716 friend class CodeViewContext; 717 718 public: MCCVDefRangeFragment(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)719 MCCVDefRangeFragment( 720 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, 721 StringRef FixedSizePortion) 722 : MCEncodedFragment(FT_CVDefRange, false), 723 Ranges(Ranges.begin(), Ranges.end()), 724 FixedSizePortion(FixedSizePortion) {} 725 getRanges()726 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const { 727 return Ranges; 728 } 729 getFixedSizePortion()730 StringRef getFixedSizePortion() const { return FixedSizePortion; } 731 classof(const MCFragment * F)732 static bool classof(const MCFragment *F) { 733 return F->getKind() == MCFragment::FT_CVDefRange; 734 } 735 }; 736 737 /// Represents required padding such that a particular other set of fragments 738 /// does not cross a particular power-of-two boundary. The other fragments must 739 /// follow this one within the same section. 740 class MCBoundaryAlignFragment : public MCFragment { 741 /// The alignment requirement of the branch to be aligned. 742 Align AlignBoundary; 743 /// The last fragment in the set of fragments to be aligned. 744 const MCFragment *LastFragment = nullptr; 745 /// The size of the fragment. The size is lazily set during relaxation, and 746 /// is not meaningful before that. 747 uint64_t Size = 0; 748 749 /// When emitting Nops some subtargets have specific nop encodings. 750 const MCSubtargetInfo &STI; 751 752 public: MCBoundaryAlignFragment(Align AlignBoundary,const MCSubtargetInfo & STI)753 MCBoundaryAlignFragment(Align AlignBoundary, const MCSubtargetInfo &STI) 754 : MCFragment(FT_BoundaryAlign, false), AlignBoundary(AlignBoundary), 755 STI(STI) {} 756 getSize()757 uint64_t getSize() const { return Size; } setSize(uint64_t Value)758 void setSize(uint64_t Value) { Size = Value; } 759 getAlignment()760 Align getAlignment() const { return AlignBoundary; } setAlignment(Align Value)761 void setAlignment(Align Value) { AlignBoundary = Value; } 762 getLastFragment()763 const MCFragment *getLastFragment() const { return LastFragment; } setLastFragment(const MCFragment * F)764 void setLastFragment(const MCFragment *F) { 765 assert(!F || getParent() == F->getParent()); 766 LastFragment = F; 767 } 768 getSubtargetInfo()769 const MCSubtargetInfo *getSubtargetInfo() const { return &STI; } 770 classof(const MCFragment * F)771 static bool classof(const MCFragment *F) { 772 return F->getKind() == MCFragment::FT_BoundaryAlign; 773 } 774 }; 775 776 class MCPseudoProbeAddrFragment : public MCEncodedFragment { 777 /// The expression for the difference of the two symbols that 778 /// make up the address delta between two .pseudoprobe directives. 779 const MCExpr *AddrDelta; 780 781 public: MCPseudoProbeAddrFragment(const MCExpr * AddrDelta)782 MCPseudoProbeAddrFragment(const MCExpr *AddrDelta) 783 : MCEncodedFragment(FT_PseudoProbe, false), AddrDelta(AddrDelta) {} 784 getAddrDelta()785 const MCExpr &getAddrDelta() const { return *AddrDelta; } 786 classof(const MCFragment * F)787 static bool classof(const MCFragment *F) { 788 return F->getKind() == MCFragment::FT_PseudoProbe; 789 } 790 }; 791 792 inline MCSection::iterator &MCSection::iterator::operator++() { 793 F = F->Next; 794 return *this; 795 } 796 797 } // end namespace llvm 798 799 #endif // LLVM_MC_MCSECTION_H 800