1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "LLVMRoutineManager.hpp" 16 17 #if REACTOR_LLVM_VERSION < 7 18 19 #include "LLVMRoutine.hpp" 20 #include "llvm/Function.h" 21 #include "ExecutableMemory.hpp" 22 #include "Thread.hpp" 23 #include "Debug.hpp" 24 25 namespace rr 26 { 27 using namespace llvm; 28 29 volatile int LLVMRoutineManager::averageInstructionSize = 4; 30 LLVMRoutineManager()31 LLVMRoutineManager::LLVMRoutineManager() 32 { 33 routine = nullptr; 34 } 35 ~LLVMRoutineManager()36 LLVMRoutineManager::~LLVMRoutineManager() 37 { 38 delete routine; 39 } 40 AllocateGOT()41 void LLVMRoutineManager::AllocateGOT() 42 { 43 UNIMPLEMENTED(); 44 } 45 allocateStub(const GlobalValue * function,unsigned stubSize,unsigned alignment)46 uint8_t *LLVMRoutineManager::allocateStub(const GlobalValue *function, unsigned stubSize, unsigned alignment) 47 { 48 UNIMPLEMENTED(); 49 return nullptr; 50 } 51 startFunctionBody(const llvm::Function * function,uintptr_t & actualSize)52 uint8_t *LLVMRoutineManager::startFunctionBody(const llvm::Function *function, uintptr_t &actualSize) 53 { 54 if(actualSize == 0) // Estimate size 55 { 56 size_t instructionCount = 0; 57 for(llvm::Function::const_iterator basicBlock = function->begin(); basicBlock != function->end(); basicBlock++) 58 { 59 instructionCount += basicBlock->size(); 60 } 61 62 actualSize = instructionCount * averageInstructionSize; 63 } 64 else // Estimate was too low 65 { 66 atomicIncrement(&averageInstructionSize); 67 } 68 69 // Round up to the next page size 70 size_t pageSize = memoryPageSize(); 71 actualSize = (actualSize + pageSize - 1) & ~(pageSize - 1); 72 73 delete routine; 74 routine = new LLVMRoutine(static_cast<int>(actualSize)); 75 76 return (uint8_t*)routine->buffer; 77 } 78 endFunctionBody(const llvm::Function * function,uint8_t * functionStart,uint8_t * functionEnd)79 void LLVMRoutineManager::endFunctionBody(const llvm::Function *function, uint8_t *functionStart, uint8_t *functionEnd) 80 { 81 routine->functionSize = static_cast<int>(static_cast<ptrdiff_t>(functionEnd - functionStart)); 82 } 83 startExceptionTable(const llvm::Function * F,uintptr_t & ActualSize)84 uint8_t *LLVMRoutineManager::startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize) 85 { 86 UNIMPLEMENTED(); 87 return nullptr; 88 } 89 endExceptionTable(const llvm::Function * F,uint8_t * TableStart,uint8_t * TableEnd,uint8_t * FrameRegister)90 void LLVMRoutineManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart, uint8_t *TableEnd, uint8_t* FrameRegister) 91 { 92 UNIMPLEMENTED(); 93 } 94 getGOTBase() const95 uint8_t *LLVMRoutineManager::getGOTBase() const 96 { 97 ASSERT(!HasGOT); 98 return nullptr; 99 } 100 allocateSpace(intptr_t Size,unsigned Alignment)101 uint8_t *LLVMRoutineManager::allocateSpace(intptr_t Size, unsigned Alignment) 102 { 103 UNIMPLEMENTED(); 104 return nullptr; 105 } 106 allocateGlobal(uintptr_t Size,unsigned Alignment)107 uint8_t *LLVMRoutineManager::allocateGlobal(uintptr_t Size, unsigned Alignment) 108 { 109 UNIMPLEMENTED(); 110 return nullptr; 111 } 112 deallocateFunctionBody(void * Body)113 void LLVMRoutineManager::deallocateFunctionBody(void *Body) 114 { 115 delete routine; 116 routine = nullptr; 117 } 118 deallocateExceptionTable(void * ET)119 void LLVMRoutineManager::deallocateExceptionTable(void *ET) 120 { 121 if(ET) 122 { 123 UNIMPLEMENTED(); 124 } 125 } 126 setMemoryWritable()127 void LLVMRoutineManager::setMemoryWritable() 128 { 129 } 130 setMemoryExecutable()131 void LLVMRoutineManager::setMemoryExecutable() 132 { 133 markExecutable(routine->buffer, routine->bufferSize); 134 } 135 setPoisonMemory(bool poison)136 void LLVMRoutineManager::setPoisonMemory(bool poison) 137 { 138 UNIMPLEMENTED(); 139 } 140 acquireRoutine(void * entry)141 LLVMRoutine *LLVMRoutineManager::acquireRoutine(void *entry) 142 { 143 routine->entry = entry; 144 145 LLVMRoutine *result = routine; 146 routine = nullptr; 147 148 return result; 149 } 150 } 151 152 #endif // REACTOR_LLVM_VERSION < 7 153