SectionMemoryManager.h revision 251662
1126261Smlaier//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===// 2126258Smlaier// 3126258Smlaier// The LLVM Compiler Infrastructure 4126258Smlaier// 5126258Smlaier// This file is distributed under the University of Illinois Open Source 6126258Smlaier// License. See LICENSE.TXT for details. 7126258Smlaier// 8126258Smlaier//===----------------------------------------------------------------------===// 9126258Smlaier// 10126258Smlaier// This file contains the declaration of a section-based memory manager used by 11126258Smlaier// the MCJIT execution engine and RuntimeDyld. 12126258Smlaier// 13126258Smlaier//===----------------------------------------------------------------------===// 14126258Smlaier 15126258Smlaier#ifndef LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H 16126258Smlaier#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H 17126258Smlaier 18126258Smlaier#include "llvm/ADT/SmallVector.h" 19126258Smlaier#include "llvm/ExecutionEngine/JITMemoryManager.h" 20126258Smlaier#include "llvm/Support/ErrorHandling.h" 21126258Smlaier#include "llvm/Support/Memory.h" 22126258Smlaier 23126258Smlaiernamespace llvm { 24126258Smlaier 25126258Smlaier/// This is a simple memory manager which implements the methods called by 26126258Smlaier/// the RuntimeDyld class to allocate memory for section-based loading of 27126258Smlaier/// objects, usually those generated by the MCJIT execution engine. 28126258Smlaier/// 29126258Smlaier/// This memory manager allocates all section memory as read-write. The 30127145Smlaier/// RuntimeDyld will copy JITed section memory into these allocated blocks 31126261Smlaier/// and perform any necessary linking and relocations. 32126261Smlaier/// 33126261Smlaier/// Any client using this memory manager MUST ensure that section-specific 34126261Smlaier/// page permissions have been applied before attempting to execute functions 35127145Smlaier/// in the JITed object. Permissions can be applied either by calling 36126258Smlaier/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions 37126258Smlaier/// directly. Clients of MCJIT should call MCJIT::finalizeObject. 38126261Smlaierclass SectionMemoryManager : public JITMemoryManager { 39126261Smlaier SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; 40126261Smlaier void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; 41127145Smlaier 42127145Smlaierpublic: 43126261Smlaier SectionMemoryManager() { } 44126258Smlaier virtual ~SectionMemoryManager(); 45126258Smlaier 46126258Smlaier /// \brief Allocates a memory block of (at least) the given size suitable for 47126258Smlaier /// executable code. 48126258Smlaier /// 49126258Smlaier /// The value of \p Alignment must be a power of two. If \p Alignment is zero 50127145Smlaier /// a default alignment of 16 will be used. 51126261Smlaier virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 52126261Smlaier unsigned SectionID); 53129907Smlaier 54126261Smlaier /// \brief Allocates a memory block of (at least) the given size suitable for 55126261Smlaier /// executable code. 56126258Smlaier /// 57126258Smlaier /// The value of \p Alignment must be a power of two. If \p Alignment is zero 58126261Smlaier /// a default alignment of 16 will be used. 59126258Smlaier virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 60126258Smlaier unsigned SectionID, 61126258Smlaier bool isReadOnly); 62126258Smlaier 63126258Smlaier /// \brief Applies section-specific memory permissions. 64126258Smlaier /// 65126258Smlaier /// This method is called when object loading is complete and section page 66126258Smlaier /// permissions can be applied. It is up to the memory manager implementation 67126258Smlaier /// to decide whether or not to act on this method. The memory manager will 68126258Smlaier /// typically allocate all sections as read-write and then apply specific 69126258Smlaier /// permissions when this method is called. Code sections cannot be executed 70126258Smlaier /// until this function has been called. 71126258Smlaier /// 72126258Smlaier /// \returns true if an error occurred, false otherwise. 73126258Smlaier virtual bool applyPermissions(std::string *ErrMsg = 0); 74126258Smlaier 75126258Smlaier void registerEHFrames(StringRef SectionData); 76126258Smlaier 77126258Smlaier /// This method returns the address of the specified function. As such it is 78126258Smlaier /// only useful for resolving library symbols, not code generated symbols. 79126258Smlaier /// 80127145Smlaier /// If \p AbortOnFailure is false and no function with the given name is 81127145Smlaier /// found, this function returns a null pointer. Otherwise, it prints a 82126261Smlaier /// message to stderr and aborts. 83126261Smlaier virtual void *getPointerToNamedFunction(const std::string &Name, 84126258Smlaier bool AbortOnFailure = true); 85126258Smlaier 86126258Smlaier /// \brief Invalidate instruction cache for code sections. 87126258Smlaier /// 88126258Smlaier /// Some platforms with separate data cache and instruction cache require 89126258Smlaier /// explicit cache flush, otherwise JIT code manipulations (like resolved 90126258Smlaier /// relocations) will get to the data cache but not to the instruction cache. 91126258Smlaier /// 92126258Smlaier /// This method is called from applyPermissions. 93126258Smlaier virtual void invalidateInstructionCache(); 94127145Smlaier 95126258Smlaierprivate: 96126261Smlaier struct MemoryGroup { 97126258Smlaier SmallVector<sys::MemoryBlock, 16> AllocatedMem; 98127145Smlaier SmallVector<sys::MemoryBlock, 16> FreeMem; 99128209Sbrooks sys::MemoryBlock Near; 100128209Sbrooks }; 101126261Smlaier 102126258Smlaier uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size, 103126261Smlaier unsigned Alignment); 104126258Smlaier 105126258Smlaier error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, 106126258Smlaier unsigned Permissions); 107126258Smlaier 108126258Smlaier MemoryGroup CodeMem; 109126258Smlaier MemoryGroup RWDataMem; 110126258Smlaier MemoryGroup RODataMem; 111126258Smlaier 112126258Smlaierpublic: 113126258Smlaier /// 114127145Smlaier /// Functions below are not used by MCJIT or RuntimeDyld, but must be 115126258Smlaier /// implemented because they are declared as pure virtuals in the base class. 116126261Smlaier /// 117126258Smlaier 118127145Smlaier virtual void setMemoryWritable() { 119126261Smlaier llvm_unreachable("Unexpected call!"); 120126261Smlaier } 121126261Smlaier virtual void setMemoryExecutable() { 122126261Smlaier llvm_unreachable("Unexpected call!"); 123126261Smlaier } 124128209Sbrooks virtual void setPoisonMemory(bool poison) { 125126261Smlaier llvm_unreachable("Unexpected call!"); 126126261Smlaier } 127126261Smlaier virtual void AllocateGOT() { 128126261Smlaier llvm_unreachable("Unexpected call!"); 129126261Smlaier } 130126261Smlaier virtual uint8_t *getGOTBase() const { 131126261Smlaier llvm_unreachable("Unexpected call!"); 132126261Smlaier return 0; 133126261Smlaier } 134126261Smlaier virtual uint8_t *startFunctionBody(const Function *F, 135126261Smlaier uintptr_t &ActualSize){ 136126261Smlaier llvm_unreachable("Unexpected call!"); 137126261Smlaier return 0; 138126261Smlaier } 139126261Smlaier virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize, 140126261Smlaier unsigned Alignment) { 141126261Smlaier llvm_unreachable("Unexpected call!"); 142126261Smlaier return 0; 143126261Smlaier } 144126261Smlaier virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, 145128209Sbrooks uint8_t *FunctionEnd) { 146126261Smlaier llvm_unreachable("Unexpected call!"); 147126261Smlaier } 148126261Smlaier virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { 149126261Smlaier llvm_unreachable("Unexpected call!"); 150126261Smlaier return 0; 151126261Smlaier } 152126261Smlaier virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { 153126261Smlaier llvm_unreachable("Unexpected call!"); 154126261Smlaier return 0; 155126261Smlaier } 156126261Smlaier virtual void deallocateFunctionBody(void *Body) { 157126261Smlaier llvm_unreachable("Unexpected call!"); 158126261Smlaier } 159126261Smlaier virtual uint8_t *startExceptionTable(const Function *F, 160126261Smlaier uintptr_t &ActualSize) { 161126261Smlaier llvm_unreachable("Unexpected call!"); 162126261Smlaier return 0; 163126261Smlaier } 164126261Smlaier virtual void endExceptionTable(const Function *F, uint8_t *TableStart, 165126261Smlaier uint8_t *TableEnd, uint8_t *FrameRegister) { 166126261Smlaier llvm_unreachable("Unexpected call!"); 167126261Smlaier } 168126261Smlaier virtual void deallocateExceptionTable(void *ET) { 169126261Smlaier llvm_unreachable("Unexpected call!"); 170126261Smlaier } 171126261Smlaier}; 172126261Smlaier 173126261Smlaier} 174126261Smlaier 175126261Smlaier#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H 176126261Smlaier 177126261Smlaier