SectionMemoryManager.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- 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 contains the declaration of a section-based memory manager used by
  11. // the MCJIT execution engine and RuntimeDyld.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
  15. #define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
  16. #include "llvm/ADT/SmallVector.h"
  17. #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
  18. #include "llvm/Support/ErrorHandling.h"
  19. #include "llvm/Support/Memory.h"
  20. namespace llvm {
  21. /// This is a simple memory manager which implements the methods called by
  22. /// the RuntimeDyld class to allocate memory for section-based loading of
  23. /// objects, usually those generated by the MCJIT execution engine.
  24. ///
  25. /// This memory manager allocates all section memory as read-write. The
  26. /// RuntimeDyld will copy JITed section memory into these allocated blocks
  27. /// and perform any necessary linking and relocations.
  28. ///
  29. /// Any client using this memory manager MUST ensure that section-specific
  30. /// page permissions have been applied before attempting to execute functions
  31. /// in the JITed object. Permissions can be applied either by calling
  32. /// MCJIT::finalizeObject or by calling SectionMemoryManager::finalizeMemory
  33. /// directly. Clients of MCJIT should call MCJIT::finalizeObject.
  34. class SectionMemoryManager : public RTDyldMemoryManager {
  35. SectionMemoryManager(const SectionMemoryManager&) = delete;
  36. void operator=(const SectionMemoryManager&) = delete;
  37. public:
  38. SectionMemoryManager() { }
  39. ~SectionMemoryManager() override;
  40. /// \brief Allocates a memory block of (at least) the given size suitable for
  41. /// executable code.
  42. ///
  43. /// The value of \p Alignment must be a power of two. If \p Alignment is zero
  44. /// a default alignment of 16 will be used.
  45. uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
  46. unsigned SectionID,
  47. StringRef SectionName) override;
  48. /// \brief Allocates a memory block of (at least) the given size suitable for
  49. /// executable code.
  50. ///
  51. /// The value of \p Alignment must be a power of two. If \p Alignment is zero
  52. /// a default alignment of 16 will be used.
  53. uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
  54. unsigned SectionID, StringRef SectionName,
  55. bool isReadOnly) override;
  56. /// \brief Update section-specific memory permissions and other attributes.
  57. ///
  58. /// This method is called when object loading is complete and section page
  59. /// permissions can be applied. It is up to the memory manager implementation
  60. /// to decide whether or not to act on this method. The memory manager will
  61. /// typically allocate all sections as read-write and then apply specific
  62. /// permissions when this method is called. Code sections cannot be executed
  63. /// until this function has been called. In addition, any cache coherency
  64. /// operations needed to reliably use the memory are also performed.
  65. ///
  66. /// \returns true if an error occurred, false otherwise.
  67. bool finalizeMemory(std::string *ErrMsg = nullptr) override;
  68. /// \brief Invalidate instruction cache for code sections.
  69. ///
  70. /// Some platforms with separate data cache and instruction cache require
  71. /// explicit cache flush, otherwise JIT code manipulations (like resolved
  72. /// relocations) will get to the data cache but not to the instruction cache.
  73. ///
  74. /// This method is called from finalizeMemory.
  75. virtual void invalidateInstructionCache();
  76. private:
  77. struct MemoryGroup {
  78. SmallVector<sys::MemoryBlock, 16> AllocatedMem;
  79. SmallVector<sys::MemoryBlock, 16> FreeMem;
  80. sys::MemoryBlock Near;
  81. };
  82. uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size,
  83. unsigned Alignment);
  84. std::error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup,
  85. unsigned Permissions);
  86. MemoryGroup CodeMem;
  87. MemoryGroup RWDataMem;
  88. MemoryGroup RODataMem;
  89. };
  90. }
  91. #endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H