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" 16 using namespace llvm; 17 18 RecordingMemoryManager::~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 29 uint8_t *RecordingMemoryManager:: 30 allocateCodeSection(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 40 uint8_t *RecordingMemoryManager:: 41 allocateDataSection(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 52 sys::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 69 void RecordingMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); } 70 void RecordingMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); } 71 void RecordingMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); } 72 void RecordingMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); } 73 uint8_t *RecordingMemoryManager::getGOTBase() const { 74 llvm_unreachable("Unexpected!"); 75 return 0; 76 } 77 uint8_t *RecordingMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){ 78 llvm_unreachable("Unexpected!"); 79 return 0; 80 } 81 uint8_t *RecordingMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize, 82 unsigned Alignment) { 83 llvm_unreachable("Unexpected!"); 84 return 0; 85 } 86 void RecordingMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart, 87 uint8_t *FunctionEnd) { 88 llvm_unreachable("Unexpected!"); 89 } 90 uint8_t *RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) { 91 llvm_unreachable("Unexpected!"); 92 return 0; 93 } 94 uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) { 95 llvm_unreachable("Unexpected!"); 96 return 0; 97 } 98 void RecordingMemoryManager::deallocateFunctionBody(void *Body) { 99 llvm_unreachable("Unexpected!"); 100 } 101 102 static int jit_noop() { 103 return 0; 104 } 105 106 void *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