Skip to content

Commit 08b6d7f

Browse files
authored
Merge pull request #2 from Masterkatze/update
Add class variable support, fix some issues
2 parents 5c38c2d + 9ac922c commit 08b6d7f

7 files changed

Lines changed: 149 additions & 49 deletions

File tree

src/formatter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ std::vector<Out2> formatVTable(const ClassInfo &classInfo)
6363

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

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

8282
while ((linuxIndex + 1 + remainingOverloads) < static_cast<int>(vtableInfo.functions.size()))
8383
{
84-
auto nextFunctionIndex = linuxIndex + 1 + remainingOverloads;
85-
auto nextFunctionInfo = vtableInfo.functions.at(nextFunctionIndex);
84+
const auto nextFunctionIndex = linuxIndex + 1 + remainingOverloads;
85+
const auto nextFunctionInfo = vtableInfo.functions.at(nextFunctionIndex);
8686

8787
if (functionInfo->symbol.name.empty() || shouldSkipWindowsFunction(classInfo, vtableIndex, nextFunctionIndex, *nextFunctionInfo))
8888
{

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,5 +246,5 @@ int main(int argc, char *argv[])
246246
}
247247
}
248248

249-
return writeGamedataFile(out.classes, inputFilePaths, outputDirectoryPaths);
249+
return writeGamedataFile(out.classes, programInfo.vtableFieldDataEntries, inputFilePaths, outputDirectoryPaths);
250250
}

src/parser.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

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

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

3939
if (symbol.section == 0)
4040
{
@@ -149,12 +149,12 @@ Out parse(ProgramInfo &programInfo)
149149
functionAddress.low = symbolDataView[functionIndex];
150150
functionAddress.isUnsigned = true;
151151

152+
// Note: Relocations not supported for 64-bit bins
152153
if (programInfo.addressSize > BYTES_PER_ELEMENT)
153154
{
154155
functionAddress.high = symbolDataView[++functionIndex];
155156
}
156-
157-
if (programInfo.addressSize == BYTES_PER_ELEMENT)
157+
else if (programInfo.addressSize == BYTES_PER_ELEMENT)
158158
{
159159
LargeNumber localAddress;
160160
localAddress.high = 0;
@@ -167,10 +167,6 @@ Out parse(ProgramInfo &programInfo)
167167
functionAddress = targetAddress;
168168
}
169169
}
170-
else
171-
{
172-
std::cout << "Relocations not supported for 64-bit bins" << std::endl;
173-
}
174170

175171
auto functionSymbolsIterator = addressToSymbolMap.find(functionAddress);
176172

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

208204
auto functionSymbols = functionSymbolsIterator->second;
209-
auto functionSymbol = functionSymbols.back();
205+
const auto& functionSymbol = functionSymbols.back();
210206

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

218-
FunctionInfo *functionInfoPtr;
214+
FunctionInfo *functionInfoPtr = nullptr;
219215

220216
auto functionInfoIterator = addressToFunctionMap.find(functionAddress);
221217
if (functionInfoIterator != addressToFunctionMap.end())
@@ -235,6 +231,7 @@ Out parse(ProgramInfo &programInfo)
235231
if (startOfName != std::string::npos)
236232
{
237233
name = name.substr(startOfName + 2);
234+
nameSpace.resize(startOfName);
238235
}
239236

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

246-
247-
nameSpace = nameSpace.substr(0, startOfName);
248-
249243
FunctionInfo functionInfo;
250244

251245
functionInfo.id = functionAddress;

src/reader.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
#include <unistd.h>
2020
#include <fcntl.h>
2121

22+
struct VTableFieldOffsetDataRaw
23+
{
24+
uint64_t class_name_ptr;
25+
uint64_t member_name_ptr;
26+
uint64_t offset;
27+
};
28+
2229
LargeNumber::LargeNumber() : high{}, low{}, isUnsigned{}
2330
{
2431

@@ -92,14 +99,14 @@ ProgramInfo process(char *image, std::size_t size)
9299
return programInfo;
93100
}
94101

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

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

