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