You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
* Added exclusions for exports in UbObjTool and added D3D12SDKVersion and friends to exclusion list * Fixed so UbaObjTool works for linux (or builds at least) * Added version to importexport files [CL 33840177 by henrik karlsson in ue5-main branch]
216 lines
5.1 KiB
C++
216 lines
5.1 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "UbaObjectFile.h"
|
|
#include "UbaBinaryReaderWriter.h"
|
|
#include "UbaFileAccessor.h"
|
|
#include "UbaObjectFileCoff.h"
|
|
#include "UbaObjectFileElf.h"
|
|
|
|
namespace uba
|
|
{
|
|
u8 SymbolFileVersion = 1;
|
|
|
|
ObjectFile* ObjectFile::OpenAndParse(Logger& logger, const tchar* filename)
|
|
{
|
|
auto file = new FileAccessor(logger, filename);
|
|
auto fileGuard = MakeGuard([&]() { delete file; });
|
|
|
|
if (!file->OpenMemoryRead())
|
|
return nullptr;
|
|
|
|
ObjectFile* objectFile = Parse(logger, file->GetData(), file->GetSize(), filename);
|
|
if (!objectFile)
|
|
return nullptr;
|
|
|
|
fileGuard.Cancel();
|
|
objectFile->m_file = file;
|
|
return objectFile;
|
|
}
|
|
|
|
ObjectFile* ObjectFile::Parse(Logger& logger, u8* data, u64 dataSize, const tchar* hint)
|
|
{
|
|
if (dataSize < 4)
|
|
return nullptr;
|
|
|
|
ObjectFile* objectFile = nullptr;
|
|
|
|
constexpr u8 elfMagic[] = { 0x7f, 'E', 'L', 'F' };
|
|
if (memcmp(data, elfMagic, sizeof(elfMagic)) == 0)
|
|
objectFile = new ObjectFileElf();
|
|
else
|
|
objectFile = new ObjectFileCoff();
|
|
|
|
objectFile->m_data = data;
|
|
objectFile->m_dataSize = dataSize;
|
|
|
|
if (objectFile->Parse(logger, hint))
|
|
return objectFile;
|
|
|
|
delete objectFile;
|
|
return nullptr;
|
|
}
|
|
|
|
bool ObjectFile::CopyMemoryAndClose()
|
|
{
|
|
u8* data = (u8*)malloc(m_dataSize);
|
|
memcpy(data, m_data, m_dataSize);
|
|
m_data = data;
|
|
m_ownsData = true;
|
|
delete m_file;
|
|
m_file = nullptr;
|
|
return true;
|
|
}
|
|
|
|
bool ObjectFile::StripExports(Logger& logger)
|
|
{
|
|
u32 keptExportCount = 0;
|
|
return StripExports(logger, m_data, {}, keptExportCount);
|
|
return true;
|
|
}
|
|
|
|
bool ObjectFile::WriteImportsAndExports(Logger& logger, MemoryBlock& memoryBlock)
|
|
{
|
|
auto write = [&](const void* data, u64 dataSize) { memcpy(memoryBlock.Allocate(dataSize, 1, TC("")), data, dataSize); };
|
|
|
|
write(&SymbolFileVersion, 1);
|
|
write(&m_type, 1);
|
|
|
|
// Write all imports
|
|
for (auto& symbol : m_imports)
|
|
{
|
|
write(symbol.c_str(), symbol.size());
|
|
write("", 1);
|
|
}
|
|
write("", 1);
|
|
|
|
// Write all exports
|
|
for (auto& kv : m_exports)
|
|
{
|
|
write(kv.first.c_str(), kv.first.size());
|
|
write(kv.second.c_str(), kv.second.size());
|
|
write("", 1);
|
|
}
|
|
write("", 1);
|
|
return true;
|
|
}
|
|
|
|
bool ObjectFile::WriteImportsAndExports(Logger& logger, const tchar* exportsFilename)
|
|
{
|
|
FileAccessor exportsFile(logger, exportsFilename);
|
|
if (!exportsFile.CreateWrite())
|
|
return false;
|
|
|
|
char buffer[256*1024];
|
|
u64 bufferPos = 0;
|
|
auto flush = [&]() { exportsFile.Write(buffer, bufferPos); bufferPos = 0; };
|
|
auto write = [&](const void* data, u64 dataSize) { if (bufferPos + dataSize > sizeof(buffer)) flush(); memcpy(buffer + bufferPos, data, dataSize); bufferPos += dataSize; };
|
|
|
|
// Write all imports
|
|
for (auto& symbol : m_imports)
|
|
{
|
|
write(symbol.c_str(), symbol.size());
|
|
write("", 1);
|
|
}
|
|
write("", 1);
|
|
|
|
// Write all exports
|
|
for (auto& kv : m_exports)
|
|
{
|
|
write(kv.first.c_str(), kv.first.size());
|
|
write(kv.second.c_str(), kv.second.size());
|
|
write("", 1);
|
|
}
|
|
write("", 1);
|
|
|
|
flush();
|
|
|
|
return exportsFile.Close();
|
|
}
|
|
|
|
ObjectFile::~ObjectFile()
|
|
{
|
|
if (m_ownsData)
|
|
free(m_data);
|
|
delete m_file;
|
|
}
|
|
|
|
const tchar* ObjectFile::GetFileName() const
|
|
{
|
|
return m_file->GetFileName();
|
|
}
|
|
|
|
const UnorderedSymbols& ObjectFile::GetImports() const
|
|
{
|
|
return m_imports;
|
|
}
|
|
|
|
const UnorderedExports& ObjectFile::GetExports() const
|
|
{
|
|
return m_exports;
|
|
}
|
|
|
|
const UnorderedSymbols& ObjectFile::GetPotentialDuplicates() const
|
|
{
|
|
return m_potentialDuplicates;
|
|
}
|
|
|
|
bool ObjectFile::CreateExtraFile(Logger& logger, const tchar* extraObjFilename, ObjectFileType type, const UnorderedSymbols& allNeededImports, const UnorderedSymbols& allSharedImports, const UnorderedExports& allSharedExports, bool includeExportsInFile)
|
|
{
|
|
ObjectFileCoff objectFileCoff;
|
|
ObjectFileElf objectFileElf;
|
|
|
|
ObjectFile& objectFile = type == ObjectFileType_Coff ? (ObjectFile&)objectFileCoff : (ObjectFile&)objectFileElf;
|
|
|
|
|
|
MemoryBlock memoryBlock(16*1024*1024);
|
|
|
|
if (!objectFile.CreateExtraFile(logger, memoryBlock, allNeededImports, allSharedImports, allSharedExports, includeExportsInFile))
|
|
return false;
|
|
|
|
FileAccessor extraFile(logger, extraObjFilename);
|
|
if (!extraFile.CreateWrite())
|
|
return false;
|
|
|
|
if (!extraFile.Write(memoryBlock.memory, memoryBlock.writtenSize))
|
|
return false;
|
|
|
|
return extraFile.Close();
|
|
}
|
|
|
|
bool SymbolFile::ParseFile(Logger& logger, const tchar* filename)
|
|
{
|
|
FileAccessor symFile(logger, filename);
|
|
if (!symFile.OpenMemoryRead())
|
|
return false;
|
|
auto readPos = (const char*)symFile.GetData();
|
|
|
|
u8 version = *(u8*)readPos++;
|
|
if (SymbolFileVersion != version)
|
|
return logger.Error(TC("%s - Import/export file version mismatch"), filename);
|
|
|
|
type = *(const ObjectFileType*)readPos++;
|
|
|
|
while (*readPos)
|
|
{
|
|
auto strEnd = strlen(readPos);
|
|
imports.insert(std::string(readPos, readPos + strEnd));
|
|
readPos = readPos + strEnd + 1;
|
|
}
|
|
++readPos;
|
|
|
|
while (*readPos)
|
|
{
|
|
auto strEnd = strlen(readPos);
|
|
std::string extra;
|
|
if (const char* comma = strchr(readPos, ','))
|
|
{
|
|
strEnd = comma - readPos;
|
|
extra = comma;
|
|
}
|
|
exports.emplace(std::string(readPos, readPos + strEnd), extra);
|
|
readPos = readPos + strEnd + 1;
|
|
}
|
|
return true;
|
|
}
|
|
}
|