1205218Srdivacky//===- MCAsmLayout.h - Assembly Layout Object -------------------*- C++ -*-===// 2205218Srdivacky// 3205218Srdivacky// The LLVM Compiler Infrastructure 4205218Srdivacky// 5205218Srdivacky// This file is distributed under the University of Illinois Open Source 6205218Srdivacky// License. See LICENSE.TXT for details. 7205218Srdivacky// 8205218Srdivacky//===----------------------------------------------------------------------===// 9205218Srdivacky 10205218Srdivacky#ifndef LLVM_MC_MCASMLAYOUT_H 11205218Srdivacky#define LLVM_MC_MCASMLAYOUT_H 12205218Srdivacky 13235633Sdim#include "llvm/ADT/DenseMap.h" 14208599Srdivacky#include "llvm/ADT/SmallVector.h" 15208599Srdivacky 16205218Srdivackynamespace llvm { 17205218Srdivackyclass MCAssembler; 18206083Srdivackyclass MCFragment; 19206083Srdivackyclass MCSectionData; 20206083Srdivackyclass MCSymbolData; 21205218Srdivacky 22205218Srdivacky/// Encapsulates the layout of an assembly file at a particular point in time. 23205218Srdivacky/// 24252723Sdim/// Assembly may require computing multiple layouts for a particular assembly 25205218Srdivacky/// file as part of the relaxation process. This class encapsulates the layout 26205218Srdivacky/// at a single point in time in such a way that it is always possible to 27252723Sdim/// efficiently compute the exact address of any symbol in the assembly file, 28205218Srdivacky/// even during the relaxation process. 29205218Srdivackyclass MCAsmLayout { 30208599Srdivackypublic: 31208599Srdivacky typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator; 32208599Srdivacky typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator; 33208599Srdivacky 34205218Srdivackyprivate: 35205218Srdivacky MCAssembler &Assembler; 36205218Srdivacky 37208599Srdivacky /// List of sections in layout order. 38208599Srdivacky llvm::SmallVector<MCSectionData*, 16> SectionOrder; 39208599Srdivacky 40221345Sdim /// The last fragment which was laid out, or 0 if nothing has been laid 41221345Sdim /// out. Fragments are always laid out in order, so all fragments with a 42252723Sdim /// lower ordinal will be valid. 43252723Sdim mutable DenseMap<const MCSectionData*, MCFragment*> LastValidFragment; 44208599Srdivacky 45208599Srdivacky /// \brief Make sure that the layout for the given fragment is valid, lazily 46208599Srdivacky /// computing it if necessary. 47252723Sdim void ensureValid(const MCFragment *F) const; 48208599Srdivacky 49252723Sdim /// \brief Is the layout for this fragment valid? 50252723Sdim bool isFragmentValid(const MCFragment *F) const; 51208599Srdivacky 52252723Sdim /// \brief Compute the amount of padding required before this fragment to 53252723Sdim /// obey bundling restrictions. 54252723Sdim uint64_t computeBundlePadding(const MCFragment *F, 55252723Sdim uint64_t FOffset, uint64_t FSize); 56252723Sdim 57205218Srdivackypublic: 58208599Srdivacky MCAsmLayout(MCAssembler &_Assembler); 59205218Srdivacky 60205218Srdivacky /// Get the assembler object this is a layout for. 61205218Srdivacky MCAssembler &getAssembler() const { return Assembler; } 62206083Srdivacky 63252723Sdim /// \brief Invalidate the fragments starting with F because it has been 64252723Sdim /// resized. The fragment's size should have already been updated, but 65252723Sdim /// its bundle padding will be recomputed. 66252723Sdim void invalidateFragmentsFrom(MCFragment *F); 67206083Srdivacky 68208599Srdivacky /// \brief Perform layout for a single fragment, assuming that the previous 69221345Sdim /// fragment has already been laid out correctly, and the parent section has 70208599Srdivacky /// been initialized. 71252723Sdim void layoutFragment(MCFragment *Fragment); 72208599Srdivacky 73208599Srdivacky /// @name Section Access (in layout order) 74208599Srdivacky /// @{ 75208599Srdivacky 76208599Srdivacky llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() { 77208599Srdivacky return SectionOrder; 78208599Srdivacky } 79208599Srdivacky const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const { 80208599Srdivacky return SectionOrder; 81208599Srdivacky } 82208599Srdivacky 83208599Srdivacky /// @} 84206083Srdivacky /// @name Fragment Layout Data 85206083Srdivacky /// @{ 86206083Srdivacky 87206083Srdivacky /// \brief Get the offset of the given fragment inside its containing section. 88206083Srdivacky uint64_t getFragmentOffset(const MCFragment *F) const; 89206083Srdivacky 90206083Srdivacky /// @} 91206083Srdivacky /// @name Utility Functions 92206083Srdivacky /// @{ 93206083Srdivacky 94208599Srdivacky /// \brief Get the address space size of the given section, as it effects 95208599Srdivacky /// layout. This may differ from the size reported by \see getSectionSize() by 96208599Srdivacky /// not including section tail padding. 97208599Srdivacky uint64_t getSectionAddressSize(const MCSectionData *SD) const; 98208599Srdivacky 99208599Srdivacky /// \brief Get the data size of the given section, as emitted to the object 100208599Srdivacky /// file. This may include additional padding, or be 0 for virtual sections. 101208599Srdivacky uint64_t getSectionFileSize(const MCSectionData *SD) const; 102208599Srdivacky 103218893Sdim /// \brief Get the offset of the given symbol, as computed in the current 104206083Srdivacky /// layout. 105218893Sdim uint64_t getSymbolOffset(const MCSymbolData *SD) const; 106206083Srdivacky 107206083Srdivacky /// @} 108205218Srdivacky}; 109205218Srdivacky 110205218Srdivacky} // end namespace llvm 111205218Srdivacky 112205218Srdivacky#endif 113