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/SmallVector.h" 17 #include "llvm/MC/MCFragment.h" 18 #include "llvm/MC/SectionKind.h" 19 #include "llvm/Support/Alignment.h" 20 #include <cassert> 21 #include <utility> 22 23 namespace llvm { 24 25 class MCAsmInfo; 26 class MCAssembler; 27 class MCContext; 28 class MCExpr; 29 class MCObjectStreamer; 30 class MCSymbol; 31 class raw_ostream; 32 class Triple; 33 34 /// Instances of this class represent a uniqued identifier for a section in the 35 /// current translation unit. The MCContext class uniques and creates these. 36 class MCSection { 37 public: 38 friend MCAssembler; 39 friend MCObjectStreamer; 40 static constexpr unsigned NonUniqueID = ~0U; 41 42 enum SectionVariant { 43 SV_COFF = 0, 44 SV_ELF, 45 SV_GOFF, 46 SV_MachO, 47 SV_Wasm, 48 SV_XCOFF, 49 SV_SPIRV, 50 SV_DXContainer, 51 }; 52 53 /// Express the state of bundle locked groups while emitting code. 54 enum BundleLockStateType { 55 NotBundleLocked, 56 BundleLocked, 57 BundleLockedAlignToEnd 58 }; 59 60 struct iterator { 61 MCFragment *F = nullptr; 62 iterator() = default; iteratoriterator63 explicit iterator(MCFragment *F) : F(F) {} 64 MCFragment &operator*() const { return *F; } 65 bool operator==(const iterator &O) const { return F == O.F; } 66 bool operator!=(const iterator &O) const { return F != O.F; } 67 iterator &operator++() { 68 F = F->Next; 69 return *this; 70 } 71 }; 72 73 struct FragList { 74 MCFragment *Head = nullptr; 75 MCFragment *Tail = nullptr; 76 }; 77 78 private: 79 // At parse time, this holds the fragment list of the current subsection. At 80 // layout time, this holds the concatenated fragment lists of all subsections. 81 FragList *CurFragList; 82 MCSymbol *Begin; 83 MCSymbol *End = nullptr; 84 /// The alignment requirement of this section. 85 Align Alignment; 86 /// The section index in the assemblers section list. 87 unsigned Ordinal = 0; 88 89 /// Keeping track of bundle-locked state. 90 BundleLockStateType BundleLockState = NotBundleLocked; 91 92 /// Current nesting depth of bundle_lock directives. 93 unsigned BundleLockNestingDepth = 0; 94 95 /// We've seen a bundle_lock directive but not its first instruction 96 /// yet. 97 bool BundleGroupBeforeFirstInst : 1; 98 99 /// Whether this section has had instructions emitted into it. 100 bool HasInstructions : 1; 101 102 bool HasLayout : 1; 103 104 bool IsRegistered : 1; 105 106 bool IsText : 1; 107 108 bool IsVirtual : 1; 109 110 MCDummyFragment DummyFragment; 111 112 // Mapping from subsection number to fragment list. At layout time, the 113 // subsection 0 list is replaced with concatenated fragments from all 114 // subsections. 115 SmallVector<std::pair<unsigned, FragList>, 1> Subsections; 116 117 protected: 118 // TODO Make Name private when possible. 119 StringRef Name; 120 SectionVariant Variant; 121 122 MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsVirtual, 123 MCSymbol *Begin); 124 ~MCSection(); 125 126 public: 127 MCSection(const MCSection &) = delete; 128 MCSection &operator=(const MCSection &) = delete; 129 getName()130 StringRef getName() const { return Name; } isText()131 bool isText() const { return IsText; } 132 getVariant()133 SectionVariant getVariant() const { return Variant; } 134 getBeginSymbol()135 MCSymbol *getBeginSymbol() { return Begin; } getBeginSymbol()136 const MCSymbol *getBeginSymbol() const { 137 return const_cast<MCSection *>(this)->getBeginSymbol(); 138 } setBeginSymbol(MCSymbol * Sym)139 void setBeginSymbol(MCSymbol *Sym) { 140 assert(!Begin); 141 Begin = Sym; 142 } 143 MCSymbol *getEndSymbol(MCContext &Ctx); 144 bool hasEnded() const; 145 getAlign()146 Align getAlign() const { return Alignment; } setAlignment(Align Value)147 void setAlignment(Align Value) { Alignment = Value; } 148 149 /// Makes sure that Alignment is at least MinAlignment. ensureMinAlignment(Align MinAlignment)150 void ensureMinAlignment(Align MinAlignment) { 151 if (Alignment < MinAlignment) 152 Alignment = MinAlignment; 153 } 154 getOrdinal()155 unsigned getOrdinal() const { return Ordinal; } setOrdinal(unsigned Value)156 void setOrdinal(unsigned Value) { Ordinal = Value; } 157 getBundleLockState()158 BundleLockStateType getBundleLockState() const { return BundleLockState; } 159 void setBundleLockState(BundleLockStateType NewState); isBundleLocked()160 bool isBundleLocked() const { return BundleLockState != NotBundleLocked; } 161 isBundleGroupBeforeFirstInst()162 bool isBundleGroupBeforeFirstInst() const { 163 return BundleGroupBeforeFirstInst; 164 } setBundleGroupBeforeFirstInst(bool IsFirst)165 void setBundleGroupBeforeFirstInst(bool IsFirst) { 166 BundleGroupBeforeFirstInst = IsFirst; 167 } 168 hasInstructions()169 bool hasInstructions() const { return HasInstructions; } setHasInstructions(bool Value)170 void setHasInstructions(bool Value) { HasInstructions = Value; } 171 hasLayout()172 bool hasLayout() const { return HasLayout; } setHasLayout(bool Value)173 void setHasLayout(bool Value) { HasLayout = Value; } 174 isRegistered()175 bool isRegistered() const { return IsRegistered; } setIsRegistered(bool Value)176 void setIsRegistered(bool Value) { IsRegistered = Value; } 177 getDummyFragment()178 const MCDummyFragment &getDummyFragment() const { return DummyFragment; } getDummyFragment()179 MCDummyFragment &getDummyFragment() { return DummyFragment; } 180 curFragList()181 FragList *curFragList() const { return CurFragList; } begin()182 iterator begin() const { return iterator(CurFragList->Head); } end()183 iterator end() const { return {}; } empty()184 bool empty() const { return !CurFragList->Head; } 185 186 void dump() const; 187 188 virtual void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 189 raw_ostream &OS, 190 uint32_t Subsection) const = 0; 191 192 /// Return true if a .align directive should use "optimized nops" to fill 193 /// instead of 0s. 194 virtual bool useCodeAlign() const = 0; 195 196 /// Check whether this section is "virtual", that is has no actual object 197 /// file contents. isVirtualSection()198 bool isVirtualSection() const { return IsVirtual; } 199 200 virtual StringRef getVirtualSectionKind() const; 201 }; 202 203 } // end namespace llvm 204 205 #endif // LLVM_MC_MCSECTION_H 206