Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:14

0001 //===- MCSection.h - Machine Code Sections ----------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file declares the MCSection class.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_MC_MCSECTION_H
0014 #define LLVM_MC_MCSECTION_H
0015 
0016 #include "llvm/ADT/SmallVector.h"
0017 #include "llvm/MC/MCFragment.h"
0018 #include "llvm/MC/SectionKind.h"
0019 #include "llvm/Support/Alignment.h"
0020 #include <cassert>
0021 #include <utility>
0022 
0023 namespace llvm {
0024 
0025 class MCAsmInfo;
0026 class MCAssembler;
0027 class MCContext;
0028 class MCExpr;
0029 class MCObjectStreamer;
0030 class MCSymbol;
0031 class raw_ostream;
0032 class Triple;
0033 
0034 /// Instances of this class represent a uniqued identifier for a section in the
0035 /// current translation unit.  The MCContext class uniques and creates these.
0036 class MCSection {
0037 public:
0038   friend MCAssembler;
0039   friend MCObjectStreamer;
0040   static constexpr unsigned NonUniqueID = ~0U;
0041 
0042   enum SectionVariant {
0043     SV_COFF = 0,
0044     SV_ELF,
0045     SV_GOFF,
0046     SV_MachO,
0047     SV_Wasm,
0048     SV_XCOFF,
0049     SV_SPIRV,
0050     SV_DXContainer,
0051   };
0052 
0053   /// Express the state of bundle locked groups while emitting code.
0054   enum BundleLockStateType {
0055     NotBundleLocked,
0056     BundleLocked,
0057     BundleLockedAlignToEnd
0058   };
0059 
0060   struct iterator {
0061     MCFragment *F = nullptr;
0062     iterator() = default;
0063     explicit iterator(MCFragment *F) : F(F) {}
0064     MCFragment &operator*() const { return *F; }
0065     bool operator==(const iterator &O) const { return F == O.F; }
0066     bool operator!=(const iterator &O) const { return F != O.F; }
0067     iterator &operator++() {
0068       F = F->Next;
0069       return *this;
0070     }
0071   };
0072 
0073   struct FragList {
0074     MCFragment *Head = nullptr;
0075     MCFragment *Tail = nullptr;
0076   };
0077 
0078 private:
0079   // At parse time, this holds the fragment list of the current subsection. At
0080   // layout time, this holds the concatenated fragment lists of all subsections.
0081   FragList *CurFragList;
0082   MCSymbol *Begin;
0083   MCSymbol *End = nullptr;
0084   /// The alignment requirement of this section.
0085   Align Alignment;
0086   /// The section index in the assemblers section list.
0087   unsigned Ordinal = 0;
0088 
0089   /// Keeping track of bundle-locked state.
0090   BundleLockStateType BundleLockState = NotBundleLocked;
0091 
0092   /// Current nesting depth of bundle_lock directives.
0093   unsigned BundleLockNestingDepth = 0;
0094 
0095   /// We've seen a bundle_lock directive but not its first instruction
0096   /// yet.
0097   bool BundleGroupBeforeFirstInst : 1;
0098 
0099   /// Whether this section has had instructions emitted into it.
0100   bool HasInstructions : 1;
0101 
0102   bool HasLayout : 1;
0103 
0104   bool IsRegistered : 1;
0105 
0106   bool IsText : 1;
0107 
0108   bool IsVirtual : 1;
0109 
0110   MCDummyFragment DummyFragment;
0111 
0112   // Mapping from subsection number to fragment list. At layout time, the
0113   // subsection 0 list is replaced with concatenated fragments from all
0114   // subsections.
0115   SmallVector<std::pair<unsigned, FragList>, 1> Subsections;
0116 
0117 protected:
0118   // TODO Make Name private when possible.
0119   StringRef Name;
0120   SectionVariant Variant;
0121 
0122   MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsVirtual,
0123             MCSymbol *Begin);
0124   ~MCSection();
0125 
0126 public:
0127   MCSection(const MCSection &) = delete;
0128   MCSection &operator=(const MCSection &) = delete;
0129 
0130   StringRef getName() const { return Name; }
0131   bool isText() const { return IsText; }
0132 
0133   SectionVariant getVariant() const { return Variant; }
0134 
0135   MCSymbol *getBeginSymbol() { return Begin; }
0136   const MCSymbol *getBeginSymbol() const {
0137     return const_cast<MCSection *>(this)->getBeginSymbol();
0138   }
0139   void setBeginSymbol(MCSymbol *Sym) {
0140     assert(!Begin);
0141     Begin = Sym;
0142   }
0143   MCSymbol *getEndSymbol(MCContext &Ctx);
0144   bool hasEnded() const;
0145 
0146   Align getAlign() const { return Alignment; }
0147   void setAlignment(Align Value) { Alignment = Value; }
0148 
0149   /// Makes sure that Alignment is at least MinAlignment.
0150   void ensureMinAlignment(Align MinAlignment) {
0151     if (Alignment < MinAlignment)
0152       Alignment = MinAlignment;
0153   }
0154 
0155   unsigned getOrdinal() const { return Ordinal; }
0156   void setOrdinal(unsigned Value) { Ordinal = Value; }
0157 
0158   BundleLockStateType getBundleLockState() const { return BundleLockState; }
0159   void setBundleLockState(BundleLockStateType NewState);
0160   bool isBundleLocked() const { return BundleLockState != NotBundleLocked; }
0161 
0162   bool isBundleGroupBeforeFirstInst() const {
0163     return BundleGroupBeforeFirstInst;
0164   }
0165   void setBundleGroupBeforeFirstInst(bool IsFirst) {
0166     BundleGroupBeforeFirstInst = IsFirst;
0167   }
0168 
0169   bool hasInstructions() const { return HasInstructions; }
0170   void setHasInstructions(bool Value) { HasInstructions = Value; }
0171 
0172   bool hasLayout() const { return HasLayout; }
0173   void setHasLayout(bool Value) { HasLayout = Value; }
0174 
0175   bool isRegistered() const { return IsRegistered; }
0176   void setIsRegistered(bool Value) { IsRegistered = Value; }
0177 
0178   const MCDummyFragment &getDummyFragment() const { return DummyFragment; }
0179   MCDummyFragment &getDummyFragment() { return DummyFragment; }
0180 
0181   FragList *curFragList() const { return CurFragList; }
0182   iterator begin() const { return iterator(CurFragList->Head); }
0183   iterator end() const { return {}; }
0184 
0185   void dump() const;
0186 
0187   virtual void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
0188                                     raw_ostream &OS,
0189                                     uint32_t Subsection) const = 0;
0190 
0191   /// Return true if a .align directive should use "optimized nops" to fill
0192   /// instead of 0s.
0193   virtual bool useCodeAlign() const = 0;
0194 
0195   /// Check whether this section is "virtual", that is has no actual object
0196   /// file contents.
0197   bool isVirtualSection() const { return IsVirtual; }
0198 
0199   virtual StringRef getVirtualSectionKind() const;
0200 };
0201 
0202 } // end namespace llvm
0203 
0204 #endif // LLVM_MC_MCSECTION_H