Update VDI format for Windows x64
Update VDI format to utilize 64-bit pointer types for stack tracing. Revise mapconv and CrashHandlerChild. Tested on both 32-bit and 64-bit builds to be working properly.
This commit is contained in:
+1
-2
@@ -224,8 +224,7 @@ inline bool MyLua_checkintboolean( lua_State *L, int iArg )
|
|||||||
int iType = lua_type( L, iArg );
|
int iType = lua_type( L, iArg );
|
||||||
if( iType == LUA_TNUMBER )
|
if( iType == LUA_TNUMBER )
|
||||||
{
|
{
|
||||||
int iValue = lua_tointeger( L, iArg );
|
return lua_tointeger(L, iArg) != 0;
|
||||||
return iValue != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MyLua_checkboolean( L, iArg );
|
return MyLua_checkboolean( L, iArg );
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void WriteToChild( HANDLE hPipe, const void *pData, size_t iSize )
|
|||||||
while( iSize )
|
while( iSize )
|
||||||
{
|
{
|
||||||
DWORD iActual;
|
DWORD iActual;
|
||||||
if( !WriteFile(hPipe, pData, iSize, &iActual, nullptr) )
|
if( !WriteFile(hPipe, pData, static_cast<DWORD>(iSize), &iActual, nullptr) )
|
||||||
return;
|
return;
|
||||||
iSize -= iActual;
|
iSize -= iActual;
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ bool StartChild( HANDLE &hProcess, HANDLE &hToStdin, HANDLE &hFromStdout )
|
|||||||
SetHandleInformation( hFromStdout, HANDLE_FLAG_INHERIT, 0 );
|
SetHandleInformation( hFromStdout, HANDLE_FLAG_INHERIT, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
char szBuf[256] = "";
|
char szBuf[MAX_PATH] = "";
|
||||||
GetModuleFileName( nullptr, szBuf, MAX_PATH );
|
GetModuleFileName( nullptr, szBuf, MAX_PATH );
|
||||||
strcat( szBuf, " " );
|
strcat( szBuf, " " );
|
||||||
strcat( szBuf, CHILD_MAGIC_PARAMETER );
|
strcat( szBuf, CHILD_MAGIC_PARAMETER );
|
||||||
@@ -144,6 +144,7 @@ bool StartChild( HANDLE &hProcess, HANDLE &hToStdin, HANDLE &hFromStdout )
|
|||||||
}
|
}
|
||||||
|
|
||||||
hProcess = pi.hProcess;
|
hProcess = pi.hProcess;
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -209,13 +210,13 @@ void RunChild()
|
|||||||
|
|
||||||
// 2. Write info.
|
// 2. Write info.
|
||||||
const TCHAR *p = RageLog::GetInfo();
|
const TCHAR *p = RageLog::GetInfo();
|
||||||
int iSize = strlen( p );
|
int iSize = static_cast<int>(strlen( p ));
|
||||||
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
||||||
WriteToChild( hToStdin, p, iSize );
|
WriteToChild( hToStdin, p, iSize );
|
||||||
|
|
||||||
// 3. Write AdditionalLog.
|
// 3. Write AdditionalLog.
|
||||||
p = RageLog::GetAdditionalLog();
|
p = RageLog::GetAdditionalLog();
|
||||||
iSize = strlen( p );
|
iSize = static_cast<int>(strlen( p ));
|
||||||
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
||||||
WriteToChild( hToStdin, p, iSize );
|
WriteToChild( hToStdin, p, iSize );
|
||||||
|
|
||||||
@@ -228,7 +229,7 @@ void RunChild()
|
|||||||
WriteToChild(hToStdin, &cnt, sizeof(cnt));
|
WriteToChild(hToStdin, &cnt, sizeof(cnt));
|
||||||
for( int i = 0; i < cnt; ++i )
|
for( int i = 0; i < cnt; ++i )
|
||||||
{
|
{
|
||||||
iSize = strlen(ps[i])+1;
|
iSize = static_cast<int>(strlen(ps[i])) + 1;
|
||||||
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
||||||
WriteToChild( hToStdin, ps[i], iSize );
|
WriteToChild( hToStdin, ps[i], iSize );
|
||||||
}
|
}
|
||||||
@@ -236,13 +237,13 @@ void RunChild()
|
|||||||
// 5. Write CHECKPOINTs.
|
// 5. Write CHECKPOINTs.
|
||||||
static TCHAR buf[1024*32];
|
static TCHAR buf[1024*32];
|
||||||
Checkpoints::GetLogs( buf, sizeof(buf), "$$" );
|
Checkpoints::GetLogs( buf, sizeof(buf), "$$" );
|
||||||
iSize = strlen( buf )+1;
|
iSize = static_cast<int>(strlen( buf )) + 1;
|
||||||
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
||||||
WriteToChild( hToStdin, buf, iSize );
|
WriteToChild( hToStdin, buf, iSize );
|
||||||
|
|
||||||
// 6. Write the crashed thread's name.
|
// 6. Write the crashed thread's name.
|
||||||
p = RageThread::GetCurrentThreadName();
|
p = RageThread::GetCurrentThreadName();
|
||||||
iSize = strlen( p )+1;
|
iSize = static_cast<int>(strlen( p )) + 1;
|
||||||
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
||||||
WriteToChild( hToStdin, p, iSize );
|
WriteToChild( hToStdin, p, iSize );
|
||||||
|
|
||||||
@@ -260,7 +261,7 @@ void RunChild()
|
|||||||
TCHAR szName[MAX_PATH];
|
TCHAR szName[MAX_PATH];
|
||||||
if( !CrashGetModuleBaseName(hMod, szName) )
|
if( !CrashGetModuleBaseName(hMod, szName) )
|
||||||
strcpy( szName, "???" );
|
strcpy( szName, "???" );
|
||||||
iSize = strlen( szName );
|
iSize = static_cast<int>(strlen( szName ));
|
||||||
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
WriteToChild( hToStdin, &iSize, sizeof(iSize) );
|
||||||
WriteToChild( hToStdin, szName, iSize );
|
WriteToChild( hToStdin, szName, iSize );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,12 @@
|
|||||||
// XXX: What happens when we *don't* have version info? Does that ever actually happen?
|
// XXX: What happens when we *don't* have version info? Does that ever actually happen?
|
||||||
#include "ver.h"
|
#include "ver.h"
|
||||||
|
|
||||||
|
#if _WIN64
|
||||||
|
#define ADDRESS_ZEROS "016"
|
||||||
|
#else
|
||||||
|
#define ADDRESS_ZEROS "08"
|
||||||
|
#endif
|
||||||
|
|
||||||
// VDI symbol lookup:
|
// VDI symbol lookup:
|
||||||
namespace VDDebugInfo
|
namespace VDDebugInfo
|
||||||
{
|
{
|
||||||
@@ -98,13 +104,18 @@ namespace VDDebugInfo
|
|||||||
// Extract fields
|
// Extract fields
|
||||||
|
|
||||||
src += 64;
|
src += 64;
|
||||||
|
const int* pVer = reinterpret_cast<const int*>(src);
|
||||||
|
const size_t* pRVASize = reinterpret_cast<const size_t*>(src + sizeof(int));
|
||||||
|
const size_t* pFNamSize = reinterpret_cast<const size_t*>(src + sizeof(int) + sizeof(size_t));
|
||||||
|
const int* pSegCnt = reinterpret_cast<const int*>(src + sizeof(int) + 2 * sizeof(size_t));
|
||||||
|
src += 2 * (sizeof(int) + sizeof(size_t));
|
||||||
|
|
||||||
pctx->nBuildNumber = *(int *)src;
|
pctx->nBuildNumber = *pVer;
|
||||||
pctx->pRVAHeap = (const unsigned char *)(src + 20);
|
pctx->pRVAHeap = reinterpret_cast<const unsigned char*>(src + sizeof(uintptr_t));
|
||||||
pctx->nFirstRVA = *(const long *)(src + 16);
|
pctx->nFirstRVA = *reinterpret_cast<const uintptr_t*>(src);
|
||||||
pctx->pFuncNameHeap = (const char *)pctx->pRVAHeap - 4 + *(const long *)(src + 4);
|
pctx->pFuncNameHeap = reinterpret_cast<const char*>(src + *pRVASize);
|
||||||
pctx->pSegments = (uintptr_t (*)[2])(pctx->pFuncNameHeap + *(const long *)(src + 8));
|
pctx->pSegments = reinterpret_cast<const uintptr_t(*)[2]>(src + *pRVASize + *pFNamSize);
|
||||||
pctx->nSegments = *(const long *)(src + 12);
|
pctx->nSegments = *pSegCnt;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -137,7 +148,7 @@ namespace VDDebugInfo
|
|||||||
if( dwFileSize == INVALID_FILE_SIZE )
|
if( dwFileSize == INVALID_FILE_SIZE )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
char *buffer = new char[dwFileSize + 1];
|
char *buffer = new char[static_cast<size_t>(dwFileSize) + 1];
|
||||||
std::fill(buffer, buffer + dwFileSize + 1, '\0' );
|
std::fill(buffer, buffer + dwFileSize + 1, '\0' );
|
||||||
|
|
||||||
DWORD dwActual;
|
DWORD dwActual;
|
||||||
@@ -168,7 +179,7 @@ namespace VDDebugInfo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *GetNameFromHeap(const char *heap, int idx)
|
static const char *GetNameFromHeap(const char *heap, size_t idx)
|
||||||
{
|
{
|
||||||
while(idx--)
|
while(idx--)
|
||||||
while(*heap++);
|
while(*heap++);
|
||||||
@@ -176,19 +187,19 @@ namespace VDDebugInfo
|
|||||||
return heap;
|
return heap;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t VDDebugInfoLookupRVA( const Context *pctx, uintptr_t rva, char *buf, int buflen )
|
intptr_t VDDebugInfoLookupRVA( const Context *pctx, uintptr_t rva, char *buf, int buflen )
|
||||||
{
|
{
|
||||||
if( !PointerIsInAnySegment(pctx, rva) )
|
if( !PointerIsInAnySegment(pctx, rva) )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
const unsigned char *pr = pctx->pRVAHeap;
|
const unsigned char *pr = pctx->pRVAHeap;
|
||||||
const unsigned char *pr_limit = (const unsigned char *)pctx->pFuncNameHeap;
|
const unsigned char *pr_limit = (const unsigned char *)pctx->pFuncNameHeap;
|
||||||
int idx = 0;
|
size_t idx = 0;
|
||||||
|
|
||||||
// Linearly unpack RVA deltas and find lower_bound
|
// Linearly unpack RVA deltas and find lower_bound
|
||||||
rva -= pctx->nFirstRVA;
|
rva -= pctx->nFirstRVA;
|
||||||
|
|
||||||
if( (signed)rva < 0 )
|
if( static_cast<intptr_t>(rva) < 0 )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
while( pr < pr_limit )
|
while( pr < pr_limit )
|
||||||
@@ -205,7 +216,7 @@ namespace VDDebugInfo
|
|||||||
|
|
||||||
rva -= diff;
|
rva -= diff;
|
||||||
|
|
||||||
if ((signed)rva < 0) {
|
if (static_cast<intptr_t>(rva) < 0) {
|
||||||
rva += diff;
|
rva += diff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -224,7 +235,7 @@ namespace VDDebugInfo
|
|||||||
strncpy( buf, fn_name, buflen );
|
strncpy( buf, fn_name, buflen );
|
||||||
buf[buflen-1] = 0;
|
buf[buflen-1] = 0;
|
||||||
|
|
||||||
return rva;
|
return static_cast<intptr_t>(rva);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +245,7 @@ bool ReadFromParent( int fd, void *p, int size )
|
|||||||
int got = 0;
|
int got = 0;
|
||||||
while( got < size )
|
while( got < size )
|
||||||
{
|
{
|
||||||
int ret = read( fd, buf+got, size-got );
|
int ret = _read( fd, buf+got, size-got );
|
||||||
if( ret == -1 )
|
if( ret == -1 )
|
||||||
{
|
{
|
||||||
if( errno == EINTR )
|
if( errno == EINTR )
|
||||||
@@ -322,16 +333,16 @@ namespace SymbolLookup
|
|||||||
|
|
||||||
RString CrashChildGetModuleBaseName( HMODULE hMod )
|
RString CrashChildGetModuleBaseName( HMODULE hMod )
|
||||||
{
|
{
|
||||||
write( _fileno(stdout), &hMod, sizeof(hMod) );
|
_write( _fileno(stdout), &hMod, sizeof(hMod) );
|
||||||
|
|
||||||
int iFD = fileno(stdin);
|
int iFD = _fileno(stdin);
|
||||||
int iSize;
|
int iSize;
|
||||||
if (!ReadFromParent(iFD, &iSize, sizeof(iSize)))
|
if (!ReadFromParent(iFD, &iSize, sizeof(iSize)))
|
||||||
{
|
{
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
RString sName;
|
RString sName;
|
||||||
char *buffer = new char[iSize + 1];
|
char *buffer = new char[static_cast<size_t>(iSize) + 1];
|
||||||
std::fill(buffer, buffer + iSize + 1, '\0');
|
std::fill(buffer, buffer + iSize + 1, '\0');
|
||||||
if (!ReadFromParent(iFD, buffer, iSize))
|
if (!ReadFromParent(iFD, buffer, iSize))
|
||||||
{
|
{
|
||||||
@@ -357,11 +368,11 @@ namespace SymbolLookup
|
|||||||
VirtualQueryEx( g_hParent, ptr, &meminfo, sizeof meminfo );
|
VirtualQueryEx( g_hParent, ptr, &meminfo, sizeof meminfo );
|
||||||
|
|
||||||
char tmp[512];
|
char tmp[512];
|
||||||
uintptr_t iAddress = VDDebugInfo::VDDebugInfoLookupRVA(pctx, reinterpret_cast<uintptr_t>(ptr), tmp, sizeof(tmp));
|
intptr_t iAddress = VDDebugInfo::VDDebugInfoLookupRVA(pctx, reinterpret_cast<uintptr_t>(ptr), tmp, sizeof(tmp));
|
||||||
if( iAddress >= 0 )
|
if( iAddress >= 0 )
|
||||||
{
|
{
|
||||||
wsprintf( buf, "%p: %s [%p+%Ix+%Ix]", ptr, Demangle(tmp),
|
wsprintf( buf, "%" ADDRESS_ZEROS "Ix: %s [%" ADDRESS_ZEROS "Ix+%Ix+%Ix]", reinterpret_cast<uintptr_t>(ptr), Demangle(tmp),
|
||||||
reinterpret_cast<void *>(pctx->nFirstRVA),
|
pctx->nFirstRVA,
|
||||||
reinterpret_cast<uintptr_t>(ptr) - pctx->nFirstRVA - iAddress,
|
reinterpret_cast<uintptr_t>(ptr) - pctx->nFirstRVA - iAddress,
|
||||||
iAddress );
|
iAddress );
|
||||||
return;
|
return;
|
||||||
@@ -374,17 +385,17 @@ namespace SymbolLookup
|
|||||||
|
|
||||||
if( pSymbol )
|
if( pSymbol )
|
||||||
{
|
{
|
||||||
wsprintf( buf, "%p: %s!%s [%p+%Ix+%Ix]",
|
wsprintf( buf, "%" ADDRESS_ZEROS "Ix: %s!%s [%" ADDRESS_ZEROS "Ix+%Ix+%Ix]",
|
||||||
ptr, sName.c_str(), pSymbol->Name,
|
reinterpret_cast<uintptr_t>(ptr), sName.c_str(), pSymbol->Name,
|
||||||
meminfo.AllocationBase,
|
reinterpret_cast<uintptr_t>(meminfo.AllocationBase),
|
||||||
static_cast<uintptr_t>(pSymbol->Address) - reinterpret_cast<uintptr_t>(meminfo.AllocationBase),
|
static_cast<uintptr_t>(pSymbol->Address) - reinterpret_cast<uintptr_t>(meminfo.AllocationBase),
|
||||||
static_cast<ULONG_PTR>(disp));
|
static_cast<ULONG_PTR>(disp));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wsprintf( buf, "%p: %s!%p",
|
wsprintf( buf, "%" ADDRESS_ZEROS "Ix: %s!%" ADDRESS_ZEROS "Ix",
|
||||||
ptr, sName.c_str(),
|
reinterpret_cast<uintptr_t>(ptr), sName.c_str(),
|
||||||
meminfo.AllocationBase );
|
reinterpret_cast<uintptr_t>(meminfo.AllocationBase) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +529,7 @@ bool ReadCrashDataFromParent( int iFD, CompleteCrashData &Data )
|
|||||||
if( !ReadFromParent(iFD, &iSize, sizeof(iSize)) )
|
if( !ReadFromParent(iFD, &iSize, sizeof(iSize)) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char *buffer = new char[iSize + 1];
|
char *buffer = new char[static_cast<size_t>(iSize) + 1];
|
||||||
std::fill(buffer, buffer + iSize + 1, '\0');
|
std::fill(buffer, buffer + iSize + 1, '\0');
|
||||||
bool wasReadSuccessful = ReadFromParent(iFD, buffer, iSize);
|
bool wasReadSuccessful = ReadFromParent(iFD, buffer, iSize);
|
||||||
RString tmp = buffer;
|
RString tmp = buffer;
|
||||||
@@ -861,7 +872,7 @@ void ChildProcess()
|
|||||||
{
|
{
|
||||||
// Read the crash data from the crashed parent.
|
// Read the crash data from the crashed parent.
|
||||||
CompleteCrashData Data;
|
CompleteCrashData Data;
|
||||||
ReadCrashDataFromParent( fileno(stdin), Data );
|
ReadCrashDataFromParent( _fileno(stdin), Data );
|
||||||
|
|
||||||
RString sCrashReport;
|
RString sCrashReport;
|
||||||
VDDebugInfo::VDDebugInfoInitFromFile( &g_debugInfo );
|
VDDebugInfo::VDDebugInfoInitFromFile( &g_debugInfo );
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -13,7 +15,7 @@
|
|||||||
#define MAX_GROUPS (64)
|
#define MAX_GROUPS (64)
|
||||||
|
|
||||||
struct RVAEnt {
|
struct RVAEnt {
|
||||||
long rva;
|
uintptr_t rva;
|
||||||
char *line;
|
char *line;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,10 +24,10 @@ std::vector<RVAEnt> rvabuf;
|
|||||||
char fnambuf[MAX_FNAMBUF];
|
char fnambuf[MAX_FNAMBUF];
|
||||||
char *fnamptr = fnambuf;
|
char *fnamptr = fnambuf;
|
||||||
|
|
||||||
long segbuf[MAX_SEGMENTS][2];
|
uintptr_t segbuf[MAX_SEGMENTS][2];
|
||||||
int segcnt=0;
|
int segcnt = 0;
|
||||||
int seggrp[MAX_SEGMENTS];
|
uint16_t seggrp[MAX_SEGMENTS];
|
||||||
long grpstart[MAX_GROUPS];
|
uintptr_t grpstart[MAX_GROUPS];
|
||||||
|
|
||||||
char line[8192];
|
char line[8192];
|
||||||
long codeseg_flags = 0;
|
long codeseg_flags = 0;
|
||||||
@@ -91,7 +93,7 @@ void RemoveAnonymousNamespaces( char *p )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parsename(long rva, char *func_name) {
|
void parsename(uintptr_t rva, char *func_name) {
|
||||||
RemoveAnonymousNamespaces( func_name );
|
RemoveAnonymousNamespaces( func_name );
|
||||||
|
|
||||||
fnamptr = strtack(fnamptr, func_name, fnambuf+MAX_FNAMBUF);
|
fnamptr = strtack(fnamptr, func_name, fnambuf+MAX_FNAMBUF);
|
||||||
@@ -106,16 +108,13 @@ struct RVASorter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int i;
|
if (argc < 3) {
|
||||||
long load_addr;
|
|
||||||
|
|
||||||
if (argc<3) {
|
|
||||||
printf("mapconv <listing-file> <output-name>\n");
|
printf("mapconv <listing-file> <output-name>\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Choose a better default for the vdi file.
|
// TODO: Choose a better default for the vdi file.
|
||||||
int ver = 20151002;
|
int ver = 20191004;
|
||||||
|
|
||||||
if (!(f=fopen(argv[1], "r"))) {
|
if (!(f=fopen(argv[1], "r"))) {
|
||||||
printf("can't open listing file \"%s\"\n", argv[1]);
|
printf("can't open listing file \"%s\"\n", argv[1]);
|
||||||
@@ -139,19 +138,21 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// printf("Reading in segment list.\n");
|
// printf("Reading in segment list.\n");
|
||||||
|
|
||||||
while(readline()) {
|
while (readline()) {
|
||||||
long grp, start, len;
|
uint16_t grp;
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
if (3!=sscanf(line, "%lx:%lx %lx", &grp, &start, &len))
|
if (sscanf(line, "%" SCNx16 ":%" SCNx32 " %" SCNx32, &grp, &start, &len) != 3)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (strstr(line+49, "CODE")) {
|
if (strstr(line + 49, "CODE")) {
|
||||||
// printf("%04x:%08lx %08lx type code\n", grp, start, len);
|
// printf("%04" PRIx16 ":%08" PRIx32 " %08" PRIx32 " type code\n", grp, start, len);
|
||||||
|
|
||||||
codeseg_flags |= 1<<grp;
|
codeseg_flags |= 1 << grp;
|
||||||
|
|
||||||
segbuf[segcnt][0] = start;
|
segbuf[segcnt][0] = static_cast<uintptr_t>(start);
|
||||||
segbuf[segcnt][1] = len;
|
segbuf[segcnt][1] = static_cast<uintptr_t>(len);
|
||||||
seggrp[segcnt] = grp;
|
seggrp[segcnt] = grp;
|
||||||
++segcnt;
|
++segcnt;
|
||||||
}
|
}
|
||||||
@@ -166,22 +167,27 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// printf("Found public symbol list.\n");
|
// printf("Found public symbol list.\n");
|
||||||
|
|
||||||
while(readline()) {
|
while (readline()) {
|
||||||
long grp, start, rva;
|
uint16_t grp;
|
||||||
|
uint32_t start;
|
||||||
|
uintptr_t rva;
|
||||||
char symname[2048];
|
char symname[2048];
|
||||||
int i;
|
|
||||||
|
|
||||||
if (4!=sscanf(line, "%lx:%lx %s %lx", &grp, &start, symname, &rva))
|
if (sscanf(line, "%" SCNx16 ":%" SCNx32 " %s %" SCNxPTR, &grp, &start, symname, &rva) != 4)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!(codeseg_flags & (1<<grp)) && strcmp(symname, "___ImageBase") )
|
#if _WIN64
|
||||||
|
if (!(codeseg_flags & (1 << grp)) && strcmp(symname, "__ImageBase"))
|
||||||
|
#else
|
||||||
|
if (!(codeseg_flags & (1 << grp)) && strcmp(symname, "___ImageBase") )
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RVAEnt entry = { rva, strdup(line) };
|
RVAEnt entry = { rva, strdup(line) };
|
||||||
|
|
||||||
rvabuf.push_back(entry);
|
rvabuf.push_back(entry);
|
||||||
|
|
||||||
// parsename(rva,symname);
|
// parsename(rva, symname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("Looking for static symbol list.\n");
|
// printf("Looking for static symbol list.\n");
|
||||||
@@ -191,21 +197,23 @@ int main(int argc, char **argv) {
|
|||||||
else {
|
else {
|
||||||
readline();
|
readline();
|
||||||
|
|
||||||
while(readline()) {
|
while (readline()) {
|
||||||
long grp, start, rva;
|
uint16_t grp;
|
||||||
|
uint32_t start;
|
||||||
|
uintptr_t rva;
|
||||||
char symname[4096];
|
char symname[4096];
|
||||||
|
|
||||||
if (4!=sscanf(line, "%lx:%lx %s %lx", &grp, &start, symname, &rva))
|
if (sscanf(line, "%" SCNx16 ":%" SCNx32 " %s %" SCNxPTR, &grp, &start, symname, &rva) != 4)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!(codeseg_flags & (1<<grp)))
|
if (!(codeseg_flags & (1 << grp)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RVAEnt entry = { rva, strdup(line) };
|
RVAEnt entry = { rva, strdup(line) };
|
||||||
|
|
||||||
rvabuf.push_back(entry);
|
rvabuf.push_back(entry);
|
||||||
|
|
||||||
// parsename(rva,symname);
|
// parsename(rva, symname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,80 +223,93 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// printf("Processing RVA entries...\n");
|
// printf("Processing RVA entries...\n");
|
||||||
|
|
||||||
for(i=0; i<rvabuf.size(); i++) {
|
for (size_t i = 0; i < rvabuf.size(); ++i) {
|
||||||
long grp, start, rva;
|
uint16_t grp;
|
||||||
|
uint32_t start;
|
||||||
|
uintptr_t rva;
|
||||||
char symname[4096];
|
char symname[4096];
|
||||||
|
|
||||||
sscanf(rvabuf[i].line, "%lx:%lx %s %lx", &grp, &start, symname, &rva);
|
if (sscanf(rvabuf[i].line, "%" SCNx16 ":%" SCNx32 " %s %" SCNxPTR, &grp, &start, symname, &rva) != 4)
|
||||||
|
break;
|
||||||
|
|
||||||
grpstart[grp] = rva - start;
|
grpstart[grp] = rva - static_cast<uintptr_t>(start);
|
||||||
|
|
||||||
parsename(rva, symname);
|
parsename(rva, symname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("Processing segment entries...\n");
|
// printf("Processing segment entries...\n");
|
||||||
|
|
||||||
for(i=0; i<segcnt; i++) {
|
for (size_t i = 0; i < segcnt; i++) {
|
||||||
segbuf[i][0] += grpstart[seggrp[i]];
|
segbuf[i][0] += grpstart[seggrp[i]];
|
||||||
// printf("\t#%-2d %08lx-%08lx\n", i+1, segbuf[i][0], segbuf[i][0]+segbuf[i][1]-1);
|
// printf("\t#%-2zu %p-%p\n", i + 1, reinterpret_cast<void*>(segbuf[i][0]), reinterpret_cast<void*>(segbuf[i][0] + segbuf[i][1] - 1));
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
printf("Raw statistics:\n");
|
printf("Raw statistics:\n");
|
||||||
printf("\tRVA bytes: %ld\n", rvabuf.size()*4);
|
printf("\tRVA bytes: %zu\n", rvabuf.size() * 4);
|
||||||
printf("\tFunc name bytes: %ld\n", fnamptr - fnambuf);
|
printf("\tFunc name bytes: %" PRIdPTR "\n", static_cast<ptrdiff_t>(fnamptr - fnambuf));
|
||||||
|
|
||||||
printf("\nPacking RVA data..."); fflush(stdout);
|
printf("\nPacking RVA data..."); fflush(stdout);
|
||||||
*/
|
*/
|
||||||
std::vector<RVAEnt>::iterator itRVA = rvabuf.begin(), itRVAEnd = rvabuf.end();
|
std::vector<RVAEnt>::iterator itRVA = rvabuf.begin(), itRVAEnd = rvabuf.end();
|
||||||
std::vector<char> rvaout;
|
std::vector<char> rvaout;
|
||||||
long firstrva = (*itRVA++).rva;
|
uintptr_t firstrva = (*itRVA++).rva;
|
||||||
long lastrva = firstrva;
|
uintptr_t lastrva = firstrva;
|
||||||
|
|
||||||
for(; itRVA != itRVAEnd; ++itRVA) {
|
for(; itRVA != itRVAEnd; ++itRVA) {
|
||||||
long rvadiff = (*itRVA).rva - lastrva;
|
ptrdiff_t rvadiff = (*itRVA).rva - lastrva;
|
||||||
|
|
||||||
lastrva += rvadiff;
|
lastrva += rvadiff;
|
||||||
|
|
||||||
if (rvadiff & 0xF0000000) rvaout.push_back((char)(0x80 | ((rvadiff>>28) & 0x7F)));
|
#if _WIN64
|
||||||
if (rvadiff & 0xFFE00000) rvaout.push_back((char)(0x80 | ((rvadiff>>21) & 0x7F)));
|
if (rvadiff & 0x8000000000000000) rvaout.push_back((char)(0x80 | ((rvadiff >> 63) & 0x7F)));
|
||||||
if (rvadiff & 0xFFFFC000) rvaout.push_back((char)(0x80 | ((rvadiff>>14) & 0x7F)));
|
if (rvadiff & 0xFF00000000000000) rvaout.push_back((char)(0x80 | ((rvadiff >> 56) & 0x7F)));
|
||||||
if (rvadiff & 0xFFFFFF80) rvaout.push_back((char)(0x80 | ((rvadiff>> 7) & 0x7F)));
|
if (rvadiff & 0xFFFE000000000000) rvaout.push_back((char)(0x80 | ((rvadiff >> 49) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFFFFC0000000000) rvaout.push_back((char)(0x80 | ((rvadiff >> 42) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFFFFFF800000000) rvaout.push_back((char)(0x80 | ((rvadiff >> 35) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFFFFFFFF0000000) rvaout.push_back((char)(0x80 | ((rvadiff >> 28) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFFFFFFFFFE00000) rvaout.push_back((char)(0x80 | ((rvadiff >> 21) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFFFFFFFFFFFC000) rvaout.push_back((char)(0x80 | ((rvadiff >> 14) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFFFFFFFFFFFFF80) rvaout.push_back((char)(0x80 | ((rvadiff >> 7) & 0x7F)));
|
||||||
|
#else
|
||||||
|
if (rvadiff & 0xF0000000) rvaout.push_back((char)(0x80 | ((rvadiff >> 28) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFE00000) rvaout.push_back((char)(0x80 | ((rvadiff >> 21) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFFFC000) rvaout.push_back((char)(0x80 | ((rvadiff >> 14) & 0x7F)));
|
||||||
|
if (rvadiff & 0xFFFFFF80) rvaout.push_back((char)(0x80 | ((rvadiff >> 7) & 0x7F)));
|
||||||
|
#endif
|
||||||
rvaout.push_back((char)(rvadiff & 0x7F));
|
rvaout.push_back((char)(rvadiff & 0x7F));
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("%ld bytes\n", rvaout.size());
|
// printf("%zu bytes\n", rvaout.size());
|
||||||
|
|
||||||
// dump data
|
// dump data
|
||||||
|
|
||||||
static const char header[64]="symbolic debug information\r\n\x1A";
|
static const char header[64] = "symbolic debug information\r\n\x1A";
|
||||||
|
|
||||||
fwrite(header, 64, 1, fo);
|
fwrite(header, 64, 1, fo);
|
||||||
|
|
||||||
long t;
|
size_t t;
|
||||||
|
|
||||||
t = ver;
|
fwrite(&ver, sizeof ver, 1, fo);
|
||||||
fwrite(&t, 4, 1, fo);
|
|
||||||
|
|
||||||
t = rvaout.size() + 4;
|
t = rvaout.size() + sizeof firstrva;
|
||||||
fwrite(&t, 4, 1, fo);
|
fwrite(&t, sizeof t, 1, fo);
|
||||||
|
|
||||||
t = fnamptr - fnambuf;
|
t = fnamptr - fnambuf;
|
||||||
fwrite(&t, 4, 1, fo);
|
fwrite(&t, sizeof t, 1, fo);
|
||||||
|
|
||||||
t = segcnt;
|
fwrite(&segcnt, sizeof segcnt, 1, fo);
|
||||||
fwrite(&t, 4, 1, fo);
|
|
||||||
|
|
||||||
fwrite(&firstrva, 4, 1, fo);
|
fwrite(&firstrva, sizeof firstrva, 1, fo);
|
||||||
fwrite(&rvaout[0], rvaout.size(), 1, fo);
|
fwrite(&rvaout[0], rvaout.size(), 1, fo);
|
||||||
fwrite(fnambuf, fnamptr - fnambuf, 1, fo);
|
fwrite(fnambuf, fnamptr - fnambuf, 1, fo);
|
||||||
fwrite(segbuf, segcnt*8, 1, fo);
|
fwrite(segbuf, segcnt * 2 * sizeof(uintptr_t), 1, fo);
|
||||||
|
|
||||||
// really all done
|
// really all done
|
||||||
|
|
||||||
if (fclose(fo))
|
if (fclose(fo))
|
||||||
throw "output file close failed";
|
throw "output file close failed";
|
||||||
|
|
||||||
} catch(const char *s) {
|
} catch (const char *s) {
|
||||||
fprintf(stderr, "%s: %s\n", argv[1], s);
|
fprintf(stderr, "%s: %s\n", argv[1], s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user