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