1195098Sed//===- MCSection.h - Machine Code Sections ----------------------*- C++ -*-===// 2195098Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6195098Sed// 7195098Sed//===----------------------------------------------------------------------===// 8195340Sed// 9195340Sed// This file declares the MCSection class. 10195340Sed// 11195340Sed//===----------------------------------------------------------------------===// 12195098Sed 13195098Sed#ifndef LLVM_MC_MCSECTION_H 14195098Sed#define LLVM_MC_MCSECTION_H 15195098Sed 16288943Sdim#include "llvm/ADT/SmallVector.h" 17288943Sdim#include "llvm/ADT/ilist.h" 18296417Sdim#include "llvm/MC/MCFragment.h" 19198090Srdivacky#include "llvm/MC/SectionKind.h" 20360784Sdim#include "llvm/Support/Alignment.h" 21321369Sdim#include <cassert> 22321369Sdim#include <utility> 23195098Sed 24195098Sednamespace llvm { 25321369Sdim 26296417Sdimclass MCAsmInfo; 27288943Sdimclass MCContext; 28288943Sdimclass MCExpr; 29288943Sdimclass MCSymbol; 30288943Sdimclass raw_ostream; 31321369Sdimclass Triple; 32210299Sed 33314564Sdimtemplate <> struct ilist_alloc_traits<MCFragment> { 34288943Sdim static void deleteNode(MCFragment *V); 35288943Sdim}; 36195098Sed 37288943Sdim/// Instances of this class represent a uniqued identifier for a section in the 38288943Sdim/// current translation unit. The MCContext class uniques and creates these. 39288943Sdimclass MCSection { 40288943Sdimpublic: 41353358Sdim enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm, SV_XCOFF }; 42208599Srdivacky 43341825Sdim /// Express the state of bundle locked groups while emitting code. 44288943Sdim enum BundleLockStateType { 45288943Sdim NotBundleLocked, 46288943Sdim BundleLocked, 47288943Sdim BundleLockedAlignToEnd 48288943Sdim }; 49210299Sed 50321369Sdim using FragmentListType = iplist<MCFragment>; 51206274Srdivacky 52321369Sdim using const_iterator = FragmentListType::const_iterator; 53321369Sdim using iterator = FragmentListType::iterator; 54249423Sdim 55321369Sdim using const_reverse_iterator = FragmentListType::const_reverse_iterator; 56321369Sdim using reverse_iterator = FragmentListType::reverse_iterator; 57198090Srdivacky 58288943Sdimprivate: 59288943Sdim MCSymbol *Begin; 60288943Sdim MCSymbol *End = nullptr; 61288943Sdim /// The alignment requirement of this section. 62360784Sdim Align Alignment; 63288943Sdim /// The section index in the assemblers section list. 64288943Sdim unsigned Ordinal = 0; 65288943Sdim /// The index of this section in the layout order. 66288943Sdim unsigned LayoutOrder; 67210299Sed 68341825Sdim /// Keeping track of bundle-locked state. 69288943Sdim BundleLockStateType BundleLockState = NotBundleLocked; 70288943Sdim 71341825Sdim /// Current nesting depth of bundle_lock directives. 72288943Sdim unsigned BundleLockNestingDepth = 0; 73288943Sdim 74341825Sdim /// We've seen a bundle_lock directive but not its first instruction 75288943Sdim /// yet. 76321369Sdim bool BundleGroupBeforeFirstInst : 1; 77288943Sdim 78288943Sdim /// Whether this section has had instructions emitted into it. 79321369Sdim bool HasInstructions : 1; 80288943Sdim 81321369Sdim bool IsRegistered : 1; 82288943Sdim 83296417Sdim MCDummyFragment DummyFragment; 84296417Sdim 85288943Sdim FragmentListType Fragments; 86288943Sdim 87288943Sdim /// Mapping from subsection number to insertion point for subsection numbers 88288943Sdim /// below that number. 89288943Sdim SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap; 90288943Sdim 91360784Sdim /// State for tracking labels that don't yet have Fragments 92360784Sdim struct PendingLabel { 93360784Sdim MCSymbol* Sym; 94360784Sdim unsigned Subsection; 95360784Sdim PendingLabel(MCSymbol* Sym, unsigned Subsection = 0) 96360784Sdim : Sym(Sym), Subsection(Subsection) {} 97360784Sdim }; 98360784Sdim SmallVector<PendingLabel, 2> PendingLabels; 99360784Sdim 100288943Sdimprotected: 101288943Sdim SectionVariant Variant; 102288943Sdim SectionKind Kind; 103321369Sdim 104321369Sdim MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin); 105296417Sdim ~MCSection(); 106288943Sdim 107288943Sdimpublic: 108321369Sdim MCSection(const MCSection &) = delete; 109321369Sdim MCSection &operator=(const MCSection &) = delete; 110321369Sdim 111288943Sdim SectionKind getKind() const { return Kind; } 112288943Sdim 113288943Sdim SectionVariant getVariant() const { return Variant; } 114288943Sdim 115288943Sdim MCSymbol *getBeginSymbol() { return Begin; } 116288943Sdim const MCSymbol *getBeginSymbol() const { 117288943Sdim return const_cast<MCSection *>(this)->getBeginSymbol(); 118288943Sdim } 119288943Sdim void setBeginSymbol(MCSymbol *Sym) { 120288943Sdim assert(!Begin); 121288943Sdim Begin = Sym; 122288943Sdim } 123288943Sdim MCSymbol *getEndSymbol(MCContext &Ctx); 124288943Sdim bool hasEnded() const; 125288943Sdim 126360784Sdim unsigned getAlignment() const { return Alignment.value(); } 127360784Sdim void setAlignment(Align Value) { Alignment = Value; } 128288943Sdim 129288943Sdim unsigned getOrdinal() const { return Ordinal; } 130288943Sdim void setOrdinal(unsigned Value) { Ordinal = Value; } 131288943Sdim 132288943Sdim unsigned getLayoutOrder() const { return LayoutOrder; } 133288943Sdim void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 134288943Sdim 135288943Sdim BundleLockStateType getBundleLockState() const { return BundleLockState; } 136288943Sdim void setBundleLockState(BundleLockStateType NewState); 137288943Sdim bool isBundleLocked() const { return BundleLockState != NotBundleLocked; } 138288943Sdim 139288943Sdim bool isBundleGroupBeforeFirstInst() const { 140288943Sdim return BundleGroupBeforeFirstInst; 141288943Sdim } 142288943Sdim void setBundleGroupBeforeFirstInst(bool IsFirst) { 143288943Sdim BundleGroupBeforeFirstInst = IsFirst; 144288943Sdim } 145288943Sdim 146288943Sdim bool hasInstructions() const { return HasInstructions; } 147288943Sdim void setHasInstructions(bool Value) { HasInstructions = Value; } 148288943Sdim 149288943Sdim bool isRegistered() const { return IsRegistered; } 150288943Sdim void setIsRegistered(bool Value) { IsRegistered = Value; } 151288943Sdim 152288943Sdim MCSection::FragmentListType &getFragmentList() { return Fragments; } 153288943Sdim const MCSection::FragmentListType &getFragmentList() const { 154288943Sdim return const_cast<MCSection *>(this)->getFragmentList(); 155288943Sdim } 156288943Sdim 157296417Sdim /// Support for MCFragment::getNextNode(). 158296417Sdim static FragmentListType MCSection::*getSublistAccess(MCFragment *) { 159296417Sdim return &MCSection::Fragments; 160296417Sdim } 161296417Sdim 162296417Sdim const MCDummyFragment &getDummyFragment() const { return DummyFragment; } 163296417Sdim MCDummyFragment &getDummyFragment() { return DummyFragment; } 164296417Sdim 165314564Sdim iterator begin() { return Fragments.begin(); } 166314564Sdim const_iterator begin() const { return Fragments.begin(); } 167288943Sdim 168314564Sdim iterator end() { return Fragments.end(); } 169314564Sdim const_iterator end() const { return Fragments.end(); } 170288943Sdim 171288943Sdim MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection); 172288943Sdim 173321369Sdim void dump() const; 174288943Sdim 175321369Sdim virtual void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 176321369Sdim raw_ostream &OS, 177288943Sdim const MCExpr *Subsection) const = 0; 178288943Sdim 179288943Sdim /// Return true if a .align directive should use "optimized nops" to fill 180288943Sdim /// instead of 0s. 181288943Sdim virtual bool UseCodeAlign() const = 0; 182288943Sdim 183288943Sdim /// Check whether this section is "virtual", that is has no actual object 184288943Sdim /// file contents. 185288943Sdim virtual bool isVirtualSection() const = 0; 186360784Sdim 187360784Sdim /// Add a pending label for the requested subsection. This label will be 188360784Sdim /// associated with a fragment in flushPendingLabels() 189360784Sdim void addPendingLabel(MCSymbol* label, unsigned Subsection = 0); 190360784Sdim 191360784Sdim /// Associate all pending labels in a subsection with a fragment. 192360784Sdim void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0, 193360784Sdim unsigned Subsection = 0); 194360784Sdim 195360784Sdim /// Associate all pending labels with empty data fragments. One fragment 196360784Sdim /// will be created for each subsection as necessary. 197360784Sdim void flushPendingLabels(); 198288943Sdim}; 199288943Sdim 200195098Sed} // end namespace llvm 201195098Sed 202321369Sdim#endif // LLVM_MC_MCSECTION_H 203