Skip to content

Commit aaffaa4

Browse files
committed
Use UnDecorateSymbolName for symbol demangling on windows
1 parent 299fbd0 commit aaffaa4

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

library/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ elseif(UNIX)
330330
set(PROJECT_LIBS rt dl dfhack-md5 ${DFHACK_TINYXML})
331331
else(WIN32)
332332
# FIXME: do we really need psapi?
333-
set(PROJECT_LIBS psapi dfhack-md5 ${DFHACK_TINYXML})
333+
set(PROJECT_LIBS psapi dbghelp dfhack-md5 ${DFHACK_TINYXML})
334334
endif()
335335

336336
set(VERSION_SRCS DFHackVersion.cpp)

library/Process-windows.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ distribution.
2929

3030
#define WIN32_LEAN_AND_MEAN
3131
#include <windows.h>
32+
#include <DbgHelp.h>
3233
#include <psapi.h>
3334

3435
#include <cstring>
@@ -343,21 +344,32 @@ int Process::adjustOffset(int offset, bool to_file)
343344

344345
string Process::doReadClassName (void * vptr)
345346
{
346-
char * rtti = readPtr((char *)vptr - sizeof(void*));
347+
char* rtti = readPtr((char *)vptr - sizeof(void*));
347348
#ifdef DFHACK64
348-
void *base;
349+
void* base;
349350
if (!RtlPcToFileHeader(rtti, &base))
350351
return "dummy";
351-
char * typeinfo = (char *)base + readDWord(rtti + 0xC);
352-
string raw = readCString(typeinfo + 0x10+4); // skips the .?AV
352+
char* typeinfo = (char *)base + readDWord(rtti + 0xC);
353+
char* raw = (char*)typeinfo + 0x10;
353354
#else
354-
char * typeinfo = readPtr(rtti + 0xC);
355-
string raw = readCString(typeinfo + 0xC); // skips the .?AV
355+
char* typeinfo = readPtr(rtti + 0xC);
356+
char* raw = (char*)typeinfo + 0x8
356357
#endif
357-
if (!raw.length())
358+
if (*raw == 0)
358359
return "dummy";
359-
raw.resize(raw.length() - 2);// trim @@ from end
360-
return raw;
360+
361+
char demangledBuf[MAX_SYM_NAME];
362+
// UNDNAME_NO_ARGUMENTS is essentially "UNDNAME_TYPE_ONLY", why Microsoft?
363+
DWORD flags = UNDNAME_NAME_ONLY | UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE;
364+
365+
// The first character ('.') is skipped as it simply denotes a class or struct
366+
DWORD res = UnDecorateSymbolName(raw + 1, (char*)&demangledBuf, MAX_SYM_NAME, flags);
367+
if (res == 0) {
368+
return "dummy";
369+
}
370+
std::string demangled((char*)&demangledBuf);
371+
372+
return demangled;
361373
}
362374

363375
uint32_t Process::getTickCount()

0 commit comments

Comments
 (0)