Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ std::vector<Out2> formatVTable(const ClassInfo &classInfo)

while ((linuxIndex - (1 + previousOverloads)) >= 0)
{
auto previousFunctionIndex = linuxIndex - (1 + previousOverloads);
auto previousFunctionInfo = vtableInfo.functions.at(previousFunctionIndex);
const auto previousFunctionIndex = linuxIndex - (1 + previousOverloads);
const auto previousFunctionInfo = vtableInfo.functions.at(previousFunctionIndex);

if (functionInfo->symbol.name.empty() || shouldSkipWindowsFunction(classInfo, vtableIndex, previousFunctionIndex, *previousFunctionInfo))
{
Expand All @@ -81,8 +81,8 @@ std::vector<Out2> formatVTable(const ClassInfo &classInfo)

while ((linuxIndex + 1 + remainingOverloads) < static_cast<int>(vtableInfo.functions.size()))
{
auto nextFunctionIndex = linuxIndex + 1 + remainingOverloads;
auto nextFunctionInfo = vtableInfo.functions.at(nextFunctionIndex);
const auto nextFunctionIndex = linuxIndex + 1 + remainingOverloads;
const auto nextFunctionInfo = vtableInfo.functions.at(nextFunctionIndex);

if (functionInfo->symbol.name.empty() || shouldSkipWindowsFunction(classInfo, vtableIndex, nextFunctionIndex, *nextFunctionInfo))
{
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,5 +246,5 @@ int main(int argc, char *argv[])
}
}

return writeGamedataFile(out.classes, inputFilePaths, outputDirectoryPaths);
return writeGamedataFile(out.classes, programInfo.vtableFieldDataEntries, inputFilePaths, outputDirectoryPaths);
}
22 changes: 8 additions & 14 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

std::unique_ptr<char, DemangledSymbolDeallocator> demangleSymbol(const char *abiName)
{
int status;
int status = -4;
char *ret = abi::__cxa_demangle(abiName, 0, 0, &status);

DemangledSymbolDeallocator deallocator = [](char *mem)
Expand All @@ -34,7 +34,7 @@ std::unique_ptr<char, DemangledSymbolDeallocator> demangleSymbol(const char *abi
std::span<const unsigned char> getDataForSymbol(const ProgramInfo &programInfo, const SymbolInfo &symbol)
{
LargeNumber dataStart;
const std::vector<RodataChunk> *dataChunks;
const std::vector<RodataChunk> *dataChunks = nullptr;

if (symbol.section == 0)
{
Expand Down Expand Up @@ -149,12 +149,12 @@ Out parse(ProgramInfo &programInfo)
functionAddress.low = symbolDataView[functionIndex];
functionAddress.isUnsigned = true;

// Note: Relocations not supported for 64-bit bins
if (programInfo.addressSize > BYTES_PER_ELEMENT)
{
functionAddress.high = symbolDataView[++functionIndex];
}

if (programInfo.addressSize == BYTES_PER_ELEMENT)
else if (programInfo.addressSize == BYTES_PER_ELEMENT)
{
LargeNumber localAddress;
localAddress.high = 0;
Expand All @@ -167,10 +167,6 @@ Out parse(ProgramInfo &programInfo)
functionAddress = targetAddress;
}
}
else
{
std::cout << "Relocations not supported for 64-bit bins" << std::endl;
}

auto functionSymbolsIterator = addressToSymbolMap.find(functionAddress);

Expand All @@ -186,7 +182,7 @@ Out parse(ProgramInfo &programInfo)
// This could be the end of the vtable, or it could just be a pure/deleted func.
if (functionSymbolsIterator == addressToSymbolMap.end())
{
if (classInfo.vtables.size() == 0 || static_cast<unsigned long long>(functionAddress) != 0)
if (classInfo.vtables.empty() || static_cast<unsigned long long>(functionAddress) != 0)
{
auto& newClassVTable = classInfo.vtables.emplace_back();
classVTable = &newClassVTable;
Expand All @@ -206,7 +202,7 @@ Out parse(ProgramInfo &programInfo)
}

auto functionSymbols = functionSymbolsIterator->second;
auto functionSymbol = functionSymbols.back();
const auto& functionSymbol = functionSymbols.back();

auto functionSymbolName = functionSymbol.name;
if (functionSymbolName == "__cxa_deleted_virtual" || functionSymbolName == "__cxa_pure_virtual")
Expand All @@ -215,7 +211,7 @@ Out parse(ProgramInfo &programInfo)
continue;
}

FunctionInfo *functionInfoPtr;
FunctionInfo *functionInfoPtr = nullptr;

auto functionInfoIterator = addressToFunctionMap.find(functionAddress);
if (functionInfoIterator != addressToFunctionMap.end())
Expand All @@ -235,6 +231,7 @@ Out parse(ProgramInfo &programInfo)
if (startOfName != std::string::npos)
{
name = name.substr(startOfName + 2);
nameSpace.resize(startOfName);
}

auto startOfArgs = demangledSymbol.rfind('(');
Expand All @@ -243,9 +240,6 @@ Out parse(ProgramInfo &programInfo)
shortName = shortName.substr(startOfName + 2, startOfArgs - startOfName - 2);
}


nameSpace = nameSpace.substr(0, startOfName);

FunctionInfo functionInfo;

functionInfo.id = functionAddress;
Expand Down
41 changes: 34 additions & 7 deletions src/reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
#include <unistd.h>
#include <fcntl.h>

struct VTableFieldOffsetDataRaw
{
uint64_t class_name_ptr;
uint64_t member_name_ptr;
uint64_t offset;
};

LargeNumber::LargeNumber() : high{}, low{}, isUnsigned{}
{

Expand Down Expand Up @@ -92,14 +99,14 @@ ProgramInfo process(char *image, std::size_t size)
return programInfo;
}

size_t numberOfSections;
size_t numberOfSections = 0;
if (elf_getshdrnum(elf, &numberOfSections) != 0)
{
programInfo.error = "Failed to get number of ELF sections. (" + std::string(elf_errmsg(-1)) + ")";
return programInfo;
}

size_t sectionNameStringTableIndex;
size_t sectionNameStringTableIndex = 0;
if (elf_getshdrstrndx(elf, &sectionNameStringTableIndex) != 0)
{
programInfo.error = "Failed to get ELF section names. (" + std::string(elf_errmsg(-1)) + ")";
Expand All @@ -113,14 +120,14 @@ ProgramInfo process(char *image, std::size_t size)
Elf_Scn *symbolTableScn = nullptr;

size_t stringTableIndex = SHN_UNDEF;
Elf_Scn *stringTableScn = nullptr;
const Elf_Scn *stringTableScn = nullptr;

size_t rodataIndex = SHN_UNDEF;
Elf64_Addr rodataOffset;
Elf64_Addr rodataOffset = 0;
Elf_Scn *rodataScn = nullptr;

size_t relRodataIndex = SHN_UNDEF;
Elf64_Addr relRodataOffset;
Elf64_Addr relRodataOffset = 0;
Elf_Scn *relRodataScn = nullptr;

for (size_t elfSectionIndex = 0; elfSectionIndex < numberOfSections; ++elfSectionIndex)
Expand Down Expand Up @@ -175,6 +182,26 @@ ProgramInfo process(char *image, std::size_t size)
relRodataOffset = elfSectionHeader.sh_addr;
relRodataScn = elfScn;
}
else if(elfSectionHeader.sh_type == SHT_PROGBITS && strcmp(name, ".member_offsets") == 0)
{
Elf_Data* data = elf_getdata(elfScn, nullptr);
if (data && data->d_size > 0)
{
size_t entry_count = data->d_size / sizeof(VTableFieldOffsetDataRaw);
auto entries = static_cast<const VTableFieldOffsetDataRaw*>(data->d_buf);

for (size_t i = 0; i < entry_count; ++i)
{
#if 0
std::cout << "VTableFieldOffsetData entry " << i << ":\n";
std::cout << " Class name: " << &image[entries[i].class_name_ptr] << "\n";
std::cout << " Member name: " << &image[entries[i].member_name_ptr] << "\n";
std::cout << " Offset: " << entries[i].offset << " (0x" << std::hex << entries[i].offset << std::dec << ")\n";
#endif
programInfo.vtableFieldDataEntries.emplace_back(&image[entries[i].class_name_ptr], &image[entries[i].member_name_ptr], entries[i].offset);
}
}
}

if (relocationTableScn && dynamicSymbolTableScn && symbolTableScn && stringTableScn && rodataScn && relRodataScn)
{
Expand All @@ -196,7 +223,7 @@ ProgramInfo process(char *image, std::size_t size)
Elf_Data *relocationData = nullptr;
while ((relocationData = elf_getdata(relocationTableScn, relocationData)) != nullptr)
{
size_t relocationIndex = 0;
int relocationIndex = 0;
GElf_Rel relocation;
while (gelf_getrel(relocationData, relocationIndex++, &relocation) == &relocation)
{
Expand All @@ -210,7 +237,7 @@ ProgramInfo process(char *image, std::size_t size)
while ((symbolData = elf_getdata(dynamicSymbolTableScn, symbolData)) != nullptr)
{
GElf_Sym symbol;
size_t symbolIndex = GELF_R_SYM(relocation.r_info);
int symbolIndex = GELF_R_SYM(relocation.r_info);
if (gelf_getsym(symbolData, symbolIndex, &symbol) != &symbol)
{
continue;
Expand Down
8 changes: 8 additions & 0 deletions src/reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ struct RelocationInfo
LargeNumber target;
};

struct MemberOffset
{
std::string className;
std::string memberName;
uint64_t offset;
};

struct ProgramInfo
{
std::string error;
Expand All @@ -62,6 +69,7 @@ struct ProgramInfo
std::vector<RodataChunk> relRodataChunks;
std::vector<SymbolInfo> symbols;
std::vector<RelocationInfo> relocations;
std::vector<MemberOffset> vtableFieldDataEntries;
};

ProgramInfo process(char *image, std::size_t size);
Loading