mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-19 17:29:06 +02:00
Demangle: handle CodeWarrior templates, function pointers and @-symbols
Checked against two PSP binaries that shipped with intact symbol tables,
which turned up several constructs the format's usual description doesn't
mention:
- Template arguments are written literally inside the length-prefixed name
("39CList<Q38hlScreen5Brwsr13CContentsUnit>"), not with a "__PT" prefix,
and they nest. Function templates put theirs in the base name instead,
followed by the return type.
- A family of "@"-decorated symbols for things with no C++ name: thunks
("@12@__dt__3SonFv"), string literals, function-local statics and their
guard variables. Plus __vt__/__RTTI__/__sinit_, printed in the same style
as the Itanium special names.
- Types are now built as a split declarator, so a pointer to a function
comes out as "int (*)(int)" rather than "int (int) *".
Also stop the lenient pass from turning plain C names with a "__" in them
into nonsense - "I3dClut__FlushCache" became "I3dClut(long, ...)". It now
requires a class qualifier, which costs nothing: over ~10000 symbols the
lenient pass rescued none and only produced those false positives.
Symbol map names go from 128 to 256 characters, since a demangled name
keeps its parameters and templates make short work of 128.
docs/CodeWarriorMangling.md describes the format, marking the parts that
are inferred from cfront rather than attested in a real binary.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SF5eS5QDNexLksRDeDZvwY
This commit is contained in:
1 parent
f89a2d4199
commit
dfc04f3578
5 files changed
+467
-28
No files matched your search
@@ -141,9 +141,9 @@ bool SymbolMap::LoadSymbolMap(const Path &filename) {
|
||||
int moduleIndex = 0;
|
||||
int typeInt = ST_NONE;
|
||||
SymbolType type;
|
||||
char name[128] = {0};
|
||||
char name[256] = {0};
|
||||
|
||||
if (sscanf(line, ".module %x %08x %08x %127c", (unsigned int *)&moduleIndex, &address, &size, name) >= 3) {
|
||||
if (sscanf(line, ".module %x %08x %08x %255c", (unsigned int *)&moduleIndex, &address, &size, name) >= 3) {
|
||||
// Found a module definition.
|
||||
ModuleEntry mod;
|
||||
mod.index = moduleIndex;
|
||||
@@ -155,7 +155,7 @@ bool SymbolMap::LoadSymbolMap(const Path &filename) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const int matched = sscanf(line, "%08x %08x %x %i %127c", &address, &size, &vaddress, &typeInt, name);
|
||||
const int matched = sscanf(line, "%08x %08x %x %i %255c", &address, &size, &vaddress, &typeInt, name);
|
||||
if (matched < 1)
|
||||
continue;
|
||||
type = (SymbolType) typeInt;
|
||||
@@ -316,8 +316,8 @@ bool SymbolMap::LoadNocashSym(const Path &filename) {
|
||||
return false;
|
||||
|
||||
while (!feof(f)) {
|
||||
char line[256], value[256] = {0};
|
||||
char *p = fgets(line, 256, f);
|
||||
char line[512], value[256] = {0};
|
||||
char *p = fgets(line, sizeof(line), f);
|
||||
if (p == NULL)
|
||||
break;
|
||||
|
||||
@@ -1262,7 +1262,7 @@ void SymbolMap::SetLabelName(const char* name, u32 address) {
|
||||
auto label = labels.find(symbolKey);
|
||||
if (label != labels.end()) {
|
||||
truncate_cpy(label->second.name, name);
|
||||
label->second.name[127] = 0;
|
||||
label->second.name[255] = 0;
|
||||
|
||||
// Refresh the active item if it exists.
|
||||
auto active = activeLabels.find(address);
|
||||
|
||||
Reference in new issue
Block a user