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