1cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===// 22d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 32d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// The LLVM Compiler Infrastructure 42d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 52d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// This file is distributed under the University of Illinois Open Source 62d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// License. See LICENSE.TXT for details. 72d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 82d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor//===----------------------------------------------------------------------===// 92d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 102d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// This file contains the declaration of a section-based memory manager used by 11cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor// the MCJIT execution engine and RuntimeDyld. 122d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 132d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor//===----------------------------------------------------------------------===// 142d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 15674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#ifndef LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H 16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H 172d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 182d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#include "llvm/ADT/SmallVector.h" 1913a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizlo#include "llvm/ExecutionEngine/RuntimeDyld.h" 202d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#include "llvm/Support/ErrorHandling.h" 212d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#include "llvm/Support/Memory.h" 222d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 232d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylornamespace llvm { 24927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor/// This is a simple memory manager which implements the methods called by 25cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor/// the RuntimeDyld class to allocate memory for section-based loading of 26cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor/// objects, usually those generated by the MCJIT execution engine. 27927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor/// 28927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor/// This memory manager allocates all section memory as read-write. The 29cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor/// RuntimeDyld will copy JITed section memory into these allocated blocks 30cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor/// and perform any necessary linking and relocations. 31927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor/// 32cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor/// Any client using this memory manager MUST ensure that section-specific 33cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor/// page permissions have been applied before attempting to execute functions 34cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor/// in the JITed object. Permissions can be applied either by calling 35abb38fe8dec11b1ea7535f84fac8ad0f0af70addDavid Tweed/// MCJIT::finalizeObject or by calling SectionMemoryManager::finalizeMemory 36cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor/// directly. Clients of MCJIT should call MCJIT::finalizeObject. 3713a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizloclass SectionMemoryManager : public RTDyldMemoryManager { 38cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; 39cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; 402d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 412d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylorpublic: 422d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor SectionMemoryManager() { } 43cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor virtual ~SectionMemoryManager(); 442d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 45cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// \brief Allocates a memory block of (at least) the given size suitable for 46cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// executable code. 47927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor /// 48cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// The value of \p Alignment must be a power of two. If \p Alignment is zero 49cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// a default alignment of 16 will be used. 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SectionID, 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SectionName) override; 532d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 54cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// \brief Allocates a memory block of (at least) the given size suitable for 55cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// executable code. 56927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor /// 57cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// The value of \p Alignment must be a power of two. If \p Alignment is zero 58cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// a default alignment of 16 will be used. 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SectionID, StringRef SectionName, 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isReadOnly) override; 6253608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor 63abb38fe8dec11b1ea7535f84fac8ad0f0af70addDavid Tweed /// \brief Update section-specific memory permissions and other attributes. 64cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// 65cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// This method is called when object loading is complete and section page 66cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// permissions can be applied. It is up to the memory manager implementation 67cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// to decide whether or not to act on this method. The memory manager will 68cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// typically allocate all sections as read-write and then apply specific 69cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// permissions when this method is called. Code sections cannot be executed 70abb38fe8dec11b1ea7535f84fac8ad0f0af70addDavid Tweed /// until this function has been called. In addition, any cache coherency 71abb38fe8dec11b1ea7535f84fac8ad0f0af70addDavid Tweed /// operations needed to reliably use the memory are also performed. 72cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// 73cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// \returns true if an error occurred, false otherwise. 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool finalizeMemory(std::string *ErrMsg = nullptr) override; 752d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 76cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// \brief Invalidate instruction cache for code sections. 77cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// 78cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// Some platforms with separate data cache and instruction cache require 79cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// explicit cache flush, otherwise JIT code manipulations (like resolved 80cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor /// relocations) will get to the data cache but not to the instruction cache. 81927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor /// 82abb38fe8dec11b1ea7535f84fac8ad0f0af70addDavid Tweed /// This method is called from finalizeMemory. 832d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor virtual void invalidateInstructionCache(); 842d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 852d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylorprivate: 86cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor struct MemoryGroup { 87cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor SmallVector<sys::MemoryBlock, 16> AllocatedMem; 88cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor SmallVector<sys::MemoryBlock, 16> FreeMem; 89cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor sys::MemoryBlock Near; 90cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor }; 912d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 92cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size, 93cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor unsigned Alignment); 942d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 95cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, 96cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Permissions); 97cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 98cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor MemoryGroup CodeMem; 99cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor MemoryGroup RWDataMem; 100cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor MemoryGroup RODataMem; 1012d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor}; 1022d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1032d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor} 1042d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1052d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H 106cc7773bdcbecf893cb9442a77cdf5e41f2af4256Andrew Kaylor 107