115122
size_t stringTableIndex = SHN_UNDEF;
116-
Elf_Scn *stringTableScn = nullptr;
123+
const Elf_Scn *stringTableScn = nullptr;
117124

118125
size_t rodataIndex = SHN_UNDEF;
119-
Elf64_Addr rodataOffset;
126+
Elf64_Addr rodataOffset = 0;
120127
Elf_Scn *rodataScn = nullptr;
121128

122129
size_t relRodataIndex = SHN_UNDEF;
123-
Elf64_Addr relRodataOffset;
130+
Elf64_Addr relRodataOffset = 0;
124131
Elf_Scn *relRodataScn = nullptr;
125132

126133
for (size_t elfSectionIndex = 0; elfSectionIndex < numberOfSections; ++elfSectionIndex)
@@ -175,6 +182,26 @@ ProgramInfo process(char *image, std::size_t size)
175182
relRodataOffset = elfSectionHeader.sh_addr;
176183
relRodataScn = elfScn;
177184
}
185+
else if(elfSectionHeader.sh_type == SHT_PROGBITS && strcmp(name, ".member_offsets") == 0)
186+
{
187+
Elf_Data* data = elf_getdata(elfScn, nullptr);
188+
if (data && data->d_size > 0)
189+
{
190+
size_t entry_count = data->d_size / sizeof(VTableFieldOffsetDataRaw);
191+
auto entries = static_cast<const VTableFieldOffsetDataRaw*>(data->d_buf);
192+
193+
for (size_t i = 0; i < entry_count; ++i)
194+
{
195+
#if 0
196+
std::cout << "VTableFieldOffsetData entry " << i << ":\n";
197+
std::cout << " Class name: " << &image[entries[i].class_name_ptr] << "\n";
198+
std::cout << " Member name: " << &image[entries[i].member_name_ptr] << "\n";
199+
std::cout << " Offset: " << entries[i].offset << " (0x" << std::hex << entries[i].offset << std::dec << ")\n";
200+
#endif
201+
programInfo.vtableFieldDataEntries.emplace_back(&image[entries[i].class_name_ptr], &image[entries[i].member_name_ptr], entries[i].offset);
202+
}
203+
}
204+
}
178205

179206
if (relocationTableScn && dynamicSymbolTableScn && symbolTableScn && stringTableScn && rodataScn && relRodataScn)
180207
{
@@ -196,7 +223,7 @@ ProgramInfo process(char *image, std::size_t size)
196223
Elf_Data *relocationData = nullptr;
197224
while ((relocationData = elf_getdata(relocationTableScn, relocationData)) != nullptr)
198225
{
199-
size_t relocationIndex = 0;
226+
int relocationIndex = 0;
200227
GElf_Rel relocation;
201228
while (gelf_getrel(relocationData, relocationIndex++, &relocation) == &relocation)
202229
{
@@ -210,7 +237,7 @@ ProgramInfo process(char *image, std::size_t size)
210237
while ((symbolData = elf_getdata(dynamicSymbolTableScn, symbolData)) != nullptr)
211238
{
212239
GElf_Sym symbol;
213-
size_t symbolIndex = GELF_R_SYM(relocation.r_info);
240+
int symbolIndex = GELF_R_SYM(relocation.r_info);
214241
if (gelf_getsym(symbolData, symbolIndex, &symbol) != &symbol)
215242
{
216243
continue;

src/reader.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ struct RelocationInfo
5050
LargeNumber target;
5151
};
5252

53+
struct MemberOffset
54+
{
55+
std::string className;
56+
std::string memberName;
57+
uint64_t offset;
58+
};
59+
5360
struct ProgramInfo
5461
{
5562
std::string error;
@@ -62,6 +69,7 @@ struct ProgramInfo
6269
std::vector<RodataChunk> relRodataChunks;
6370
std::vector<SymbolInfo> symbols;
6471
std::vector<RelocationInfo> relocations;
72+
std::vector<MemberOffset> vtableFieldDataEntries;
6573
};
6674

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

0 commit comments

Comments
 (0)