Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
6.7 KiB

  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/JITMemoryManager.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::applyPermissions
  33. /// directly. Clients of MCJIT should call MCJIT::finalizeObject.
  34. class SectionMemoryManager : public JITMemoryManager {
  35. SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
  36. void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
  37. public:
  38. SectionMemoryManager() { }
  39. virtual ~SectionMemoryManager();
  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. virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
  46. unsigned SectionID);
  47. /// \brief Allocates a memory block of (at least) the given size suitable for
  48. /// executable code.
  49. ///
  50. /// The value of \p Alignment must be a power of two. If \p Alignment is zero
  51. /// a default alignment of 16 will be used.
  52. virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
  53. unsigned SectionID,
  54. bool isReadOnly);
  55. /// \brief Applies section-specific memory permissions.
  56. ///
  57. /// This method is called when object loading is complete and section page
  58. /// permissions can be applied. It is up to the memory manager implementation
  59. /// to decide whether or not to act on this method. The memory manager will
  60. /// typically allocate all sections as read-write and then apply specific
  61. /// permissions when this method is called. Code sections cannot be executed
  62. /// until this function has been called.
  63. ///
  64. /// \returns true if an error occurred, false otherwise.
  65. virtual bool applyPermissions(std::string *ErrMsg = 0);
  66. /// This method returns the address of the specified function. As such it is
  67. /// only useful for resolving library symbols, not code generated symbols.
  68. ///
  69. /// If \p AbortOnFailure is false and no function with the given name is
  70. /// found, this function returns a null pointer. Otherwise, it prints a
  71. /// message to stderr and aborts.
  72. virtual void *getPointerToNamedFunction(const std::string &Name,
  73. bool AbortOnFailure = true);
  74. /// \brief Invalidate instruction cache for code sections.
  75. ///
  76. /// Some platforms with separate data cache and instruction cache require
  77. /// explicit cache flush, otherwise JIT code manipulations (like resolved
  78. /// relocations) will get to the data cache but not to the instruction cache.
  79. ///
  80. /// This method is not called by RuntimeDyld or MCJIT during the load
  81. /// process. Clients may call this function when needed. See the lli
  82. /// tool for example use.
  83. virtual void invalidateInstructionCache();
  84. private:
  85. struct MemoryGroup {
  86. SmallVector<sys::MemoryBlock, 16> AllocatedMem;
  87. SmallVector<sys::MemoryBlock, 16> FreeMem;
  88. sys::MemoryBlock Near;
  89. };
  90. uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size,
  91. unsigned Alignment);
  92. error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup,
  93. unsigned Permissions);
  94. MemoryGroup CodeMem;
  95. MemoryGroup RWDataMem;
  96. MemoryGroup RODataMem;
  97. public:
  98. ///
  99. /// Functions below are not used by MCJIT or RuntimeDyld, but must be
  100. /// implemented because they are declared as pure virtuals in the base class.
  101. ///
  102. virtual void setMemoryWritable() {
  103. llvm_unreachable("Unexpected call!");
  104. }
  105. virtual void setMemoryExecutable() {
  106. llvm_unreachable("Unexpected call!");
  107. }
  108. virtual void setPoisonMemory(bool poison) {
  109. llvm_unreachable("Unexpected call!");
  110. }
  111. virtual void AllocateGOT() {
  112. llvm_unreachable("Unexpected call!");
  113. }
  114. virtual uint8_t *getGOTBase() const {
  115. llvm_unreachable("Unexpected call!");
  116. return 0;
  117. }
  118. virtual uint8_t *startFunctionBody(const Function *F,
  119. uintptr_t &ActualSize){
  120. llvm_unreachable("Unexpected call!");
  121. return 0;
  122. }
  123. virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize,
  124. unsigned Alignment) {
  125. llvm_unreachable("Unexpected call!");
  126. return 0;
  127. }
  128. virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
  129. uint8_t *FunctionEnd) {
  130. llvm_unreachable("Unexpected call!");
  131. }
  132. virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
  133. llvm_unreachable("Unexpected call!");
  134. return 0;
  135. }
  136. virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
  137. llvm_unreachable("Unexpected call!");
  138. return 0;
  139. }
  140. virtual void deallocateFunctionBody(void *Body) {
  141. llvm_unreachable("Unexpected call!");
  142. }
  143. virtual uint8_t *startExceptionTable(const Function *F,
  144. uintptr_t &ActualSize) {
  145. llvm_unreachable("Unexpected call!");
  146. return 0;
  147. }
  148. virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
  149. uint8_t *TableEnd, uint8_t *FrameRegister) {
  150. llvm_unreachable("Unexpected call!");
  151. }
  152. virtual void deallocateExceptionTable(void *ET) {
  153. llvm_unreachable("Unexpected call!");
  154. }
  155. };
  156. }
  157. #endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H