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/ADT/ilist.h" 18 #include "llvm/MC/MCFragment.h" 19 #include "llvm/MC/SectionKind.h" 20 #include <cassert> 21 #include <utility> 22 23 namespace llvm { 24 25 class MCAsmInfo; 26 class MCContext; 27 class MCExpr; 28 class MCSymbol; 29 class raw_ostream; 30 class Triple; 31 32 template <> struct ilist_alloc_traits<MCFragment> { 33 static void deleteNode(MCFragment *V); 34 }; 35 36 /// Instances of this class represent a uniqued identifier for a section in the 37 /// current translation unit. The MCContext class uniques and creates these. 38 class MCSection { 39 public: 40 enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm, SV_XCOFF }; 41 42 /// Express the state of bundle locked groups while emitting code. 43 enum BundleLockStateType { 44 NotBundleLocked, 45 BundleLocked, 46 BundleLockedAlignToEnd 47 }; 48 49 using FragmentListType = iplist<MCFragment>; 50 51 using const_iterator = FragmentListType::const_iterator; 52 using iterator = FragmentListType::iterator; 53 54 using const_reverse_iterator = FragmentListType::const_reverse_iterator; 55 using reverse_iterator = FragmentListType::reverse_iterator; 56 57 private: 58 MCSymbol *Begin; 59 MCSymbol *End = nullptr; 60 /// The alignment requirement of this section. 61 unsigned Alignment = 1; 62 /// The section index in the assemblers section list. 63 unsigned Ordinal = 0; 64 /// The index of this section in the layout order. 65 unsigned LayoutOrder; 66 67 /// Keeping track of bundle-locked state. 68 BundleLockStateType BundleLockState = NotBundleLocked; 69 70 /// Current nesting depth of bundle_lock directives. 71 unsigned BundleLockNestingDepth = 0; 72 73 /// We've seen a bundle_lock directive but not its first instruction 74 /// yet. 75 bool BundleGroupBeforeFirstInst : 1; 76 77 /// Whether this section has had instructions emitted into it. 78 bool HasInstructions : 1; 79 80 /// Whether this section has had data emitted into it. 81 /// Right now this is only used by the ARM backend. 82 bool HasData : 1; 83 84 bool IsRegistered : 1; 85 86 MCDummyFragment DummyFragment; 87 88 FragmentListType Fragments; 89 90 /// Mapping from subsection number to insertion point for subsection numbers 91 /// below that number. 92 SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap; 93 94 protected: 95 SectionVariant Variant; 96 SectionKind Kind; 97 98 MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin); 99 ~MCSection(); 100 101 public: 102 MCSection(const MCSection &) = delete; 103 MCSection &operator=(const MCSection &) = delete; 104 105 SectionKind getKind() const { return Kind; } 106 107 SectionVariant getVariant() const { return Variant; } 108 109 MCSymbol *getBeginSymbol() { return Begin; } 110 const MCSymbol *getBeginSymbol() const { 111 return const_cast<MCSection *>(this)->getBeginSymbol(); 112 } 113 void setBeginSymbol(MCSymbol *Sym) { 114 assert(!Begin); 115 Begin = Sym; 116 } 117 MCSymbol *getEndSymbol(MCContext &Ctx); 118 bool hasEnded() const; 119 120 unsigned getAlignment() const { return Alignment; } 121 void setAlignment(unsigned Value) { Alignment = Value; } 122 123 unsigned getOrdinal() const { return Ordinal; } 124 void setOrdinal(unsigned Value) { Ordinal = Value; } 125 126 unsigned getLayoutOrder() const { return LayoutOrder; } 127 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 128 129 BundleLockStateType getBundleLockState() const { return BundleLockState; } 130 void setBundleLockState(BundleLockStateType NewState); 131 bool isBundleLocked() const { return BundleLockState != NotBundleLocked; } 132 133 bool isBundleGroupBeforeFirstInst() const { 134 return BundleGroupBeforeFirstInst; 135 } 136 void setBundleGroupBeforeFirstInst(bool IsFirst) { 137 BundleGroupBeforeFirstInst = IsFirst; 138 } 139 140 bool hasInstructions() const { return HasInstructions; } 141 void setHasInstructions(bool Value) { HasInstructions = Value; } 142 143 bool hasData() const { return HasData; } 144 void setHasData(bool Value) { HasData = Value; } 145 146 bool isRegistered() const { return IsRegistered; } 147 void setIsRegistered(bool Value) { IsRegistered = Value; } 148 149 MCSection::FragmentListType &getFragmentList() { return Fragments; } 150 const MCSection::FragmentListType &getFragmentList() const { 151 return const_cast<MCSection *>(this)->getFragmentList(); 152 } 153 154 /// Support for MCFragment::getNextNode(). 155 static FragmentListType MCSection::*getSublistAccess(MCFragment *) { 156 return &MCSection::Fragments; 157 } 158 159 const MCDummyFragment &getDummyFragment() const { return DummyFragment; } 160 MCDummyFragment &getDummyFragment() { return DummyFragment; } 161 162 iterator begin() { return Fragments.begin(); } 163 const_iterator begin() const { return Fragments.begin(); } 164 165 iterator end() { return Fragments.end(); } 166 const_iterator end() const { return Fragments.end(); } 167 168 reverse_iterator rbegin() { return Fragments.rbegin(); } 169 const_reverse_iterator rbegin() const { return Fragments.rbegin(); } 170 171 reverse_iterator rend() { return Fragments.rend(); } 172 const_reverse_iterator rend() const { return Fragments.rend(); } 173 174 MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection); 175 176 void dump() const; 177 178 virtual void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 179 raw_ostream &OS, 180 const MCExpr *Subsection) const = 0; 181 182 /// Return true if a .align directive should use "optimized nops" to fill 183 /// instead of 0s. 184 virtual bool UseCodeAlign() const = 0; 185 186 /// Check whether this section is "virtual", that is has no actual object 187 /// file contents. 188 virtual bool isVirtualSection() const = 0; 189 }; 190 191 } // end namespace llvm 192 193 #endif // LLVM_MC_MCSECTION_H 194