MCAsmLayout.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- MCAsmLayout.h - Assembly Layout Object -------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_MC_MCASMLAYOUT_H
  14. #define LLVM_MC_MCASMLAYOUT_H
  15. #include "llvm/ADT/DenseMap.h"
  16. #include "llvm/ADT/SmallVector.h"
  17. namespace llvm {
  18. class MCAssembler;
  19. class MCFragment;
  20. class MCSection;
  21. class MCSymbol;
  22. /// Encapsulates the layout of an assembly file at a particular point in time.
  23. ///
  24. /// Assembly may require computing multiple layouts for a particular assembly
  25. /// file as part of the relaxation process. This class encapsulates the layout
  26. /// at a single point in time in such a way that it is always possible to
  27. /// efficiently compute the exact address of any symbol in the assembly file,
  28. /// even during the relaxation process.
  29. class MCAsmLayout {
  30. MCAssembler &Assembler;
  31. /// List of sections in layout order.
  32. llvm::SmallVector<MCSection *, 16> SectionOrder;
  33. /// The last fragment which was laid out, or 0 if nothing has been laid
  34. /// out. Fragments are always laid out in order, so all fragments with a
  35. /// lower ordinal will be valid.
  36. mutable DenseMap<const MCSection *, MCFragment *> LastValidFragment;
  37. /// Make sure that the layout for the given fragment is valid, lazily
  38. /// computing it if necessary.
  39. void ensureValid(const MCFragment *F) const;
  40. /// Is the layout for this fragment valid?
  41. bool isFragmentValid(const MCFragment *F) const;
  42. public:
  43. MCAsmLayout(MCAssembler &Assembler);
  44. /// Get the assembler object this is a layout for.
  45. MCAssembler &getAssembler() const { return Assembler; }
  46. /// \returns whether the offset of fragment \p F can be obtained via
  47. /// getFragmentOffset.
  48. bool canGetFragmentOffset(const MCFragment *F) const;
  49. /// Invalidate the fragments starting with F because it has been
  50. /// resized. The fragment's size should have already been updated, but
  51. /// its bundle padding will be recomputed.
  52. void invalidateFragmentsFrom(MCFragment *F);
  53. /// Perform layout for a single fragment, assuming that the previous
  54. /// fragment has already been laid out correctly, and the parent section has
  55. /// been initialized.
  56. void layoutFragment(MCFragment *Fragment);
  57. /// \name Section Access (in layout order)
  58. /// @{
  59. llvm::SmallVectorImpl<MCSection *> &getSectionOrder() { return SectionOrder; }
  60. const llvm::SmallVectorImpl<MCSection *> &getSectionOrder() const {
  61. return SectionOrder;
  62. }
  63. /// @}
  64. /// \name Fragment Layout Data
  65. /// @{
  66. /// Get the offset of the given fragment inside its containing section.
  67. uint64_t getFragmentOffset(const MCFragment *F) const;
  68. /// @}
  69. /// \name Utility Functions
  70. /// @{
  71. /// Get the address space size of the given section, as it effects
  72. /// layout. This may differ from the size reported by \see getSectionSize() by
  73. /// not including section tail padding.
  74. uint64_t getSectionAddressSize(const MCSection *Sec) const;
  75. /// Get the data size of the given section, as emitted to the object
  76. /// file. This may include additional padding, or be 0 for virtual sections.
  77. uint64_t getSectionFileSize(const MCSection *Sec) const;
  78. /// Get the offset of the given symbol, as computed in the current
  79. /// layout.
  80. /// \return True on success.
  81. bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const;
  82. /// Variant that reports a fatal error if the offset is not computable.
  83. uint64_t getSymbolOffset(const MCSymbol &S) const;
  84. /// If this symbol is equivalent to A + Constant, return A.
  85. const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const;
  86. /// @}
  87. };
  88. } // end namespace llvm
  89. #endif
  90. #ifdef __GNUC__
  91. #pragma GCC diagnostic pop
  92. #endif