1f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar//===- MCAsmLayout.h - Assembly Layout Object -------------------*- C++ -*-===//
2f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar//
3f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar//                     The LLVM Compiler Infrastructure
4f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar//
5f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar// This file is distributed under the University of Illinois Open Source
6f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar// License. See LICENSE.TXT for details.
7f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar//
8f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar//===----------------------------------------------------------------------===//
9f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar
10f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar#ifndef LLVM_MC_MCASMLAYOUT_H
11f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar#define LLVM_MC_MCASMLAYOUT_H
12f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar
13066b5d8403483bf3a8bb033b690da318fbc68e79Benjamin Kramer#include "llvm/ADT/DenseMap.h"
14bc1a0cf13950dcd64d6d0398df5419a0a2931721Daniel Dunbar#include "llvm/ADT/SmallVector.h"
15bc1a0cf13950dcd64d6d0398df5419a0a2931721Daniel Dunbar
16f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbarnamespace llvm {
17f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbarclass MCAssembler;
18207e06ea0446c51cb1d89f6400ec7becc46487f8Daniel Dunbarclass MCFragment;
196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarclass MCSection;
20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesclass MCSymbol;
21f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar
22f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar/// Encapsulates the layout of an assembly file at a particular point in time.
23f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar///
24f43e3fdb4ffddff6f71b5597c813c43e1e206564Eli Bendersky/// Assembly may require computing multiple layouts for a particular assembly
25f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar/// file as part of the relaxation process. This class encapsulates the layout
26f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar/// at a single point in time in such a way that it is always possible to
27f43e3fdb4ffddff6f71b5597c813c43e1e206564Eli Bendersky/// efficiently compute the exact address of any symbol in the assembly file,
28f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar/// even during the relaxation process.
29f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbarclass MCAsmLayout {
30f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar  MCAssembler &Assembler;
31f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar
32bc1a0cf13950dcd64d6d0398df5419a0a2931721Daniel Dunbar  /// List of sections in layout order.
336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  llvm::SmallVector<MCSection *, 16> SectionOrder;
34bc1a0cf13950dcd64d6d0398df5419a0a2931721Daniel Dunbar
357a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  /// The last fragment which was laid out, or 0 if nothing has been laid
367a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  /// out. Fragments are always laid out in order, so all fragments with a
37d52a2c0a31a49e1a8fa16f6b975d01b1e934a49fEli Bendersky  /// lower ordinal will be valid.
386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  mutable DenseMap<const MCSection *, MCFragment *> LastValidFragment;
399005d45a990ef46f06800bd6bd6a7d1298a33645Daniel Dunbar
4047b3ec4daa12019b98468e8f646501ec285bbb59Daniel Dunbar  /// \brief Make sure that the layout for the given fragment is valid, lazily
4147b3ec4daa12019b98468e8f646501ec285bbb59Daniel Dunbar  /// computing it if necessary.
42d52a2c0a31a49e1a8fa16f6b975d01b1e934a49fEli Bendersky  void ensureValid(const MCFragment *F) const;
4347b3ec4daa12019b98468e8f646501ec285bbb59Daniel Dunbar
44d52a2c0a31a49e1a8fa16f6b975d01b1e934a49fEli Bendersky  /// \brief Is the layout for this fragment valid?
45d52a2c0a31a49e1a8fa16f6b975d01b1e934a49fEli Bendersky  bool isFragmentValid(const MCFragment *F) const;
469005d45a990ef46f06800bd6bd6a7d1298a33645Daniel Dunbar
47f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbarpublic:
484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  MCAsmLayout(MCAssembler &Assembler);
49f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar
50f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar  /// Get the assembler object this is a layout for.
51a0e36d55c495b3325805c659ac365b5faea84e34Daniel Dunbar  MCAssembler &getAssembler() const { return Assembler; }
52207e06ea0446c51cb1d89f6400ec7becc46487f8Daniel Dunbar
53f918d7fd7393049bc87bc03fda2d2cd3cec1dacbDerek Schuff  /// \brief Invalidate the fragments starting with F because it has been
54f918d7fd7393049bc87bc03fda2d2cd3cec1dacbDerek Schuff  /// resized. The fragment's size should have already been updated, but
55f918d7fd7393049bc87bc03fda2d2cd3cec1dacbDerek Schuff  /// its bundle padding will be recomputed.
56f918d7fd7393049bc87bc03fda2d2cd3cec1dacbDerek Schuff  void invalidateFragmentsFrom(MCFragment *F);
570cc8bd48619b943379f5c2cc11a19fb189342925Daniel Dunbar
58b69fc044db8c193348b6611f46432bb21b3cbe90Daniel Dunbar  /// \brief Perform layout for a single fragment, assuming that the previous
597a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  /// fragment has already been laid out correctly, and the parent section has
60b69fc044db8c193348b6611f46432bb21b3cbe90Daniel Dunbar  /// been initialized.
61d52a2c0a31a49e1a8fa16f6b975d01b1e934a49fEli Bendersky  void layoutFragment(MCFragment *Fragment);
62b69fc044db8c193348b6611f46432bb21b3cbe90Daniel Dunbar
636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// \name Section Access (in layout order)
64bc1a0cf13950dcd64d6d0398df5419a0a2931721Daniel Dunbar  /// @{
65bc1a0cf13950dcd64d6d0398df5419a0a2931721Daniel Dunbar
666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  llvm::SmallVectorImpl<MCSection *> &getSectionOrder() { return SectionOrder; }
676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const llvm::SmallVectorImpl<MCSection *> &getSectionOrder() const {
68d13a0caf726e05c9bd939d752ef371d6d467ef28Daniel Dunbar    return SectionOrder;
69d13a0caf726e05c9bd939d752ef371d6d467ef28Daniel Dunbar  }
70bc1a0cf13950dcd64d6d0398df5419a0a2931721Daniel Dunbar
71bc1a0cf13950dcd64d6d0398df5419a0a2931721Daniel Dunbar  /// @}
726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// \name Fragment Layout Data
735d428511ca9607d52a09d3483d0738f483e09934Daniel Dunbar  /// @{
74207e06ea0446c51cb1d89f6400ec7becc46487f8Daniel Dunbar
755d428511ca9607d52a09d3483d0738f483e09934Daniel Dunbar  /// \brief Get the offset of the given fragment inside its containing section.
76432cd5fd9b4c97f1e4a53fcf45e16f7dd6bc085eDaniel Dunbar  uint64_t getFragmentOffset(const MCFragment *F) const;
775d428511ca9607d52a09d3483d0738f483e09934Daniel Dunbar
785d428511ca9607d52a09d3483d0738f483e09934Daniel Dunbar  /// @}
796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// \name Utility Functions
802661f11e4602ad017fa155f6fdcee0a4f2d1ae86Daniel Dunbar  /// @{
815d428511ca9607d52a09d3483d0738f483e09934Daniel Dunbar
82b5844ff1c44f0427bcf132eaece945da411e650fDaniel Dunbar  /// \brief Get the address space size of the given section, as it effects
83b5844ff1c44f0427bcf132eaece945da411e650fDaniel Dunbar  /// layout. This may differ from the size reported by \see getSectionSize() by
84b5844ff1c44f0427bcf132eaece945da411e650fDaniel Dunbar  /// not including section tail padding.
856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint64_t getSectionAddressSize(const MCSection *Sec) const;
86b5844ff1c44f0427bcf132eaece945da411e650fDaniel Dunbar
872661f11e4602ad017fa155f6fdcee0a4f2d1ae86Daniel Dunbar  /// \brief Get the data size of the given section, as emitted to the object
882661f11e4602ad017fa155f6fdcee0a4f2d1ae86Daniel Dunbar  /// file. This may include additional padding, or be 0 for virtual sections.
896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint64_t getSectionFileSize(const MCSection *Sec) const;
90b5844ff1c44f0427bcf132eaece945da411e650fDaniel Dunbar
91ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola  /// \brief Get the offset of the given symbol, as computed in the current
92ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola  /// layout.
936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// \return True on success.
946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const;
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// \brief Variant that reports a fatal error if the offset is not computable.
976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint64_t getSymbolOffset(const MCSymbol &S) const;
98ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola
99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// \brief If this symbol is equivalent to A + Constant, return A.
100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const;
101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1025d428511ca9607d52a09d3483d0738f483e09934Daniel Dunbar  /// @}
103f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar};
104f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar
105f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar} // end namespace llvm
106f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar
107f82f4490b130eca55b08d605456a4ceacccf288aDaniel Dunbar#endif
108