xref: /freebsd/contrib/llvm-project/llvm/include/llvm/MC/MCSection.h (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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