1//===- RecordingMemoryManager.cpp - Recording memory manager --------------===// 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 memory manager allocates local storage and keeps a record of each 11// allocation. Iterators are provided for all data and code allocations. 12// 13//===----------------------------------------------------------------------===// 14 15#include "RecordingMemoryManager.h" 16using namespace llvm; 17 18RecordingMemoryManager::~RecordingMemoryManager() { 19 for (SmallVectorImpl<Allocation>::iterator 20 I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end(); 21 I != E; ++I) 22 sys::Memory::releaseMappedMemory(I->first); 23 for (SmallVectorImpl<Allocation>::iterator 24 I = AllocatedDataMem.begin(), E = AllocatedDataMem.end(); 25 I != E; ++I) 26 sys::Memory::releaseMappedMemory(I->first); 27} 28 29uint8_t *RecordingMemoryManager:: 30allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { 31 // The recording memory manager is just a local copy of the remote target. 32 // The alignment requirement is just stored here for later use. Regular 33 // heap storage is sufficient here, but we're using mapped memory to work 34 // around a bug in MCJIT. 35 sys::MemoryBlock Block = allocateSection(Size); 36 AllocatedCodeMem.push_back(Allocation(Block, Alignment)); 37 return (uint8_t*)Block.base(); 38} 39 40uint8_t *RecordingMemoryManager:: 41allocateDataSection(uintptr_t Size, unsigned Alignment, 42 unsigned SectionID, bool IsReadOnly) { 43 // The recording memory manager is just a local copy of the remote target. 44 // The alignment requirement is just stored here for later use. Regular 45 // heap storage is sufficient here, but we're using mapped memory to work 46 // around a bug in MCJIT. 47 sys::MemoryBlock Block = allocateSection(Size); 48 AllocatedDataMem.push_back(Allocation(Block, Alignment)); 49 return (uint8_t*)Block.base(); 50} 51 52sys::MemoryBlock RecordingMemoryManager::allocateSection(uintptr_t Size) { 53 error_code ec; 54 sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size, 55 &Near, 56 sys::Memory::MF_READ | 57 sys::Memory::MF_WRITE, 58 ec); 59 assert(!ec && MB.base()); 60 61 // FIXME: This is part of a work around to keep sections near one another 62 // when MCJIT performs relocations after code emission but before 63 // the generated code is moved to the remote target. 64 // Save this address as the basis for our next request 65 Near = MB; 66 return MB; 67} 68 69void RecordingMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); } 70void RecordingMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); } 71void RecordingMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); } 72void RecordingMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); } 73uint8_t *RecordingMemoryManager::getGOTBase() const { 74 llvm_unreachable("Unexpected!"); 75 return 0; 76} 77uint8_t *RecordingMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){ 78 llvm_unreachable("Unexpected!"); 79 return 0; 80} 81uint8_t *RecordingMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize, 82 unsigned Alignment) { 83 llvm_unreachable("Unexpected!"); 84 return 0; 85} 86void RecordingMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart, 87 uint8_t *FunctionEnd) { 88 llvm_unreachable("Unexpected!"); 89} 90uint8_t *RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) { 91 llvm_unreachable("Unexpected!"); 92 return 0; 93} 94uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) { 95 llvm_unreachable("Unexpected!"); 96 return 0; 97} 98void RecordingMemoryManager::deallocateFunctionBody(void *Body) { 99 llvm_unreachable("Unexpected!"); 100} 101 102static int jit_noop() { 103 return 0; 104} 105 106void *RecordingMemoryManager::getPointerToNamedFunction(const std::string &Name, 107 bool AbortOnFailure) { 108 // We should not invoke parent's ctors/dtors from generated main()! 109 // On Mingw and Cygwin, the symbol __main is resolved to 110 // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors 111 // (and register wrong callee's dtors with atexit(3)). 112 // We expect ExecutionEngine::runStaticConstructorsDestructors() 113 // is called before ExecutionEngine::runFunctionAsMain() is called. 114 if (Name == "__main") return (void*)(intptr_t)&jit_noop; 115 116 return NULL; 117} 118