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 "llvm/Support/Alignment.h"
21#include <cassert>
22#include <utility>
23
24namespace llvm {
25
26class MCAsmInfo;
27class MCContext;
28class MCExpr;
29class MCSymbol;
30class raw_ostream;
31class Triple;
32
33template <> struct ilist_alloc_traits<MCFragment> {
34 static void deleteNode(MCFragment *V);
35};
36
37/// Instances of this class represent a uniqued identifier for a section in the
38/// current translation unit. The MCContext class uniques and creates these.
39class MCSection {
40public:
41 static constexpr unsigned NonUniqueID = ~0U;
42
43 enum SectionVariant {
44 SV_COFF = 0,
45 SV_ELF,
46 SV_GOFF,
47 SV_MachO,
48 SV_Wasm,
49 SV_XCOFF,
50 SV_SPIRV,
51 SV_DXContainer,
52 };
53
54 /// Express the state of bundle locked groups while emitting code.
55 enum BundleLockStateType {
56 NotBundleLocked,
57 BundleLocked,
58 BundleLockedAlignToEnd
59 };
60
61 using FragmentListType = iplist<MCFragment>;
62
63 using const_iterator = FragmentListType::const_iterator;
64 using iterator = FragmentListType::iterator;
65
66 using const_reverse_iterator = FragmentListType::const_reverse_iterator;
67 using reverse_iterator = FragmentListType::reverse_iterator;
68
69private:
70 MCSymbol *Begin;
71 MCSymbol *End = nullptr;
72 /// The alignment requirement of this section.
73 Align Alignment;
74 /// The section index in the assemblers section list.
75 unsigned Ordinal = 0;
76 /// The index of this section in the layout order.
77 unsigned LayoutOrder = 0;
78
79 /// Keeping track of bundle-locked state.
80 BundleLockStateType BundleLockState = NotBundleLocked;
81
82 /// Current nesting depth of bundle_lock directives.
83 unsigned BundleLockNestingDepth = 0;
84
85 /// We've seen a bundle_lock directive but not its first instruction
86 /// yet.
87 bool BundleGroupBeforeFirstInst : 1;
88
89 /// Whether this section has had instructions emitted into it.
90 bool HasInstructions : 1;
91
92 bool IsRegistered : 1;
93
94 MCDummyFragment DummyFragment;
95
96 FragmentListType Fragments;
97
98 /// Mapping from subsection number to insertion point for subsection numbers
99 /// below that number.
100 SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
101
102 /// State for tracking labels that don't yet have Fragments
103 struct PendingLabel {
104 MCSymbol* Sym;
105 unsigned Subsection;
106 PendingLabel(MCSymbol* Sym, unsigned Subsection = 0)
107 : Sym(Sym), Subsection(Subsection) {}
108 };
109 SmallVector<PendingLabel, 2> PendingLabels;
110
111protected:
112 // TODO Make Name private when possible.
113 StringRef Name;
114 SectionVariant Variant;
115 SectionKind Kind;
116
117 MCSection(SectionVariant V, StringRef Name, SectionKind K, MCSymbol *Begin);
118 ~MCSection();
119
120public:
121 MCSection(const MCSection &) = delete;
122 MCSection &operator=(const MCSection &) = delete;
123
124 StringRef getName() const { return Name; }
125 SectionKind getKind() const { return Kind; }
126
127 SectionVariant getVariant() const { return Variant; }
128
129 MCSymbol *getBeginSymbol() { return Begin; }
130 const MCSymbol *getBeginSymbol() const {
131 return const_cast<MCSection *>(this)->getBeginSymbol();
132 }
133 void setBeginSymbol(MCSymbol *Sym) {
134 assert(!Begin);
135 Begin = Sym;
136 }
137 MCSymbol *getEndSymbol(MCContext &Ctx);
138 bool hasEnded() const;
139
140 Align getAlign() const { return Alignment; }
141 void setAlignment(Align Value) { Alignment = Value; }
142
143 /// Makes sure that Alignment is at least MinAlignment.
144 void ensureMinAlignment(Align MinAlignment) {
145 if (Alignment < MinAlignment)
146 Alignment = MinAlignment;
147 }
148
149 unsigned getOrdinal() const { return Ordinal; }
150 void setOrdinal(unsigned Value) { Ordinal = Value; }
151
152 unsigned getLayoutOrder() const { return LayoutOrder; }
153 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
154
155 BundleLockStateType getBundleLockState() const { return BundleLockState; }
156 void setBundleLockState(BundleLockStateType NewState);
157 bool isBundleLocked() const { return BundleLockState != NotBundleLocked; }
158
159 bool isBundleGroupBeforeFirstInst() const {
160 return BundleGroupBeforeFirstInst;
161 }
162 void setBundleGroupBeforeFirstInst(bool IsFirst) {
163 BundleGroupBeforeFirstInst = IsFirst;
164 }
165
166 bool hasInstructions() const { return HasInstructions; }
167 void setHasInstructions(bool Value) { HasInstructions = Value; }
168
169 bool isRegistered() const { return IsRegistered; }
170 void setIsRegistered(bool Value) { IsRegistered = Value; }
171
172 MCSection::FragmentListType &getFragmentList() { return Fragments; }
173 const MCSection::FragmentListType &getFragmentList() const {
174 return const_cast<MCSection *>(this)->getFragmentList();
175 }
176
177 /// Support for MCFragment::getNextNode().
178 static FragmentListType MCSection::*getSublistAccess(MCFragment *) {
179 return &MCSection::Fragments;
180 }
181
182 const MCDummyFragment &getDummyFragment() const { return DummyFragment; }
183 MCDummyFragment &getDummyFragment() { return DummyFragment; }
184
185 iterator begin() { return Fragments.begin(); }
186 const_iterator begin() const { return Fragments.begin(); }
187
188 iterator end() { return Fragments.end(); }
189 const_iterator end() const { return Fragments.end(); }
190
191 MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection);
192
193 void dump() const;
194
195 virtual void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
196 raw_ostream &OS,
197 const MCExpr *Subsection) const = 0;
198
199 /// Return true if a .align directive should use "optimized nops" to fill
200 /// instead of 0s.
201 virtual bool useCodeAlign() const = 0;
202
203 /// Check whether this section is "virtual", that is has no actual object
204 /// file contents.
205 virtual bool isVirtualSection() const = 0;
206
207 virtual StringRef getVirtualSectionKind() const;
208
209 /// Add a pending label for the requested subsection. This label will be
210 /// associated with a fragment in flushPendingLabels()
211 void addPendingLabel(MCSymbol* label, unsigned Subsection = 0);
212
213 /// Associate all pending labels in a subsection with a fragment.
214 void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0,
215 unsigned Subsection = 0);
216
217 /// Associate all pending labels with empty data fragments. One fragment
218 /// will be created for each subsection as necessary.
219 void flushPendingLabels();
220};
221
222} // end namespace llvm
223
224#endif // LLVM_MC_MCSECTION_H
225

source code of llvm/include/llvm/MC/MCSection.h