Commit aff3ad41 by Nicolas Capens

Deprecate DLL precaching support.

It has bitrotted and should be reimplemented with support from the Reactor back-end if needed again. Bug swiftshader:10 Change-Id: Ie926903ccd8117e91b9d13bf031a7b88287e7276 Reviewed-on: https://swiftshader-review.googlesource.com/7250Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 2ab69ee7
...@@ -677,8 +677,6 @@ if(WIN32) ...@@ -677,8 +677,6 @@ if(WIN32)
${SOURCE_DIR}/Main/FrameBufferGDI.hpp ${SOURCE_DIR}/Main/FrameBufferGDI.hpp
${SOURCE_DIR}/Main/FrameBufferWin.cpp ${SOURCE_DIR}/Main/FrameBufferWin.cpp
${SOURCE_DIR}/Main/FrameBufferWin.hpp ${SOURCE_DIR}/Main/FrameBufferWin.hpp
${SOURCE_DIR}/Reactor/DLL.cpp
${SOURCE_DIR}/Reactor/DLL.hpp
) )
list(APPEND OPENGL_COMPILER_LIST ${OPENGL_COMPILER_DIR}/ossource_win.cpp) list(APPEND OPENGL_COMPILER_LIST ${OPENGL_COMPILER_DIR}/ossource_win.cpp)
list(APPEND EGL_LIST ${OPENGL_DIR}/libEGL/libEGL.rc) list(APPEND EGL_LIST ${OPENGL_DIR}/libEGL/libEGL.rc)
......
...@@ -47,7 +47,6 @@ source_set("swiftshader_reactor") { ...@@ -47,7 +47,6 @@ source_set("swiftshader_reactor") {
] ]
if (is_win) { if (is_win) {
sources += [ "DLL.cpp" ]
configs -= [ "//build/config/win:unicode" ] configs -= [ "//build/config/win:unicode" ]
} }
......
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "DLL.hpp"
#include <time.h>
#ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
#endif
#ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
#endif
namespace sw
{
#ifdef _M_AMD64
const bool AMD64 = true;
#else
const bool AMD64 = false;
#endif
DLL::DLL(const char *name, const void *constants, int constSize) : constants(constants), constSize(constSize)
{
dllName = new char[strlen(name) + 1];
strcpy(dllName, name);
codeSize = 0;
}
DLL::~DLL()
{
delete[] dllName;
for(FunctionList::iterator i = functionList.begin(); i != functionList.end(); i++)
{
delete i->second;
}
}
void DLL::addFunction(const void *function, const void *entry, int size)
{
functionOrder.push_back(function);
functionList[function] = new Function(codeSize, function, entry, size);
codeSize += size;
}
void DLL::addRelocation(const void *function, const void *address, bool ripRelative)
{
globalRelocations[function].push_back(Relocation((unsigned int)((unsigned char*)address - (unsigned char*)function), ripRelative));
}
void DLL::emit()
{
if(codeSize == 0)
{
return;
}
for(GlobalRelocations::iterator i = globalRelocations.begin(); i != globalRelocations.end(); i++)
{
const unsigned char *function = (const unsigned char*)i->first;
const std::vector<Relocation> &functionRelocations = i->second;
unsigned int location = functionList[function]->location;
for(unsigned int j = 0; j < functionRelocations.size(); j++)
{
unsigned int address = location + functionRelocations[j].offset;
unsigned int page = address / 0x1000;
unsigned short reloc = address - page * 0x1000;
unsigned int relocType = AMD64 ? IMAGE_REL_BASED_DIR64 : IMAGE_REL_BASED_HIGHLOW;
pageRelocations[page].push_back((relocType << 12) | reloc);
}
}
if(pageRelocations.empty())
{
pageRelocations[0]; // Initialize an emtpy list
}
int relocSize = 0;
for(PageRelocations::iterator i = pageRelocations.begin(); i != pageRelocations.end(); i++)
{
if(i->second.size() % 2) // Pad to align to DWORD
{
i->second.push_back(0);
}
relocSize += (int)sizeof(IMAGE_BASE_RELOCATION) + (int)i->second.size() * (int)sizeof(unsigned short);
}
unsigned long timeDateStamp = (unsigned long)time(0);
memset(&DOSheader, 0, sizeof(DOSheader));
DOSheader.e_magic = IMAGE_DOS_SIGNATURE; // "MZ"
DOSheader.e_lfanew = sizeof(DOSheader);
int base = 0x10000000;
int codePage = pageAlign(sizeof(DOSheader) + (AMD64 ? sizeof(COFFheader64) : sizeof(COFFheader32)));
int exportsPage = codePage + pageAlign(codeSize);
int exportsSize = (int)(sizeof(IMAGE_EXPORT_DIRECTORY) + functionList.size() * sizeof(void*) + (strlen(dllName) + 1));
int relocPage = exportsPage + pageAlign(exportsSize);
int constPage = relocPage + pageAlign(relocSize);
if(!AMD64)
{
memset(&COFFheader32, 0, sizeof(COFFheader32));
COFFheader32.Signature = IMAGE_NT_SIGNATURE; // "PE"
COFFheader32.FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
COFFheader32.FileHeader.NumberOfSections = 4;
COFFheader32.FileHeader.TimeDateStamp = timeDateStamp;
COFFheader32.FileHeader.PointerToSymbolTable = 0; // Deprecated COFF symbol table
COFFheader32.FileHeader.NumberOfSymbols = 0;
COFFheader32.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32);
COFFheader32.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE |
IMAGE_FILE_32BIT_MACHINE |
IMAGE_FILE_DLL;
COFFheader32.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
COFFheader32.OptionalHeader.MajorLinkerVersion = 8;
COFFheader32.OptionalHeader.MinorLinkerVersion = 0;
COFFheader32.OptionalHeader.SizeOfCode = fileAlign(codeSize);
COFFheader32.OptionalHeader.SizeOfInitializedData = fileAlign(exportsSize) + fileAlign(relocSize) + fileAlign(constSize);
COFFheader32.OptionalHeader.SizeOfUninitializedData = 0;
COFFheader32.OptionalHeader.AddressOfEntryPoint = 0;
COFFheader32.OptionalHeader.BaseOfCode = codePage;
COFFheader32.OptionalHeader.BaseOfData = exportsPage;
COFFheader32.OptionalHeader.ImageBase = base;
COFFheader32.OptionalHeader.SectionAlignment = 0x1000;
COFFheader32.OptionalHeader.FileAlignment = 0x200;
COFFheader32.OptionalHeader.MajorOperatingSystemVersion = 4;
COFFheader32.OptionalHeader.MinorOperatingSystemVersion = 0;
COFFheader32.OptionalHeader.MajorImageVersion = 0;
COFFheader32.OptionalHeader.MinorImageVersion = 0;
COFFheader32.OptionalHeader.MajorSubsystemVersion = 4;
COFFheader32.OptionalHeader.MinorSubsystemVersion = 0;
COFFheader32.OptionalHeader.Win32VersionValue = 0;
COFFheader32.OptionalHeader.SizeOfImage = constPage + pageAlign(constSize);
COFFheader32.OptionalHeader.SizeOfHeaders = fileAlign(sizeof(DOSheader) + sizeof(COFFheader32));
COFFheader32.OptionalHeader.CheckSum = 0;
COFFheader32.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
COFFheader32.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NO_SEH |
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | // Base address randomization
IMAGE_DLLCHARACTERISTICS_NX_COMPAT; // Data Execution Prevention compatible
COFFheader32.OptionalHeader.SizeOfStackReserve = 1024 * 1024;
COFFheader32.OptionalHeader.SizeOfStackCommit = 4 * 1024;
COFFheader32.OptionalHeader.SizeOfHeapReserve = 1024 * 1024;
COFFheader32.OptionalHeader.SizeOfHeapCommit = 4 * 1024;
COFFheader32.OptionalHeader.LoaderFlags = 0;
COFFheader32.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = exportsPage;
COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = exportsSize;
COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = relocPage;
COFFheader32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = relocSize;
}
else
{
memset(&COFFheader64, 0, sizeof(COFFheader64));
COFFheader64.Signature = IMAGE_NT_SIGNATURE; // "PE"
COFFheader64.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64;
COFFheader64.FileHeader.NumberOfSections = 4;
COFFheader64.FileHeader.TimeDateStamp = timeDateStamp;
COFFheader64.FileHeader.PointerToSymbolTable = 0; // Deprecated COFF symbol table
COFFheader64.FileHeader.NumberOfSymbols = 0;
COFFheader64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64);
COFFheader64.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE |
IMAGE_FILE_LARGE_ADDRESS_AWARE |
IMAGE_FILE_DLL;
COFFheader64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
COFFheader64.OptionalHeader.MajorLinkerVersion = 8;
COFFheader64.OptionalHeader.MinorLinkerVersion = 0;
COFFheader64.OptionalHeader.SizeOfCode = fileAlign(codeSize);
COFFheader64.OptionalHeader.SizeOfInitializedData = fileAlign(exportsSize) + fileAlign(relocSize) + fileAlign(constSize);
COFFheader64.OptionalHeader.SizeOfUninitializedData = 0;
COFFheader64.OptionalHeader.AddressOfEntryPoint = 0;
COFFheader64.OptionalHeader.BaseOfCode = codePage;
COFFheader64.OptionalHeader.ImageBase = base;
COFFheader64.OptionalHeader.SectionAlignment = 0x1000;
COFFheader64.OptionalHeader.FileAlignment = 0x200;
COFFheader64.OptionalHeader.MajorOperatingSystemVersion = 4;
COFFheader64.OptionalHeader.MinorOperatingSystemVersion = 0;
COFFheader64.OptionalHeader.MajorImageVersion = 0;
COFFheader64.OptionalHeader.MinorImageVersion = 0;
COFFheader64.OptionalHeader.MajorSubsystemVersion = 4;
COFFheader64.OptionalHeader.MinorSubsystemVersion = 0;
COFFheader64.OptionalHeader.Win32VersionValue = 0;
COFFheader64.OptionalHeader.SizeOfImage = constPage + pageAlign(constSize);
COFFheader64.OptionalHeader.SizeOfHeaders = fileAlign(sizeof(DOSheader) + sizeof(COFFheader64));
COFFheader64.OptionalHeader.CheckSum = 0;
COFFheader64.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
COFFheader64.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NO_SEH |
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | // Base address randomization
IMAGE_DLLCHARACTERISTICS_NX_COMPAT; // Data Execution Prevention compatible
COFFheader64.OptionalHeader.SizeOfStackReserve = 1024 * 1024;
COFFheader64.OptionalHeader.SizeOfStackCommit = 4 * 1024;
COFFheader64.OptionalHeader.SizeOfHeapReserve = 1024 * 1024;
COFFheader64.OptionalHeader.SizeOfHeapCommit = 4 * 1024;
COFFheader64.OptionalHeader.LoaderFlags = 0;
COFFheader64.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = exportsPage;
COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = exportsSize;
COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = relocPage;
COFFheader64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = relocSize;
}
memset(&textSection, 0, sizeof(textSection));
strcpy((char*)&textSection.Name, ".text");
textSection.Misc.VirtualSize = pageAlign(codeSize);
textSection.VirtualAddress = codePage;
textSection.SizeOfRawData = fileAlign(codeSize);
textSection.PointerToRawData = fileAlign(sizeof(DOSheader) + (AMD64 ? sizeof(COFFheader64) : sizeof(COFFheader32)));
textSection.PointerToRelocations = 0;
textSection.PointerToLinenumbers = 0;
textSection.NumberOfRelocations = 0;
textSection.NumberOfLinenumbers = 0;
textSection.Characteristics = IMAGE_SCN_CNT_CODE |
IMAGE_SCN_MEM_EXECUTE |
IMAGE_SCN_MEM_READ;
memset(&exportsSection, 0, sizeof(exportsSection));
strcpy((char*)&exportsSection.Name, ".edata");
exportsSection.Misc.VirtualSize = pageAlign(exportsSize);
exportsSection.VirtualAddress = exportsPage;
exportsSection.SizeOfRawData = fileAlign(exportsSize);
exportsSection.PointerToRawData = textSection.PointerToRawData + fileAlign(codeSize);
exportsSection.PointerToRelocations = 0;
exportsSection.PointerToLinenumbers = 0;
exportsSection.NumberOfRelocations = 0;
exportsSection.NumberOfLinenumbers = 0;
exportsSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_READ;
memset(&relocSection, 0, sizeof(relocSection));
strcpy((char*)&relocSection.Name, ".reloc");
relocSection.Misc.VirtualSize = pageAlign(relocSize);
relocSection.VirtualAddress = relocPage;
relocSection.SizeOfRawData = fileAlign(relocSize);
relocSection.PointerToRawData = exportsSection.PointerToRawData + fileAlign(exportsSize);
relocSection.PointerToRelocations = 0;
relocSection.PointerToLinenumbers = 0;
relocSection.NumberOfRelocations = 0;
relocSection.NumberOfLinenumbers = 0;
relocSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_DISCARDABLE |
IMAGE_SCN_MEM_READ;
memset(&constSection, 0, sizeof(constSection));
strcpy((char*)&constSection.Name, ".rdata");
constSection.Misc.VirtualSize = pageAlign(constSize);
constSection.VirtualAddress = constPage;
constSection.SizeOfRawData = fileAlign(constSize);
constSection.PointerToRawData = relocSection.PointerToRawData + fileAlign(relocSize);
constSection.PointerToRelocations = 0;
constSection.PointerToLinenumbers = 0;
constSection.NumberOfRelocations = 0;
constSection.NumberOfLinenumbers = 0;
constSection.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_READ;
memset(&exportDirectory, 0, sizeof(exportDirectory));
exportDirectory.Characteristics = 0;
exportDirectory.TimeDateStamp = timeDateStamp;
exportDirectory.MajorVersion = 0;
exportDirectory.MinorVersion = 0;
exportDirectory.Name = (unsigned long)(exportsPage + sizeof(IMAGE_EXPORT_DIRECTORY) + functionList.size() * sizeof(void*));
exportDirectory.Base = 1;
exportDirectory.NumberOfFunctions = (unsigned long)functionList.size();
exportDirectory.NumberOfNames = 0;
exportDirectory.AddressOfFunctions = exportsPage + sizeof(IMAGE_EXPORT_DIRECTORY);
exportDirectory.AddressOfNames = 0;
exportDirectory.AddressOfNameOrdinals = 0;
FILE *file = fopen(dllName, "wb");
if(file)
{
fwrite(&DOSheader, 1, sizeof(DOSheader), file);
if(AMD64)
{
fwrite(&COFFheader64, 1, sizeof(COFFheader64), file);
}
else
{
fwrite(&COFFheader32, 1, sizeof(COFFheader32), file);
}
fwrite(&textSection, 1, sizeof(textSection), file);
fwrite(&exportsSection, 1, sizeof(textSection), file);
fwrite(&relocSection, 1, sizeof(relocSection), file);
fwrite(&constSection, 1, sizeof(constSection), file);
for(FunctionList::iterator i = functionList.begin(); i != functionList.end(); i++)
{
const void *function = i->first;
unsigned int location = i->second->location;
const std::vector<Relocation> &functionRelocations = globalRelocations[function];
for(unsigned int j = 0; j < functionRelocations.size(); j++)
{
unsigned int *address = (unsigned int*)((unsigned char*)i->second->buffer + functionRelocations[j].offset);
if(functionRelocations[j].ripRelative)
{
*address = base + codePage + location + (*address - (unsigned int)(size_t)function);
}
else
{
*address = base + constPage + (*address - (unsigned int)(size_t)constants);
}
}
fseek(file, textSection.PointerToRawData + location, SEEK_SET);
fwrite(i->second->buffer, 1, i->second->size, file);
}
fseek(file, exportsSection.PointerToRawData, SEEK_SET);
fwrite(&exportDirectory, 1, sizeof(exportDirectory), file);
for(unsigned int i = 0; i < functionOrder.size(); i++)
{
const void *buffer = functionOrder[i];
Function *function = functionList[buffer];
unsigned int functionAddress = codePage + function->location;
unsigned int functionEntry = functionAddress + (int)((size_t)function->entry - (size_t)buffer);
fwrite(&functionEntry, 1, sizeof(functionEntry), file);
}
fwrite(dllName, 1, strlen(dllName) + 1, file);
fseek(file, relocSection.PointerToRawData, SEEK_SET);
for(PageRelocations::iterator i = pageRelocations.begin(); i != pageRelocations.end(); i++)
{
IMAGE_BASE_RELOCATION relocationBlock;
relocationBlock.VirtualAddress = codePage + i->first * 0x1000;
relocationBlock.SizeOfBlock = (unsigned long)(sizeof(IMAGE_BASE_RELOCATION) + i->second.size() * sizeof(unsigned short));
fwrite(&relocationBlock, 1, sizeof(IMAGE_BASE_RELOCATION), file);
if(i->second.size() > 0)
{
fwrite(&i->second[0], 1, i->second.size() * sizeof(unsigned short), file);
}
}
fseek(file, constSection.PointerToRawData, SEEK_SET);
fwrite(constants, 1, constSize, file);
char *padding = new char[fileAlign(constSize) - constSize];
fwrite(padding, 1, fileAlign(constSize) - constSize, file);
delete[] padding;
fclose(file);
}
}
}
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_DLL_hpp
#define sw_DLL_hpp
#include <windows.h>
#include <vector>
#include <map>
namespace sw
{
class DLL
{
public:
DLL(const char *name, const void *constants = 0, int constSize = 0);
~DLL();
void addFunction(const void *function, const void *entry, int size);
void addRelocation(const void *function, const void *address, bool ripRelative);
void emit();
private:
int pageAlign(int address) // Align to 4 kB virtual page size
{
return (address + 0xFFF) & -0x1000;
}
int fileAlign(int address) // Align to 512 byte file sections
{
return (address + 0x1FF) & -0x200;
}
char *dllName;
IMAGE_DOS_HEADER DOSheader;
IMAGE_NT_HEADERS32 COFFheader32;
IMAGE_NT_HEADERS64 COFFheader64;
IMAGE_SECTION_HEADER textSection;
IMAGE_SECTION_HEADER exportsSection;
IMAGE_SECTION_HEADER relocSection;
IMAGE_SECTION_HEADER constSection;
IMAGE_EXPORT_DIRECTORY exportDirectory;
struct Function
{
Function() {};
Function(unsigned int location, const void *function, const void *entry, int size) : location(location), entry(entry), size(size)
{
buffer = new unsigned char[size];
memcpy(buffer, function, size);
}
~Function()
{
delete[] buffer;
}
void *buffer;
unsigned int location;
const void *entry;
int size;
};
std::vector<const void*> functionOrder;
typedef std::map<const void*, Function*> FunctionList;
FunctionList functionList;
int codeSize;
const void *constants;
int constSize;
struct Relocation
{
Relocation(unsigned int offset, bool ripRelative) : offset(offset), ripRelative(ripRelative)
{
}
unsigned int offset;
bool ripRelative;
};
typedef std::map<const void*, std::vector<Relocation> > GlobalRelocations;
GlobalRelocations globalRelocations;
typedef std::map<unsigned int, std::vector<unsigned short> > PageRelocations;
PageRelocations pageRelocations;
};
}
#endif // sw_DLL_hpp
...@@ -266,13 +266,11 @@ ...@@ -266,13 +266,11 @@
</ProjectReference> </ProjectReference>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="DLL.cpp" />
<ClCompile Include="Nucleus.cpp" /> <ClCompile Include="Nucleus.cpp" />
<ClCompile Include="Routine.cpp" /> <ClCompile Include="Routine.cpp" />
<ClCompile Include="RoutineManager.cpp" /> <ClCompile Include="RoutineManager.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="DLL.hpp" />
<ClInclude Include="Nucleus.hpp" /> <ClInclude Include="Nucleus.hpp" />
<ClInclude Include="Reactor.hpp" /> <ClInclude Include="Reactor.hpp" />
<ClInclude Include="Routine.hpp" /> <ClInclude Include="Routine.hpp" />
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="DLL.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Nucleus.cpp"> <ClCompile Include="Nucleus.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
...@@ -29,9 +26,6 @@ ...@@ -29,9 +26,6 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="DLL.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Nucleus.hpp"> <ClInclude Include="Nucleus.hpp">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
......
...@@ -34,141 +34,15 @@ namespace sw ...@@ -34,141 +34,15 @@ namespace sw
HMODULE precacheDLL; HMODULE precacheDLL;
#endif #endif
}; };
}
#if defined(_WIN32)
#include "Shader/Constants.hpp"
#include "Reactor/DLL.hpp"
#endif
namespace sw
{
template<class State> template<class State>
RoutineCache<State>::RoutineCache(int n, const char *precache) : LRUCache<State, Routine>(n), precache(precache) RoutineCache<State>::RoutineCache(int n, const char *precache) : LRUCache<State, Routine>(n), precache(precache)
{ {
#if defined(_WIN32)
precacheDLL = 0;
if(precache)
{
char dllName[1024]; sprintf(dllName, "%s.dll", precache);
char dirName[1024]; sprintf(dirName, "%s.dir", precache);
precacheDLL = LoadLibrary(dllName);
FILE *dir = fopen(dirName, "rb");
uintptr_t ordinal = 1;
while(precacheDLL && dir)
{
State state;
int offset;
int size;
size_t bytes = fread(&state, 1, sizeof(State), dir);
bytes += fread(&offset, 1, sizeof(offset), dir);
bytes += fread(&size, 1, sizeof(size), dir);
if(bytes != sizeof(State) + sizeof(offset) + sizeof(size))
{
break;
}
void (*routine)(void) = (void(*)(void))GetProcAddress(precacheDLL, (char*)ordinal);
ordinal++;
if(routine)
{
add(state, new Routine(routine, size, offset));
}
}
if(dir)
{
fclose(dir);
}
}
#endif
} }
template<class State> template<class State>
RoutineCache<State>::~RoutineCache() RoutineCache<State>::~RoutineCache()
{ {
#if defined(_WIN32)
char dllName[1024]; sprintf(dllName, "%s.dll", precache);
char dirName[1024]; sprintf(dirName, "%s.dir", precache);
if(precache)
{
DLL dll(dllName, &constants, sizeof(Constants));
FILE *dir = fopen(dirName, "wb");
for(int i = 0; i < getSize(); i++)
{
State &state = getKey(i);
Routine *routine = query(state);
if(routine)
{
unsigned char *buffer = (unsigned char*)routine->getBuffer();
unsigned char *entry = (unsigned char*)routine->getEntry();
int size = routine->getBufferSize();
int codeSize = routine->getCodeSize();
#ifndef _M_AMD64
for(int j = 1; j < codeSize - 4; j++)
{
unsigned char modRM_SIB = entry[j - 1];
unsigned int address = *(unsigned int*)&entry[j];
if((modRM_SIB & 0x05) == 0x05 && (address % 4) == 0)
{
if(address >= (unsigned int)buffer && address < (unsigned int)entry) // Constant stored above the function entry
{
dll.addRelocation(buffer, &entry[j], true);
j += 4;
}
}
}
#else
for(int j = 1; j < codeSize - 4; j++)
{
// unsigned char modRM_SIB = entry[j - 1];
uint64_t address = *(uint64_t*)&entry[j];
// if((modRM_SIB & 0x05) == 0x05 && (address % 4) == 0)
{
if(address >= (uint64_t)buffer && address < (uint64_t)entry) // Constant stored above the function entry
{
dll.addRelocation(buffer, &entry[j], true);
j += 4;
}
}
}
#endif
dll.addFunction(buffer, entry, size);
fwrite(&state, 1, sizeof(State), dir);
int offset = (int)(entry - buffer);
fwrite(&offset, 1, sizeof(offset), dir);
fwrite(&size, 1, sizeof(size), dir);
}
}
FreeLibrary(precacheDLL);
dll.emit();
fclose(dir);
}
else
{
FreeLibrary(precacheDLL);
remove(dllName);
remove(dirName);
}
#endif
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment