diff --git a/stepmania/src/Crash.cpp b/stepmania/src/Crash.cpp deleted file mode 100644 index 9503092c37..0000000000 --- a/stepmania/src/Crash.cpp +++ /dev/null @@ -1,1593 +0,0 @@ -#include "stdafx.h" - -// from VirtualDub -// Copyright (C) 1998-2001 Avery Lee -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -// DO NOT USE stdio.h! printf() calls malloc()! -//#include -#include -#include - -#include -#include - -#include "resource.h" -#include "crash.h" -#include "disasm.h" -#include "CrashList.h" - -#include "archutils/Win32/GotoURL.h" - -static void DoSave(const EXCEPTION_POINTERS *pExc); - -/////////////////////////////////////////////////////////////////////////// - -#define CODE_WINDOW (256) - -/////////////////////////////////////////////////////////////////////////// - -extern HINSTANCE g_hInstance; -extern unsigned long version_num; - -static CodeDisassemblyWindow *g_pcdw; - -struct VDDebugInfoContext { - void *pRawBlock; - - int nBuildNumber; - - const unsigned char *pRVAHeap; - unsigned nFirstRVA; - - const char *pClassNameHeap; - const char *pFuncNameHeap; - const unsigned long (*pSegments)[2]; - int nSegments; -}; - - -static VDDebugInfoContext g_debugInfo; - -/////////////////////////////////////////////////////////////////////////// - -BOOL APIENTRY CrashDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static void ReportCrashLog(HWND hwnd, HANDLE hFile); -static void ReportStaticLog(HWND hwnd, HANDLE hFile); - -/////////////////////////////////////////////////////////////////////////// - -#ifdef _DEBUG -/* -void checkfpustack(const char *file, const int line) throw() { - static const char szFPUProblemCaption[]="FPU/MMX internal problem"; - static const char szFPUProblemMessage[]="The FPU stack wasn't empty! Tagword = %04x\nFile: %s, line %d"; - static bool seenmsg=false; - - char buf[128]; - unsigned short tagword; - - if (seenmsg) - return; - - __asm fnstenv buf - - tagword = *(unsigned short *)(buf + 8); - - if (tagword != 0xffff) { - wsprintf(buf, szFPUProblemMessage, tagword, file, line); - MessageBox(NULL, buf, szFPUProblemCaption, MB_OK); - seenmsg=true; - } - -} - -static void __declspec(naked) *operator new(size_t bytes) { - static const char fname[]="stack trace"; - - __asm { - push ebp - mov ebp,esp - - push [ebp+4] ;return address - push offset fname ;'filename' - push _NORMAL_BLOCK ;block type - push [ebp+8] ;allocation size - - call _malloc_dbg - add esp,16 - - pop ebp - ret - } -} -*/ -#endif - -#if 0 -void __declspec(naked) stackcheck(void *&sp) { - static const char g_szStackHemorrhage[]="WARNING: Thread is hemorrhaging stack space!\n"; - - __asm { - mov eax,[esp+4] - mov ecx,[eax] - or ecx,ecx - jnz started - mov [eax],esp - ret -started: - sub ecx,esp - mov eax,ecx - sar ecx,31 - xor eax,ecx - sub eax,ecx - cmp eax,128 - jb ok - push offset g_szStackHemorrhage - call dword ptr [OutputDebugString] - int 3 -ok: - ret - } -} -#endif - -/////////////////////////////////////////////////////////////////////////// -// -// Nina's per-thread debug logs are really handy, so I back-ported -// them to 1.x. These are lightweight in comparison, however. -// - -VirtualDubThreadState __declspec(thread) g_PerThreadState; -__declspec(thread) -struct { - ListNode node; - VirtualDubThreadState *pState; -} g_PerThreadStateNode; - -class VirtualDubThreadStateNode : public ListNode2 { -public: - VirtualDubThreadState *pState; -}; - -static CRITICAL_SECTION g_csPerThreadState; -static List2 g_listPerThreadState; -static LONG g_nThreadsTrackedMinusOne = -1; - -void VirtualDubInitializeThread(const char *pszName) { - DWORD dwThreadId = GetCurrentThreadId(); - - if (!InterlockedIncrement(&g_nThreadsTrackedMinusOne)) { - InitializeCriticalSection(&g_csPerThreadState); - } - - EnterCriticalSection(&g_csPerThreadState); - - if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), (HANDLE *)&g_PerThreadState.hThread, NULL, FALSE, DUPLICATE_SAME_ACCESS)) { - - g_PerThreadState.pszThreadName = pszName; - g_PerThreadState.dwThreadId = dwThreadId; - - g_PerThreadStateNode.pState = &g_PerThreadState; - g_listPerThreadState.AddTail((ListNode2 *)&g_PerThreadStateNode); - } - - LeaveCriticalSection(&g_csPerThreadState); -} - -void VirtualDubDeinitializeThread() { - EnterCriticalSection(&g_csPerThreadState); - - ((ListNode2 *)&g_PerThreadStateNode)->Remove(); - - LeaveCriticalSection(&g_csPerThreadState); - - if (g_PerThreadState.pszThreadName) - CloseHandle((HANDLE)g_PerThreadState.hThread); - - InterlockedDecrement(&g_nThreadsTrackedMinusOne); -} - -/////////////////////////////////////////////////////////////////////////// - -static const struct ExceptionLookup { - DWORD code; - const char *name; -} exceptions[]={ - { EXCEPTION_ACCESS_VIOLATION, "Access Violation" }, - { EXCEPTION_BREAKPOINT, "Breakpoint" }, - { EXCEPTION_FLT_DENORMAL_OPERAND, "FP Denormal Operand" }, - { EXCEPTION_FLT_DIVIDE_BY_ZERO, "FP Divide-by-Zero" }, - { EXCEPTION_FLT_INEXACT_RESULT, "FP Inexact Result" }, - { EXCEPTION_FLT_INVALID_OPERATION, "FP Invalid Operation" }, - { EXCEPTION_FLT_OVERFLOW, "FP Overflow", }, - { EXCEPTION_FLT_STACK_CHECK, "FP Stack Check", }, - { EXCEPTION_FLT_UNDERFLOW, "FP Underflow", }, - { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer Divide-by-Zero", }, - { EXCEPTION_INT_OVERFLOW, "Integer Overflow", }, - { EXCEPTION_PRIV_INSTRUCTION, "Privileged Instruction", }, - { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" }, - { EXCEPTION_INVALID_HANDLE, "Invalid handle" }, - { 0xe06d7363, "Unhandled Microsoft C++ Exception", }, - // hmm... '_msc'... gee, who would have thought? - { NULL }, -}; - -long VDDebugInfoLookupRVA(VDDebugInfoContext *pctx, unsigned rva, char *buf, int buflen); -bool VDDebugInfoInitFromMemory(VDDebugInfoContext *pctx, const void *_src); -bool VDDebugInfoInitFromFile(VDDebugInfoContext *pctx, const char *pszFilename); -void VDDebugInfoDeinit(VDDebugInfoContext *pctx); - -static void SpliceProgramPath(char *buf, int bufsiz, const char *fn) { - char tbuf[MAX_PATH]; - char *pszFile; - - GetModuleFileName(NULL, tbuf, sizeof tbuf); - GetFullPathName(tbuf, bufsiz, buf, &pszFile); - strcpy(pszFile, fn); -} - -long CrashSymLookup(VDDisassemblyContext *pctx, unsigned long virtAddr, char *buf, int buf_len) { - if (!g_debugInfo.pRVAHeap) - return -1; - - return VDDebugInfoLookupRVA(&g_debugInfo, virtAddr, buf, buf_len); -} - -static char szEmergencyDumpName[MAX_PATH]; -static void DoSaveEmergencyDump(const char *buf, int siz) { - HANDLE hFile; - - SpliceProgramPath(szEmergencyDumpName, sizeof szEmergencyDumpName, "crashdump.dat"); - hFile = CreateFile(szEmergencyDumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (INVALID_HANDLE_VALUE == hFile) - return; - - DWORD dwActual; - WriteFile(hFile, buf, siz, &dwActual, NULL); - FlushFileBuffers(hFile); - - CloseHandle(hFile); -} - -static void DoEraseEmergencyDump() -{ - DeleteFile(szEmergencyDumpName); -} - -extern HWND g_hWndMain; -long __stdcall CrashHandler(EXCEPTION_POINTERS *pExc) { - /* If we're fullscreen, the fullscreen d3d window will obscure - * the crash dialog. Do this before we suspend threads, or it'll - * deadlock if the thread controlling this window has been stopped. */ - /* XXX problem: If the sound thread crashes at the same time the main - * thread tells it to shut down, the main thread will be blocking waiting - * for the sound thread to finish; we'll come here and deadlock waiting for - * it to hide. Hmmmmm. */ - ShowWindow( g_hWndMain, SW_HIDE ); - - ///////////////////////// - // - // QUICKLY: SUSPEND ALL THREADS THAT AREN'T US. - - EnterCriticalSection(&g_csPerThreadState); - - try { - DWORD dwCurrentThread = GetCurrentThreadId(); - - for(List2::fwit it = g_listPerThreadState.begin(); it; ++it) { - const VirtualDubThreadState *pState = it->pState; - - if (pState->dwThreadId && pState->dwThreadId != dwCurrentThread) { - SuspendThread((HANDLE)pState->hThread); - } - } - } catch(...) { - } - - LeaveCriticalSection(&g_csPerThreadState); - - static bool InHere = false; - if(InHere) - { - /* If we get here, then we've been called recursively, which means - * we (the disassembler or related code) crashed. If this happens, - * we're not in very good shape. We've left the emergency dump; - * that's all we have to go by. Tell this to the user, and then die. - * - * We've already blown up twice, and this is our last line of defense. - * If this dies, we have nothing, so keep it simple. */ - SetUnhandledExceptionFilter(NULL); - MessageBox( NULL, - "The error reporting interface has crashed.\n" - "Please report a bug and attach the file \"crashdump.dat\"\n" - "to the report.", "Fatal Error", MB_OK ); -#ifdef _DEBUG - DebugBreak(); -#endif - - return EXCEPTION_EXECUTE_HANDLER; - } - InHere=true; - ///////////////////////// - - static char buf[CODE_WINDOW+16]; - HANDLE hprMe = GetCurrentProcess(); - void *lpBaseAddress = pExc->ExceptionRecord->ExceptionAddress; - char *lpAddr = (char *)((long)lpBaseAddress & -32); - - memset(buf, 0, sizeof buf); - - if ((unsigned long)lpAddr > CODE_WINDOW/2) - lpAddr -= CODE_WINDOW/2; - else - lpAddr = NULL; - - if (!ReadProcessMemory(hprMe, lpAddr, buf, CODE_WINDOW, NULL)) { - int i; - - for(i=0; iExceptionRecord; - - // fill out bomb reason - const struct ExceptionLookup *pel = exceptions; - - while(pel->code) { - if (pel->code == pRecord->ExceptionCode) - break; - - ++pel; - } - - // Unfortunately, EXCEPTION_ACCESS_VIOLATION doesn't seem to provide - // us with the read/write flag and virtual address as the docs say... - // *sigh* - - if (!pel->code) { - if (hwndReason) - SetWindowTitlef(hwndReason, "Crash reason: unknown exception 0x%08lx", pRecord->ExceptionCode); - - if (hFile) - Report(hwnd, hFile, "Crash reason: unknown exception 0x%08lx", pRecord->ExceptionCode); - } else { - if (hwndReason) - SetWindowTitlef(hwndReason, "Crash reason: %s", pel->name); - - if (hFile) - Report(hwnd, hFile, "Crash reason: %s", pel->name); - } -} - -static void ReportThreadStacks(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc) -{ - EnterCriticalSection(&g_csPerThreadState); - - try { - for(List2::fwit it = g_listPerThreadState.begin(); it; ++it) { - const VirtualDubThreadState *pState = it->pState; - - Report(hwnd, hFile, "Thread %08lx (%s)", pState->dwThreadId, pState->pszThreadName?pState->pszThreadName:"unknown"); - - for(int i=0; icp[(pState->nNextCP+i) & (CHECKPOINT_COUNT-1)]; - - if (cp.file) { - Report(hwnd, hFile, "\t%s:%d %s", cp.file, cp.line, cp.message? cp.message:""); - } - } - } - } catch(...) { - } - - LeaveCriticalSection(&g_csPerThreadState); -} - -static void ReportCrashData(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc) { -// const EXCEPTION_RECORD *const pRecord = (const EXCEPTION_RECORD *)pExc->ExceptionRecord; - const CONTEXT *const pContext = (const CONTEXT *)pExc->ContextRecord; - int i, tos; - - Report(hwnd, hFile, "EAX = %08lx", pContext->Eax); - Report(hwnd, hFile, "EBX = %08lx", pContext->Ebx); - Report(hwnd, hFile, "ECX = %08lx", pContext->Ecx); - Report(hwnd, hFile, "EDX = %08lx", pContext->Edx); - Report(hwnd, hFile, "EBP = %08lx", pContext->Ebp); - Report(hwnd, hFile, "DS:ESI = %04x:%08lx", pContext->SegDs, pContext->Esi); - Report(hwnd, hFile, "ES:EDI = %04x:%08lx", pContext->SegEs, pContext->Edi); - Report(hwnd, hFile, "SS:ESP = %04x:%08lx", pContext->SegSs, pContext->Esp); - Report(hwnd, hFile, "CS:EIP = %04x:%08lx", pContext->SegCs, pContext->Eip); - Report(hwnd, hFile, "FS = %04x", pContext->SegFs); - Report(hwnd, hFile, "GS = %04x", pContext->SegGs); - Report(hwnd, hFile, "EFLAGS = %08lx", pContext->EFlags); - Report(hwnd, hFile, ""); - - // extract out MMX registers - - tos = (pContext->FloatSave.StatusWord & 0x3800)>>11; - - for(i=0; i<8; i++) { - long *pReg = (long *)(pContext->FloatSave.RegisterArea + 10*((i-tos) & 7)); - - Report(hwnd, hFile, "MM%c = %08lx%08lx", i+'0', pReg[1], pReg[0]); - } -} - -static const char *GetNameFromHeap(const char *heap, int idx) { - while(idx--) - while(*heap++); - - return heap; -} - -////////////////////////////////////////////////////////////////////////////// - -static bool IsValidCall(char *buf, int len) { - // Permissible CALL sequences that we care about: - // - // E8 xx xx xx xx CALL near relative - // FF (group 2) CALL near absolute indirect - // - // Minimum sequence is 2 bytes (call eax). - // Maximum sequence is 7 bytes (call dword ptr [eax+disp32]). - - if (len >= 5 && buf[-5] == (char)0xE8) - return true; - - // FF 14 xx CALL [reg32+reg32*scale] - - if (len >= 3 && buf[-3] == (char)0xFF && buf[-2]==0x14) - return true; - - // FF 15 xx xx xx xx CALL disp32 - - if (len >= 6 && buf[-6] == (char)0xFF && buf[-5]==0x15) - return true; - - // FF 00-3F(!14/15) CALL [reg32] - - if (len >= 2 && buf[-2] == (char)0xFF && (unsigned char)buf[-1] < 0x40) - return true; - - // FF D0-D7 CALL reg32 - - if (len >= 2 && buf[-2] == (char)0xFF && (buf[-1]&0xF8) == 0xD0) - return true; - - // FF 50-57 xx CALL [reg32+reg32*scale+disp8] - - if (len >= 3 && buf[-3] == (char)0xFF && (buf[-2]&0xF8) == 0x50) - return true; - - // FF 90-97 xx xx xx xx xx CALL [reg32+reg32*scale+disp32] - - if (len >= 7 && buf[-7] == (char)0xFF && (buf[-6]&0xF8) == 0x90) - return true; - - return false; -} - -////////////////////////////////////////////////////////////////////////////// - -struct ModuleInfo { - const char *name; - unsigned long base, size; -}; - -// ARRGH. Where's psapi.h?!? - -struct Win32ModuleInfo { - DWORD base, size, entry; -}; - -typedef BOOL (__stdcall *PENUMPROCESSMODULES)(HANDLE, HMODULE *, DWORD, LPDWORD); -typedef DWORD (__stdcall *PGETMODULEBASENAME)(HANDLE, HMODULE, LPTSTR, DWORD); -typedef BOOL (__stdcall *PGETMODULEINFORMATION)(HANDLE, HMODULE, Win32ModuleInfo *, DWORD); - -typedef HANDLE (__stdcall *PCREATETOOLHELP32SNAPSHOT)(DWORD, DWORD); -typedef BOOL (WINAPI *PMODULE32FIRST)(HANDLE, LPMODULEENTRY32); -typedef BOOL (WINAPI *PMODULE32NEXT)(HANDLE, LPMODULEENTRY32); - -static ModuleInfo *CrashGetModules(void *&ptr) { - void *pMem = VirtualAlloc(NULL, 65536, MEM_COMMIT, PAGE_READWRITE); - - if (!pMem) { - ptr = NULL; - return NULL; - } - - // This sucks. If we're running under Windows 9x, we must use - // TOOLHELP.DLL to get the module list. Under Windows NT, we must - // use PSAPI.DLL. With Windows 2000, we can use both (but prefer - // PSAPI.DLL). - - HMODULE hmodPSAPI = LoadLibrary("psapi.dll"); - - if (hmodPSAPI) { - // Using PSAPI.DLL. Call EnumProcessModules(), then GetModuleFileNameEx() - // and GetModuleInformation(). - - PENUMPROCESSMODULES pEnumProcessModules = (PENUMPROCESSMODULES)GetProcAddress(hmodPSAPI, "EnumProcessModules"); - PGETMODULEBASENAME pGetModuleBaseName = (PGETMODULEBASENAME)GetProcAddress(hmodPSAPI, "GetModuleBaseNameA"); - PGETMODULEINFORMATION pGetModuleInformation = (PGETMODULEINFORMATION)GetProcAddress(hmodPSAPI, "GetModuleInformation"); - HMODULE *pModules, *pModules0 = (HMODULE *)((char *)pMem + 0xF000); - DWORD cbNeeded; - - if (pEnumProcessModules && pGetModuleBaseName && pGetModuleInformation - && pEnumProcessModules(GetCurrentProcess(), pModules0, 0x1000, &cbNeeded)) { - - ModuleInfo *pMod, *pMod0; - char *pszHeap = (char *)pMem, *pszHeapLimit; - - if (cbNeeded > 0x1000) cbNeeded = 0x1000; - - pModules = (HMODULE *)((char *)pMem + 0x10000 - cbNeeded); - memmove(pModules, pModules0, cbNeeded); - - pMod = pMod0 = (ModuleInfo *)((char *)pMem + 0x10000 - sizeof(ModuleInfo) * (cbNeeded / sizeof(HMODULE) + 1)); - pszHeapLimit = (char *)pMod; - - do { - HMODULE hCurMod = *pModules++; - Win32ModuleInfo mi; - - if (pGetModuleBaseName(GetCurrentProcess(), hCurMod, pszHeap, pszHeapLimit - pszHeap) - && pGetModuleInformation(GetCurrentProcess(), hCurMod, &mi, sizeof mi)) { - - char *period = NULL; - - pMod->name = pszHeap; - - while(*pszHeap++) - if (pszHeap[-1] == '.') - period = pszHeap-1; - - if (period) { - *period = 0; - pszHeap = period+1; - } - - pMod->base = mi.base; - pMod->size = mi.size; - ++pMod; - } - } while((cbNeeded -= sizeof(HMODULE *)) > 0); - - pMod->name = NULL; - - FreeLibrary(hmodPSAPI); - ptr = pMem; - return pMod0; - } - - FreeLibrary(hmodPSAPI); - } else { - // No PSAPI. Use the ToolHelp functions in KERNEL. - - HMODULE hmodKERNEL32 = LoadLibrary("kernel32.dll"); - - PCREATETOOLHELP32SNAPSHOT pCreateToolhelp32Snapshot = (PCREATETOOLHELP32SNAPSHOT)GetProcAddress(hmodKERNEL32, "CreateToolhelp32Snapshot"); - PMODULE32FIRST pModule32First = (PMODULE32FIRST)GetProcAddress(hmodKERNEL32, "Module32First"); - PMODULE32NEXT pModule32Next = (PMODULE32NEXT)GetProcAddress(hmodKERNEL32, "Module32Next"); - HANDLE hSnap; - - if (pCreateToolhelp32Snapshot && pModule32First && pModule32Next) { - if ((HANDLE)-1 != (hSnap = pCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0))) { - ModuleInfo *pModInfo = (ModuleInfo *)((char *)pMem + 65536); - char *pszHeap = (char *)pMem; - MODULEENTRY32 me; - - --pModInfo; - pModInfo->name = NULL; - - me.dwSize = sizeof(MODULEENTRY32); - - if (pModule32First(hSnap, &me)) - do { - if (pszHeap+strlen(me.szModule) >= (char *)(pModInfo - 1)) - break; - - strcpy(pszHeap, me.szModule); - - --pModInfo; - pModInfo->name = pszHeap; - - char *period = NULL; - - while(*pszHeap++); - if (pszHeap[-1]=='.') - period = pszHeap-1; - - if (period) { - *period = 0; - pszHeap = period+1; - } - - pModInfo->base = (unsigned long)me.modBaseAddr; - pModInfo->size = me.modBaseSize; - - } while(pModule32Next(hSnap, &me)); - - CloseHandle(hSnap); - - FreeLibrary(hmodKERNEL32); - - ptr = pMem; - return pModInfo; - } - } - - FreeLibrary(hmodKERNEL32); - } - - VirtualFree(pMem, 0, MEM_RELEASE); - - ptr = NULL; - return NULL; -} - -/////////////////////////////////////////////////////////////////////////// -// -// info from Portable Executable/Common Object File Format (PE/COFF) spec - -typedef unsigned short ushort; -typedef unsigned long ulong; - -struct PEHeader { - ulong signature; - ushort machine; - ushort sections; - ulong timestamp; - ulong symbol_table; - ulong symbols; - ushort opthdr_size; - ushort characteristics; -}; - -struct PESectionHeader { - char name[8]; - ulong virtsize; - ulong virtaddr; - ulong rawsize; - ulong rawptr; - ulong relocptr; - ulong linenoptr; - ushort reloc_cnt; - ushort lineno_cnt; - ulong characteristics; -}; - -struct PEExportDirectory { - ulong flags; - ulong timestamp; - ushort major; - ushort minor; - ulong nameptr; - ulong ordbase; - ulong addrtbl_cnt; - ulong nametbl_cnt; - ulong addrtbl_ptr; - ulong nametbl_ptr; - ulong ordtbl_ptr; -}; - -struct PE32OptionalHeader { - ushort magic; // 0 - char major_linker_ver; // 2 - char minor_linker_ver; // 3 - ulong codesize; // 4 - ulong idatasize; // 8 - ulong udatasize; // 12 - ulong entrypoint; // 16 - ulong codebase; // 20 - ulong database; // 24 - ulong imagebase; // 28 - ulong section_align; // 32 - ulong file_align; // 36 - ushort majoros; // 40 - ushort minoros; // 42 - ushort majorimage; // 44 - ushort minorimage; // 46 - ushort majorsubsys; // 48 - ushort minorsubsys; // 50 - ulong reserved; // 52 - ulong imagesize; // 56 - ulong hdrsize; // 60 - ulong checksum; // 64 - ushort subsystem; // 68 - ushort characteristics; // 70 - ulong stackreserve; // 72 - ulong stackcommit; // 76 - ulong heapreserve; // 80 - ulong heapcommit; // 84 - ulong loaderflags; // 88 - ulong dictentries; // 92 - - // Not part of header, but it's convienent here - - ulong export_RVA; // 96 - ulong export_size; // 100 -}; - -struct PE32PlusOptionalHeader { - ushort magic; // 0 - char major_linker_ver; // 2 - char minor_linker_ver; // 3 - ulong codesize; // 4 - ulong idatasize; // 8 - ulong udatasize; // 12 - ulong entrypoint; // 16 - ulong codebase; // 20 - __int64 imagebase; // 24 - ulong section_align; // 32 - ulong file_align; // 36 - ushort majoros; // 40 - ushort minoros; // 42 - ushort majorimage; // 44 - ushort minorimage; // 46 - ushort majorsubsys; // 48 - ushort minorsubsys; // 50 - ulong reserved; // 52 - ulong imagesize; // 56 - ulong hdrsize; // 60 - ulong checksum; // 64 - ushort subsystem; // 68 - ushort characteristics; // 70 - __int64 stackreserve; // 72 - __int64 stackcommit; // 80 - __int64 heapreserve; // 88 - __int64 heapcommit; // 96 - ulong loaderflags; // 104 - ulong dictentries; // 108 - - // Not part of header, but it's convienent here - - ulong export_RVA; // 112 - ulong export_size; // 116 -}; - -static const char *CrashLookupExport(HMODULE hmod, unsigned long addr, unsigned long &fnbase) { - char *pBase = (char *)hmod; - - // The PEheader offset is at hmod+0x3c. Add the size of the optional header - // to step to the section headers. - - PEHeader *pHeader = (PEHeader *)(pBase + ((long *)hmod)[15]); - - if (pHeader->signature != 'EP') - return NULL; - -#if 0 - PESectionHeader *pSHdrs = (PESectionHeader *)((char *)pHeader + sizeof(PEHeader) + pHeader->opthdr_size); - - // Scan down the section headers and look for ".edata" - - int i; - - for(i=0; isections; i++) { - MessageBox(NULL, pSHdrs[i].name, "section", MB_OK); - if (!memcmp(pSHdrs[i].name, ".edata", 6)) - break; - } - - if (i >= pHeader->sections) - return NULL; -#endif - - // Verify the optional structure. - - PEExportDirectory *pExportDir; - - if (pHeader->opthdr_size < 104) - return NULL; - - switch(*(short *)((char *)pHeader + sizeof(PEHeader))) { - case 0x10b: // PE32 - { - PE32OptionalHeader *pOpt = (PE32OptionalHeader *)((char *)pHeader + sizeof(PEHeader)); - - if (pOpt->dictentries < 1) - return NULL; - - pExportDir = (PEExportDirectory *)(pBase + pOpt->export_RVA); - } - break; - case 0x20b: // PE32+ - { - PE32PlusOptionalHeader *pOpt = (PE32PlusOptionalHeader *)((char *)pHeader + sizeof(PEHeader)); - - if (pOpt->dictentries < 1) - return NULL; - - pExportDir = (PEExportDirectory *)(pBase + pOpt->export_RVA); - } - break; - - default: - return NULL; - } - - // Hmmm... no exports? - - if ((char *)pExportDir == pBase) - return NULL; - - // Find the location of the export information. - - ulong *pNameTbl = (ulong *)(pBase + pExportDir->nametbl_ptr); - ulong *pAddrTbl = (ulong *)(pBase + pExportDir->addrtbl_ptr); - ushort *pOrdTbl = (ushort *)(pBase + pExportDir->ordtbl_ptr); - - // Scan exports. - - const char *pszName = NULL; - ulong bestdelta = 0xFFFFFFFF; - unsigned i; - - addr -= (ulong)pBase; - - for(i=0; inametbl_cnt; i++) { - ulong fnaddr; - int idx; - - idx = pOrdTbl[i]; - fnaddr = pAddrTbl[idx]; - - if (addr >= fnaddr) { - ulong delta = addr - fnaddr; - - if (delta < bestdelta) { - bestdelta = delta; - fnbase = fnaddr; - - if (pNameTbl[i]) - pszName = pBase + pNameTbl[i]; - else { - static char buf[8]; - - wsprintf(buf, "ord%d", pOrdTbl[i]); - pszName = buf; - } - - } - } - } - - return pszName; -} - -/////////////////////////////////////////////////////////////////////////// - -static bool IsExecutableProtection(DWORD dwProtect) { - MEMORY_BASIC_INFORMATION meminfo; - - // Windows NT/2000 allows Execute permissions, but Win9x seems to - // rip it off. So we query the permissions on our own code block, - // and use it to determine if READONLY/READWRITE should be - // considered 'executable.' - - VirtualQuery(IsExecutableProtection, &meminfo, sizeof meminfo); - - switch((unsigned char)dwProtect) { - case PAGE_READONLY: // *sigh* Win9x... - case PAGE_READWRITE: // *sigh* - return meminfo.Protect==PAGE_READONLY || meminfo.Protect==PAGE_READWRITE; - - case PAGE_EXECUTE: - case PAGE_EXECUTE_READ: - case PAGE_EXECUTE_READWRITE: - case PAGE_EXECUTE_WRITECOPY: - return true; - } - return false; -} - -static const char *CrashGetModuleBaseName(HMODULE hmod, char *pszBaseName) { - char szPath1[MAX_PATH]; - char szPath2[MAX_PATH]; - - __try { - DWORD dw; - char *pszFile, *period = NULL; - - if (!GetModuleFileName(hmod, szPath1, sizeof szPath1)) - return NULL; - - dw = GetFullPathName(szPath1, sizeof szPath2, szPath2, &pszFile); - - if (!dw || dw>sizeof szPath2) - return NULL; - - strcpy(pszBaseName, pszFile); - - pszFile = pszBaseName; - - while(*pszFile++) - if (pszFile[-1]=='.') - period = pszFile-1; - - if (period) - *period = 0; - } __except(1) { - return NULL; - } - - return pszBaseName; -} - - -/////////////////////////////////////////////////////////////////////////// - -bool VDDebugInfoInitFromMemory(VDDebugInfoContext *pctx, const void *_src) { - const unsigned char *src = (const unsigned char *)_src; - - pctx->pRVAHeap = NULL; - - // Check type string - - if (!memcmp((char *)src + 6, "] StepMania disasm", 18)) - src += *(long *)(src + 64) + 72; - - if (src[0] != '[' || src[3] != '|') - return false; - - if (memcmp((char *)src + 6, "] StepMania symbolic debug information", 38)) - return false; - - // Check version number - -// int write_version = (src[1]-'0')*10 + (src[2] - '0'); - int compat_version = (src[4]-'0')*10 + (src[5] - '0'); - - if (compat_version > 1) - return false; // resource is too new for us to load - - // Extract fields - - src += 64; - - pctx->nBuildNumber = *(int *)src; - pctx->pRVAHeap = (const unsigned char *)(src + 24); - pctx->nFirstRVA = *(const long *)(src + 20); - pctx->pClassNameHeap = (const char *)pctx->pRVAHeap - 4 + *(const long *)(src + 4); - pctx->pFuncNameHeap = pctx->pClassNameHeap + *(const long *)(src + 8); - pctx->pSegments = (unsigned long (*)[2])(pctx->pFuncNameHeap + *(const long *)(src + 12)); - pctx->nSegments = *(const long *)(src + 16); - - return true; -} - -void VDDebugInfoDeinit(VDDebugInfoContext *pctx) { - if (pctx->pRawBlock) { - VirtualFree(pctx->pRawBlock, 0, MEM_RELEASE); - pctx->pRawBlock = NULL; - } -} - -bool VDDebugInfoInitFromFile(VDDebugInfoContext *pctx, const char *pszFilename) { - pctx->pRawBlock = NULL; - pctx->pRVAHeap = NULL; - - HANDLE h = CreateFile(pszFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (INVALID_HANDLE_VALUE == h) { - return false; - } - - do { - DWORD dwFileSize = GetFileSize(h, NULL); - - if (dwFileSize == 0xFFFFFFFF) - break; - - pctx->pRawBlock = VirtualAlloc(NULL, dwFileSize, MEM_COMMIT, PAGE_READWRITE); - if (!pctx->pRawBlock) - break; - - DWORD dwActual; - if (!ReadFile(h, pctx->pRawBlock, dwFileSize, &dwActual, NULL) || dwActual != dwFileSize) - break; - - if (VDDebugInfoInitFromMemory(pctx, pctx->pRawBlock)) { - CloseHandle(h); - return true; - } - } while(false); - - VDDebugInfoDeinit(pctx); - CloseHandle(h); - return false; -} - -long VDDebugInfoLookupRVA(VDDebugInfoContext *pctx, unsigned rva, char *buf, int buflen) { - int i; - - for(i=0; inSegments; ++i) { - if (rva >= pctx->pSegments[i][0] && rva < pctx->pSegments[i][0] + pctx->pSegments[i][1]) - break; - } - - if (i >= pctx->nSegments) - return -1; - - const unsigned char *pr = pctx->pRVAHeap; - const unsigned char *pr_limit = (const unsigned char *)pctx->pClassNameHeap; - int idx = 0; - - // Linearly unpack RVA deltas and find lower_bound - - rva -= pctx->nFirstRVA; - - if ((signed)rva < 0) - return -1; - - while(pr < pr_limit) { - unsigned char c; - unsigned diff = 0; - - do { - c = *pr++; - - diff = (diff << 7) | (c & 0x7f); - } while(c & 0x80); - - rva -= diff; - - if ((signed)rva < 0) { - rva += diff; - break; - } - - ++idx; - } - - // Decompress name for RVA - - if (pr < pr_limit) { - const char *fn_name = GetNameFromHeap(pctx->pFuncNameHeap, idx); - const char *class_name = NULL; - const char *prefix = ""; - - if (*fn_name == 0) - return -1; - - if (*fn_name < 32) { - int class_idx; - - class_idx = (((unsigned char*)fn_name)[0] - 1)*128 + (((unsigned char*)fn_name)[1] - 1); - class_name = GetNameFromHeap(pctx->pClassNameHeap, class_idx); - - fn_name += 2; - - if (*fn_name == 1) { - fn_name = class_name; - } else if (*fn_name == 2) { - fn_name = class_name; - prefix = "~"; - } else if (*fn_name < 32) - fn_name = "(special)"; - } - - // ehh... where's my wsnprintf? _snprintf() might allocate memory or locks.... - return wsprintf(buf, "%s%s%s%s", class_name?class_name:"", class_name?"::":"", prefix, fn_name) >= 0 - ? rva - : -1; - } - - return -1; -} - -/////////////////////////////////////////////////////////////////////////// - -static bool ReportCrashCallStack(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc, const void *pDebugSrc) { - const CONTEXT *const pContext = (const CONTEXT *)pExc->ContextRecord; - HANDLE hprMe = GetCurrentProcess(); - char *lpAddr = (char *)pContext->Esp; - int limit = 100; - unsigned long data; - char buf[512]; - - if (!g_debugInfo.pRVAHeap) { - Report(hwnd, hFile, "Could not open debug resource file (StepMania.vdi)."); - return false; - } - - if (g_debugInfo.nBuildNumber != int(version_num)) { - Report(hwnd, hFile, "Incorrect StepMania.vdi file (build %d, expected %d) for this version of StepMania -- call stack unavailable.", g_debugInfo.nBuildNumber, int(version_num)); - return false; - } - - // Get some module names. - - void *pModuleMem; - ModuleInfo *pModules = CrashGetModules(pModuleMem); - - // Retrieve stack pointers. - // Not sure if NtCurrentTeb() is available on Win95.... - - NT_TIB *pTib; - - __asm { - mov eax, fs:[0]_NT_TIB.Self - mov pTib, eax - } - - char *pStackBase = (char *)pTib->StackBase; - - // Walk up the stack. Hopefully it wasn't fscked. - - data = pContext->Eip; - do { - bool fValid = true; - int len; - MEMORY_BASIC_INFORMATION meminfo; - - VirtualQuery((void *)data, &meminfo, sizeof meminfo); - - if (!IsExecutableProtection(meminfo.Protect) || meminfo.State!=MEM_COMMIT) { -// Report(hwnd, hFile, "Rejected: %08lx (%08lx)", data, meminfo.Protect); - fValid = false; - } - - if (data != pContext->Eip) { - len = 7; - - *(long *)(buf + 0) = *(long *)(buf + 4) = 0; - - while(len > 0 && !ReadProcessMemory(GetCurrentProcess(), (void *)(data-len), buf+7-len, len, NULL)) - --len; - - fValid &= IsValidCall(buf+7, len); - } - - if (fValid) { - if (VDDebugInfoLookupRVA(&g_debugInfo, data, buf, sizeof buf) >= 0) { - Report(hwnd, hFile, "%08lx: %s()", data, buf); - --limit; - } else { - ModuleInfo *pMods = pModules; - ModuleInfo mi; - char szName[MAX_PATH]; - - mi.name = NULL; - - if (pMods) { - while(pMods->name) { - if (data >= pMods->base && (data - pMods->base) < pMods->size) - break; - - ++pMods; - } - - mi = *pMods; - } else { - - // Well, something failed, or we didn't have either PSAPI.DLL or ToolHelp - // to play with. So we'll use a nastier method instead. - - mi.base = (unsigned long)meminfo.AllocationBase; - mi.name = CrashGetModuleBaseName((HMODULE)mi.base, szName); - } - - if (mi.name) { - unsigned long fnbase; - const char *pExportName = CrashLookupExport((HMODULE)mi.base, data, fnbase); - - if (pExportName) - Report(hwnd, hFile, "%08lx: %s!%s [%08lx+%lx+%lx]", data, mi.name, pExportName, mi.base, fnbase, (data-mi.base-fnbase)); - else - Report(hwnd, hFile, "%08lx: %s!%08lx", data, mi.name, data - mi.base); - } else - Report(hwnd, hFile, "%08lx: %08lx", data, data); - - --limit; - } - } - - if (lpAddr >= pStackBase) - break; - - lpAddr += 4; - } while(limit > 0 && ReadProcessMemory(hprMe, lpAddr-4, &data, 4, NULL)); - - // All done, close up shop and exit. - - if (pModuleMem) - VirtualFree(pModuleMem, 0, MEM_RELEASE); - - return true; -} - -static void ReportDisasm(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc) -{ - char tbuf[2048]; - long idx = 0; - - Report(hwnd, hFile, "Disassembly:"); - - while(idx = g_pcdw->getInstruction(tbuf, idx)) { - Report(hwnd, hFile, "%s", tbuf); - } - FlushFileBuffers(hFile); -} - -static void DoSave(const EXCEPTION_POINTERS *pExc) { - HANDLE hFile; - char szModName2[MAX_PATH]; - - SpliceProgramPath(szModName2, sizeof szModName2, "crashinfo.txt"); - - hFile = CreateFile(szModName2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (INVALID_HANDLE_VALUE == hFile) - return; - - Report(NULL, hFile, - "StepMania crash report -- build %d\r\n" - "--------------------------------------" - "\r\n", version_num); - - // Detect operating system. - - OSVERSIONINFO ovi; - ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - /* XXX: rewrite this mess */ - if (GetVersionEx(&ovi)) { - Report(NULL, hFile, "Windows %d.%d (Win%s build %d) [%s]", - ovi.dwMajorVersion, - ovi.dwMinorVersion, - ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS? - (ovi.dwMinorVersion>0? "98" : "95"): - ovi.dwPlatformId == VER_PLATFORM_WIN32_NT? - (ovi.dwMajorVersion >= 5? - (ovi.dwMinorVersion>0? "XP":"2000"): "NT") - : "?", - ovi.dwBuildNumber & 0xffff, - ovi.szCSDVersion); - } - Report(NULL, hFile, ""); - - ReportReason(NULL, NULL, hFile, pExc); - Report(NULL, hFile, ""); - - // Dump thread stacks - ReportThreadStacks(NULL, hFile, pExc); - Report(NULL, hFile, ""); - - ReportCrashCallStack(NULL, hFile, pExc, g_pcdw->vdc.pExtraData); - Report(NULL, hFile, ""); - - ReportStaticLog(NULL, hFile); - Report(NULL, hFile, ""); - - ReportCrashLog(NULL, hFile); - Report(NULL, hFile, ""); - - /* We can do without these for now. People keep saying "here's a bug, - * tell me if you want the crash dump" which wastes time (of course we - * do!). Let's make the dump smaller to encourage just sending it, which - * is what people should be doing. (If we can use the SF BTS more - * consistently, instead of forums, this will be less of an issue.) */ -/* ReportDisasm(NULL, hFile, pExc); - Report(NULL, hFile, ""); - - ReportCrashData(NULL, hFile, pExc); - Report(NULL, hFile, ""); -*/ - Report(NULL, hFile, "-- End of report"); - CloseHandle(hFile); -} - -void ViewWithNotepad(const char *str) -{ - char buf[256] = ""; - strcat(buf, "notepad.exe "); - strcat(buf, str); - - char cwd[MAX_PATH]; - SpliceProgramPath(cwd, MAX_PATH, ""); - - PROCESS_INFORMATION pi; - STARTUPINFO si; - ZeroMemory( &si, sizeof(si) ); - - CreateProcess( - NULL, // pointer to name of executable module - buf, // pointer to command line string - NULL, // process security attributes - NULL, // thread security attributes - false, // handle inheritance flag - 0, // creation flags - NULL, // pointer to new environment block - cwd, // pointer to current directory name - &si, // pointer to STARTUPINFO - &pi // pointer to PROCESS_INFORMATION - ); -} - -BOOL APIENTRY CrashDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - static const EXCEPTION_POINTERS *s_pExc; - static bool s_bHaveCallstack; - - switch(msg) { - - case WM_INITDIALOG: - { - HWND hwndList1 = GetDlgItem(hDlg, IDC_ASMBOX); - HWND hwndList2 = GetDlgItem(hDlg, IDC_REGDUMP); - HWND hwndList3 = GetDlgItem(hDlg, IDC_CALL_STACK); - HWND hwndReason = GetDlgItem(hDlg, IDC_STATIC_BOMBREASON); - const EXCEPTION_POINTERS *const pExc = (const EXCEPTION_POINTERS *)lParam; - - s_pExc = pExc; - - g_pcdw->DoInitListbox(hwndList1); - - SendMessage(hwndList2, WM_SETFONT, SendMessage(hwndList1, WM_GETFONT, 0, 0), MAKELPARAM(TRUE, 0)); - SendMessage(hwndList3, WM_SETFONT, SendMessage(hwndList1, WM_GETFONT, 0, 0), MAKELPARAM(TRUE, 0)); - - ReportReason(NULL, hwndReason, NULL, pExc); - ReportCrashData(hwndList2, NULL, pExc); - s_bHaveCallstack = ReportCrashCallStack(hwndList3, NULL, pExc, g_pcdw->vdc.pExtraData); - } - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_BUTTON_CLOSE: - EndDialog(hDlg, FALSE); - return TRUE; - case IDOK: - EndDialog(hDlg, TRUE); - return TRUE; - case IDC_VIEW_LOG: - ViewWithNotepad("log.txt"); - break; - case IDC_CRASH_SAVE: - if (!s_bHaveCallstack) - if (IDOK != MessageBox(hDlg, - "StepMania cannot load its crash resource file, and thus the crash dump will be " - "missing the most important part, the call stack. Crash dumps are much less useful " - "without the call stack.", - "StepMania warning", MB_OK|MB_ICONEXCLAMATION)) - return TRUE; - - ViewWithNotepad("crashinfo.txt"); - return TRUE; - case IDC_BUTTON_RESTART: - { - char cwd[MAX_PATH]; - SpliceProgramPath(cwd, MAX_PATH, ""); - - TCHAR szFullAppPath[MAX_PATH]; - GetModuleFileName(NULL, szFullAppPath, MAX_PATH); - - // Launch StepMania - PROCESS_INFORMATION pi; - STARTUPINFO si; - ZeroMemory( &si, sizeof(si) ); - - CreateProcess( - NULL, // pointer to name of executable module - szFullAppPath, // pointer to command line string - NULL, // process security attributes - NULL, // thread security attributes - false, // handle inheritance flag - 0, // creation flags - NULL, // pointer to new environment block - cwd, // pointer to current directory name - &si, // pointer to STARTUPINFO - &pi // pointer to PROCESS_INFORMATION - ); - } - EndDialog( hDlg, FALSE ); - break; - case IDC_BUTTON_REPORT: - GotoURL( "http://sourceforge.net/tracker/?func=add&group_id=37892&atid=421366" ); - break; - } - break; - - case WM_MEASUREITEM: - return g_pcdw->DoMeasureItem(lParam); - - case WM_DRAWITEM: - return g_pcdw->DoDrawItem(lParam); - } - - return FALSE; -} - -void crash() { - __try { - __asm xor ebx,ebx - __asm mov eax,dword ptr [ebx] -// __asm mov dword ptr [ebx],eax -// __asm lock add dword ptr cs:[00000000h], 12345678h - } __except(CrashHandler((EXCEPTION_POINTERS*)_exception_info())) { - } -} - -/* RageLog feeds us logs; keep track of recent logs in a circular - * buffer. This lets us include recent logs in the crash report. - * We don't want to include RageLog, since we don't want to pull - * in MFC. - * - * Since this is a static, preallocated region, even if it gets - * trampled we'll just print garbage, not crash due to an invalid - * pointer. */ -static const int BACKLOG_LINES = 10; -static char backlog[BACKLOG_LINES][1024]; -static int backlog_start=0, backlog_cnt=0; - -void CrashLog(const char *str) -{ - int len = strlen(str); - if(len > sizeof(backlog[backlog_start])-1) - len = sizeof(backlog[backlog_start])-1; - - strncpy(backlog[backlog_start], str, len); - backlog[backlog_start] [ len ] = 0; - - backlog_start++; - if(backlog_start > backlog_cnt) - backlog_cnt=backlog_start; - backlog_start %= BACKLOG_LINES; -} - -static void ReportCrashLog(HWND hwnd, HANDLE hFile) -{ - Report(NULL, hFile, "Partial log:"); - - int i; - for(i = backlog_start; i < BACKLOG_LINES && i < backlog_cnt; ++i) - Report(hwnd, hFile, "%s", backlog[i]); - for(i = 0; i < backlog_start && i < backlog_cnt; ++i) - Report(hwnd, hFile, "%s", backlog[i]); -} - -/* Same idea, except this is for data that we *always* want to print - * in the crash log, even if it was printed when we started. */ -static const int STATICLOG_SIZE = 1024*32; -static char staticlog[STATICLOG_SIZE]=""; -static char *staticlog_ptr=staticlog, *staticlog_end=staticlog+STATICLOG_SIZE; -void StaticLog(const char *str) -{ - if(!staticlog_ptr) - return; - - int len = strlen(str)+2; /* +newline +null */ - if(staticlog_ptr+len >= staticlog_end) - { - const char *txt = "\nStaticlog limit reached\n"; - char *max_ptr = staticlog_end-strlen(txt)-1; - if(staticlog_ptr > max_ptr) - staticlog_ptr = max_ptr; - - strcpy(staticlog_ptr, txt); - staticlog_ptr=NULL; /* stop */ - return; - } - - strcpy(staticlog_ptr, str); - - staticlog_ptr[len-2] = '\n'; - staticlog_ptr[len-1] = 0; - /* Advance to sit on the NULL, so the terminator will be overwritten - * on the next log. */ - staticlog_ptr += len-1; -} - -static void ReportStaticLog(HWND hwnd, HANDLE hFile) -{ - Report(NULL, hFile, "Static log:"); - Report(hwnd, hFile, "%s", staticlog); -} - diff --git a/stepmania/src/Crash.h b/stepmania/src/Crash.h deleted file mode 100644 index c8d89a6d5b..0000000000 --- a/stepmania/src/Crash.h +++ /dev/null @@ -1,62 +0,0 @@ -// from VirtualDub -// Copyright (C) 1998-2001 Avery Lee -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -#ifndef f_CRASH_H -#define f_CRASH_H - -#ifdef f_CRASH_CPP -#define EXTERN -#else -#define EXTERN extern -#endif - -struct VirtualDubCheckpoint { - const char *file; - int line; - const char *message; - - inline void set(const char *f, int l, const char *m=NULL) { file=f; line=l; message=m; } -}; - -#define CHECKPOINT_COUNT (16) - -struct VirtualDubThreadState { - const char *pszThreadName; - unsigned long dwThreadId; - void * hThread; - - VirtualDubCheckpoint cp[CHECKPOINT_COUNT]; - int nNextCP; -}; - -EXTERN __declspec(thread) VirtualDubThreadState g_PerThreadState; - -#define VDCHECKPOINT (g_PerThreadState.cp[g_PerThreadState.nNextCP++&(CHECKPOINT_COUNT-1)].set(__FILE__, __LINE__)) -#define VDCHECKPOINT_M(m) (g_PerThreadState.cp[g_PerThreadState.nNextCP++&(CHECKPOINT_COUNT-1)].set(__FILE__, __LINE__, (m))) - -void VirtualDubInitializeThread(const char *pszName); -void VirtualDubDeinitializeThread(); -extern long __stdcall CrashHandler(struct _EXCEPTION_POINTERS *ExceptionInfo); - -void CrashLog(const char *str); -void StaticLog(const char *str); - -/* Exactly as advertised. (This will bring up the crash handler even - * in the debugger.) */ -void crash(); - -#endif diff --git a/stepmania/src/CrashList.h b/stepmania/src/CrashList.h deleted file mode 100644 index 91a0a4c21a..0000000000 --- a/stepmania/src/CrashList.h +++ /dev/null @@ -1,174 +0,0 @@ -// from VirtualDub -// Copyright (C) 1998-2001 Avery Lee, All Rights Reserved. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -// Don't use this. It's only here for the crash code. -#ifndef f_DISASM_LIST_H -#define f_DISASM_LIST_H - -class ListNode { -public: - ListNode *next, *prev; - - void Remove() { - next->prev = prev; - prev->next = next; -#ifdef _DEBUG - prev = next = 0; -#endif - } - - void InsertBefore(ListNode *node) { - next = node->next; - prev = node; - if (node->next) node->next->prev = this; - node->next = this; - } - - ListNode *NextFromHead() const { - return prev; - } -}; - -class List { -private: -public: - ListNode head, tail; - - // <--- next prev ---> - // - // head <-> node <-> node <-> tail - - List() { - head.next = tail.prev = 0; - head.prev = &tail; - tail.next = &head; - } - - void AddTail(ListNode *node) { - node->InsertBefore(&tail); - } - - bool IsEmpty() const throw() { - return !head.prev->prev; - } - - ListNode *AtHead() const throw() { - return head.prev; - } - - ListNode *AtTail() const throw() { - return tail.next; - } -}; - -// Templated classes... templated classes good. - -template class List2; - -template -class ListNode2 : public ListNode { -friend List2; -public: - void InsertBefore(ListNode2 *node) { ListNode::InsertBefore(node); } - - void Remove() { ListNode::Remove(); } - T *NextFromHead() const { return (T *)ListNode::NextFromHead(); } - T *NextFromTail() const { return (T *)ListNode::NextFromTail(); } -}; - -template -class List2 : public List { -public: - List2() {} - - void AddHead(ListNode2 *node) { List::AddHead(node); } - void AddTail(ListNode2 *node) { List::AddTail(node); } - T *AtHead() const { return (T *)List::AtHead(); } - T *AtTail() const { return (T *)List::AtTail(); } - - // I must admit to being pampered by STL (end is different though!!) - - T *begin() const { return AtHead(); } - T *end() const { return AtTail(); } - - class iterator { - protected: - ListNode2 *node; - ListNode2 *next; - - public: - iterator() {} - iterator(const iterator& src) throw() : node(src.node), next(src.next) {} - - bool operator!() const throw() { return 0 == next; } - T *operator->() const throw() { return (T *)node; } - operator bool() const throw() { return 0 != next; } - T& operator *() const throw() { return *(T *)node; } - }; - - // fwit: forward iterator (SAFE if node disappears) - // rvit: reverse iterator (SAFE if node disappears) - - class fwit : public iterator { - public: - fwit() throw() {} - fwit(const fwit& src) throw() : iterator(src) {} - fwit(ListNode2 *start) throw() { - node = start; - next = start->NextFromHead(); - } - - const fwit& operator=(ListNode2 *start) throw() { - node = start; - next = start->NextFromHead(); - - return *this; - } - - fwit& operator++() throw() { - node = next; - next = node->NextFromHead(); - - return *this; - } - - const fwit& operator+=(int v) throw() { - while(next && v--) { - node = next; - next = node->NextFromHead(); - } - - return *this; - } - - fwit operator+(int v) const throw() { - fwit t(*this); - - t += v; - - return t; - } - - // This one's for my sanity. - - void operator++(int) throw() { - ++*this; - } - }; -}; - -#endif diff --git a/stepmania/src/Disasm.cpp b/stepmania/src/Disasm.cpp deleted file mode 100644 index 020a972492..0000000000 --- a/stepmania/src/Disasm.cpp +++ /dev/null @@ -1,816 +0,0 @@ -// from VirtualDub -// Copyright (C) 1998-2001 Avery Lee -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -#include -#include - -#include - -#include "resource.h" -#include "disasm.h" - -extern HINSTANCE g_hInstance; - -#define MAX_INSTRUCTIONS (1024) - -// WARNING: This is called from crash-time conditions! No malloc() or new!!! - -#define malloc not_allowed_here -#define new not_allowed_here - -// Also, we keep as much of our initialized data as possible as const. That way, -// it is in a write-locked code segment, which can't be overwritten. - -static char *VDDisasmMatchRule(VDDisassemblyContext *pContext, const unsigned char *source, const unsigned char *pattern, int pattern_len, int bytes, int *sp, char *hp, const unsigned char *&source_end); - -char *strtack(char *s, const char *t) { - while(*s = *t) - ++s, ++t; - - return s; -} - -// 1-15 are static lookups -static const char kTarget_r32 = 1; -static const char kTarget_r16 = 2; -static const char kTarget_r8 = 3; -static const char kTarget_rm = 4; -static const char kTarget_rx = 5; -static const char kTarget_rc = 6; -static const char kTarget_rd = 7; -static const char kTarget_rs = 8; -static const char kTarget_rf = 9; - -// 16-31 are dynamic translations -static const char kTarget_r1632 = 16; -static const char kTarget_rmx = 17; -static const char kTarget_x = 18; -static const char kTarget_hx = 19; -static const char kTarget_lx = 20; -static const char kTarget_s = 21; -static const char kTarget_o = 22; -static const char kTarget_ho = 23; -static const char kTarget_lo = 24; -static const char kTarget_a = 25; -static const char kTarget_ha = 26; -static const char kTarget_la = 27; - -static const char kTarget_ap = (char)224; -static const char kTarget_p_cs = (char)225; -static const char kTarget_p_ss = (char)226; -static const char kTarget_p_ds = (char)227; -static const char kTarget_p_es = (char)228; -static const char kTarget_p_fs = (char)229; -static const char kTarget_p_gs = (char)230; -static const char kTarget_p_66 = (char)231; -static const char kTarget_p_67 = (char)232; -static const char kTarget_p_F2 = (char)233; -static const char kTarget_p_F3 = (char)234; - -static void *VDDisasmDecompress(void *_dst, const unsigned char *src, int src_len) { - const unsigned char *src_limit = src + src_len; - unsigned char *dst = (unsigned char *)_dst; - - // read ruleset count - int rulesets = *src++; - unsigned char **prstab = (unsigned char **)dst; - - dst += sizeof(unsigned char *) * (rulesets + 1); - - // decompress rulesets sequentially - for(int rs=0; rs> 6; - - int prematch = (packctl & 7) * 2; - int postmatch = ((packctl>>3) & 7) * 2; - int literal = (*src++ - 1) * 2; - - *dst++ = literal + prematch + postmatch; - - const unsigned char *pattern_start = dst; - - for(cnt=0; cnt0; --cnt) { - pattern_cache[cnt][0] = pattern_cache[cnt-1][0]; - pattern_cache[cnt][1] = pattern_cache[cnt-1][1]; - } - - pattern_cache[0][0] = pattern_start; - pattern_cache[0][1] = dst; - - // read pack control byte and copy prematch-literal-postmatch for result - - packctl = *src++; - packsrc = packctl >> 6; - - prematch = (packctl & 7); - postmatch = ((packctl>>3) & 7); - literal = (*src++ - 1); - - *dst++ = prematch + postmatch + literal; - - const unsigned char *result_start = dst; - - for(cnt=0; cnt0; --cnt) { - result_cache[cnt][0] = result_cache[cnt-1][0]; - result_cache[cnt][1] = result_cache[cnt-1][1]; - } - - result_cache[0][0] = result_start; - result_cache[0][1] = dst; - } - - src += 2; - - *dst++ = 0; - *dst++ = 0; - } - - prstab[0] = prstab[rulesets]; - - return dst; -} - -static long VDDisasmPack32(const int *src) { - return src[0] + (src[1]<<8) + (src[2]<<16) + (src[3]<<24); -} - -static void VDDisasmExpandRule(VDDisassemblyContext *pContext, char *s, const unsigned char *result, const int *sp_base, const unsigned char *source) { - static const char *const reg32[8]={"eax","ecx","edx","ebx","esp","ebp","esi","edi"}; - static const char *const reg16[8]={"ax","cx","dx","bx","sp","bp","si","di"}; - static const char *const reg8[8]={"al","cl","dl","bl","ah","ch","dh","bh"}; - static const char *const regmmx[8]={"mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7"}; - static const char *const regxmm[8]={"xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7"}; - static const char *const regcrn[8]={"cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"}; - static const char *const regdrn[8]={"dr0","dr1","dr2","dr3","dr4","dr5","dr6","dr7"}; - static const char *const regseg[8]={"es","cs","ss","ds","fs","gs","?6s","?7s"}; - static const char *const regf[8]={"st(0)","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)"}; - - static const char *const *const sStaticLabels[]={ - reg32, - reg16, - reg8, - regmmx, - regxmm, - regcrn, - regdrn, - regseg, - regf - }; - - const unsigned char *result_limit = result + result[0]+1; - - ++result; - - while(result < result_limit) { - char c = *result++; - - if ((unsigned char)(c&0x7f) < 32) { - if (c & 0x80) { - c &= 0x7f; - *s++ = ' '; - } - - static const unsigned char static_bitfields[8]={ - 0x80, 0x30, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - unsigned char control_byte = (unsigned char)*result++; - unsigned char bitfield = static_bitfields[control_byte >> 5]; - - if (!bitfield) - bitfield = (unsigned char)*result++; - - int bf_start = bitfield & 15; - int bf_siz = bitfield>>4; - const char *arg_s = (const char *)sp_base[c-1]; - int arg = (sp_base[c-1] >> bf_start) & ((1<bSizeOverride); - break; - case kTarget_rmx: - s = strtack(s, (pContext->bSizeOverride ? regxmm : regmmx)[arg]); - break; - case kTarget_lx: - symoffset = VDDisasmPack32(sp_base + c - 1); - s += sprintf(s, "%08lx", symoffset); - break; - case kTarget_hx: - s += sprintf(s, "%02x%02x" - , (unsigned char)sp_base[c] - , (unsigned char)sp_base[c-1] - ); - break; - case kTarget_x: - s += sprintf(s, "%02x", arg); - break; - case kTarget_lo: - symoffset = VDDisasmPack32(sp_base + c - 1); - s += sprintf(s, "%c%02lx", symoffset<0 ? '-' : '+', abs(symoffset)); - break; - case kTarget_ho: - { - short x = ((unsigned char)sp_base[c ] << 8) - + (unsigned char)sp_base[c-1]; - - s += sprintf(s, "%c%02lx", x<0 ? '-' : '+', abs(x)); - } - break; - case kTarget_o: - s += sprintf(s, "%c%02x", arg&0x80?'-':'+', abs((signed char)arg)); - break; - case kTarget_la: - symoffset = (long)source + VDDisasmPack32(sp_base + c - 1) + pContext->physToVirtOffset; - s += sprintf(s, "%08lx", symoffset); - break; - case kTarget_ha: - symoffset = (long)source + (signed short)(sp_base[c-1] + (sp_base[c]<<8)) + pContext->physToVirtOffset; - s += sprintf(s, "%08lx", symoffset); - break; - case kTarget_a: - symoffset = (long)source + (signed char)arg + pContext->physToVirtOffset; - s += sprintf(s, "%08lx", symoffset); - break; - case kTarget_s: - if(arg_s < (const char *) 0x100) { - /* Oops--somehow we got a character value on the stack where - * we expected a string. This is probably an error in the - * disassembly rules. */ - s = strtack(s, "(DISASSEMBLY ERROR: STRING EXPECTED)"); - break; - } - s = strtack(s, arg_s); - break; - } - - if (symoffset && pContext->pSymLookup) { - char buf[1024]; - - symoffset = pContext->pSymLookup(pContext, (unsigned long)symoffset, buf, sizeof buf - 16); - - if (symoffset >= 0) { - int l = strlen(buf); - int l2 = s - s_base; - - if (symoffset) - l += sprintf(buf+l, "+%02x", symoffset); - - memmove(s_base+l+2, s_base, l2); - memcpy(s_base, buf, l); - s_base[l] = ' '; - s_base[l+1] = '('; - s = s_base + l+l2+2; - *s++ = ')'; - } - } - } - } else if ((unsigned char)c >= 0xe0) { - switch(c) { - case kTarget_ap: - if (pContext->pszSegmentOverride) { - s = strtack(s, pContext->pszSegmentOverride); - *s++ = ':'; - } - break; - case kTarget_p_cs: pContext->pszSegmentOverride = regseg[1]; break; - case kTarget_p_ss: pContext->pszSegmentOverride = regseg[2]; break; - case kTarget_p_ds: pContext->pszSegmentOverride = regseg[3]; break; - case kTarget_p_es: pContext->pszSegmentOverride = regseg[0]; break; - case kTarget_p_fs: pContext->pszSegmentOverride = regseg[4]; break; - case kTarget_p_gs: pContext->pszSegmentOverride = regseg[5]; break; - case kTarget_p_66: pContext->bSizeOverride = true; break; - case kTarget_p_67: pContext->bAddressOverride = true; break; - case kTarget_p_F2: pContext->bRepnePrefix = true; break; - case kTarget_p_F3: pContext->bRepePrefix = true; break; - } - } else - *s++ = c; - } - - *s = 0; -} - -static char *VDDisasmApplyRuleset(VDDisassemblyContext *pContext, const unsigned char *rs, int *sp, char *hp, const unsigned char *source, int bytes, const unsigned char *&source_end) { - char *hpr; - - while(rs[0] || rs[1]) { - const unsigned char *src_end; - const unsigned char *result = rs + rs[0] + 1; - const unsigned char *match_next = result + result[0] + 1; - - hpr = VDDisasmMatchRule(pContext, source, rs+1, rs[0]>>1, bytes, sp, hp, src_end); - - if (hpr) { - VDDisasmExpandRule(pContext, hpr, result, sp, src_end); - - source_end = src_end; - return hpr; - } - - rs = match_next; - } - - return NULL; -} - -static char *VDDisasmMatchRule(VDDisassemblyContext *pContext, const unsigned char *source, const unsigned char *pattern, int pattern_len, int bytes, int *sp, char *hp, const unsigned char *&source_end) { - while(pattern_len) { - if (!pattern[1] && pattern[0]) { - if (pattern[0] & 0x80) { - int count = pattern[0] & 0x3f; - - if (pattern[0] & 0x40) { - --source; - ++bytes; - } - - const unsigned char *src_end; - - hp = VDDisasmApplyRuleset(pContext, pContext->pRuleSystem[count+1], sp, hp, source, bytes, src_end); - - if (!hp) - return NULL; - - *sp++ = *source; - *sp++ = (int)hp; - - while(*hp++); - - bytes -= (src_end - source)-1; - source = src_end; - } else if (pattern[0] < 16) { - if (pattern[0] > bytes) - return NULL; - - for(int i=0; ibSizeOverride) return NULL; break; - case 17: if (!pContext->bAddressOverride) return NULL; break; - case 18: if (!pContext->bRepnePrefix) return NULL; break; - case 19: if (!pContext->bRepePrefix) return NULL; break; - case 20: if (pContext->pszSegmentOverride) return NULL; break; - } - } - } else { - if (!bytes) - return NULL; - - unsigned char b = *source++; - - if ((b & pattern[1]) != pattern[0]) - return NULL; - - *sp++ = b; - } - pattern += 2; - --bytes; - --pattern_len; - } - - if (!pattern_len) { - source_end = source; - return hp; - } - - return NULL; -} - -char *VDDisassemble(VDDisassemblyContext *pvdc, const unsigned char *source, int bytes, int& count) { - const unsigned char *src2 = source; - const unsigned char *src_end; - char *s; - - pvdc->bAddressOverride = false; - pvdc->bSizeOverride = false; - pvdc->bRepePrefix = false; - pvdc->bRepnePrefix = false; - pvdc->pszSegmentOverride = NULL; - - do { - s = VDDisasmApplyRuleset(pvdc, pvdc->pRuleSystem[0], pvdc->stack, pvdc->heap, src2, bytes, src_end); - - bytes -= (src_end - src2); - src2 = src_end; - } while(!*s && bytes); - - if (!*s) - return NULL; - - count = src2 - source; - - char *dst = s, *dst_base; - - while(*dst++) - ; - - dst_base = dst; - - char *t = s; - while(*t && *t != ' ') - ++t; - - if (*t) - *t++ = 0; - - sprintf(dst, "%-6s %s", s, t); - - return dst_base; -} - -bool VDDisasmInit(VDDisassemblyContext *pvdc, const char *pszFilename) { - HANDLE h; - - pvdc->pRawBlock = NULL; - pvdc->pExtraData = NULL; - - h = CreateFile(pszFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (h == INVALID_HANDLE_VALUE) - return false; - - DWORD dwSize = GetFileSize(h, NULL), dwActual; - - pvdc->pRawBlock = VirtualAlloc(NULL, dwSize + 65536, MEM_COMMIT, PAGE_READWRITE); - - if (!pvdc->pRawBlock || !ReadFile(h, pvdc->pRawBlock, dwSize, &dwActual, NULL) || dwActual != dwSize) { - CloseHandle(h); - return false; - } - - CloseHandle(h); - - const char *src = (const char *)pvdc->pRawBlock; - - if (src[0] != '[' || src[3] != '|') - return false; - - if (memcmp((char *)src + 6, "] StepMania disasm module", 25)) - return false; - - // Check version number - - int write_version = (src[1]-'0')*10 + (src[2] - '0'); - int compat_version = (src[4]-'0')*10 + (src[5] - '0'); - - if (compat_version > 1) - return false; // resource is too new for us to load - - - long packSize = *(long *)((char *)pvdc->pRawBlock + 64); - long depackSize = *(long *)((char *)pvdc->pRawBlock + 68); - - pvdc->pRuleSystem = (const unsigned char **)((char *)pvdc->pRawBlock + dwSize); - pvdc->stack = (int *)((char *)pvdc->pRuleSystem + depackSize); - pvdc->heap = (char *)(pvdc->stack + 32); - - pvdc->cbExtraData = dwSize - (packSize+72); - pvdc->pExtraData = NULL; - - if (pvdc->cbExtraData) - pvdc->pExtraData = (char *)pvdc->pRawBlock + 72 + packSize; - - VDDisasmDecompress(pvdc->pRuleSystem, (unsigned char *)pvdc->pRawBlock + 72, packSize); - - return true; -} - -void VDDisasmDeinit(VDDisassemblyContext *pvdc) { - if (pvdc->pRawBlock) { - VirtualFree(pvdc->pRawBlock, 0, MEM_RELEASE); - pvdc->pRawBlock = NULL; - } -} - -/////////////////////////////////////////////////////////////////////////////// - -static void SpliceProgramPath(char *buf, int bufsiz, const char *fn) { - char tbuf[MAX_PATH]; - char *pszFile; - - GetModuleFileName(NULL, tbuf, sizeof tbuf); - GetFullPathName(tbuf, bufsiz, buf, &pszFile); - strcpy(pszFile, fn); -} - -CodeDisassemblyWindow::CodeDisassemblyWindow(void *_code, long _length, void *_rbaseptr, void *_abaseptr) -: code(_code) -, rbase(_rbaseptr) -, abase(_abaseptr) -, length(_length) -, pFault(0) -{ -// lbents = new lbent[MAX_INSTRUCTIONS]; - - char buf[MAX_PATH]; - - vdc.pRuleSystem = NULL; - vdc.pSymLookup = NULL; - vdc.physToVirtOffset = -(long)_rbaseptr; - - SpliceProgramPath(buf, sizeof buf, "ia32.vdi"); - if (!VDDisasmInit(&vdc, buf)) { - SpliceProgramPath(buf, sizeof buf, "StepMania.vdi"); - if (!VDDisasmInit(&vdc, buf)) { - SpliceProgramPath(buf, sizeof buf, "StepMani.vdi"); - VDDisasmInit(&vdc, buf); - } - } - - lbents = (lbent *)VirtualAlloc(NULL, sizeof(lbent)*MAX_INSTRUCTIONS, MEM_COMMIT, PAGE_READWRITE); - - hFontMono = CreateFont( - 10, // nHeight - 0, // nWidth - 0, // nEscapement - 0, // nOrientation - FW_DONTCARE, // fnWeight - FALSE, // fdwItalic - FALSE, // fdwUnderline - FALSE, // fdwStrikeOut - ANSI_CHARSET, // fdwCharSet - OUT_DEFAULT_PRECIS, // fdwOutputPrecision - CLIP_DEFAULT_PRECIS, // fdwClipPrecision - DEFAULT_QUALITY, // fdwQuality - DEFAULT_PITCH | FF_DONTCARE, // fdwPitchAndFamily - "Lucida Console" - ); - - if (!hFontMono) hFontMono = (HFONT)GetStockObject(ANSI_FIXED_FONT); - num_ents = 0; -} - -CodeDisassemblyWindow::~CodeDisassemblyWindow() { - - VDDisasmDeinit(&vdc); - - if (hFontMono) DeleteObject(hFontMono); - - if (lbents) - VirtualFree(lbents, 0, MEM_RELEASE); -} - -///////////////////////////////////////////////////////////////////////// - - -void CodeDisassemblyWindow::parse() { - if (!vdc.pRuleSystem) - return; - - unsigned char *ip = (unsigned char *)code; - unsigned char *ipend = ip + length; - lbent *ipd = lbents; - int cnt=0; - - if (!ipd) { - num_ents = 0; - return; - } - - while(ip < ipend && cnt++ip = ip; - ipd->len = count; - - ip += count; - - ++ipd; - } - - num_ents = ipd-lbents; -} -/* -BOOL CodeDisassemblyWindow::post(HWND hWnd) { - if (!lbents) return FALSE; - - DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_DISASM), hWnd, CodeDisassemblyWindow::DlgProc, (LPARAM)this); - - return TRUE; -} -*/ -long CodeDisassemblyWindow::getInstruction(char *buf, long val) { - lbent *ipd; - unsigned char *ip; - - if ((val >> 16) >= num_ents) - return 0; - - ipd = &lbents[val >> 16]; - ip = ipd->ip; - - int count; - - unsigned virtAddr = (unsigned)ip - (unsigned)code + (unsigned)abase; - int subIndex = val & 0xffff; - int left = ipd->len - subIndex * 7; - - buf += sprintf(buf, subIndex ? " " : "%08lx: ", virtAddr); - - for(int i=0; i<7; ++i) { - if (--left >= 0) { - buf += wsprintf(buf, "%02x", (unsigned char)ip[subIndex*7+i]); - } else { - *buf++ = ' '; - *buf++ = ' '; - } - } - - *buf++ = ' '; - *buf++ = ' '; - *buf = 0; - - if (!subIndex) { - strcpy(buf, VDDisassemble(&vdc, ip, ipd->len, count)); - - if (virtAddr == (unsigned)pFault) - strcat(buf, " <-- FAULT"); - } - - ++subIndex; - - if (subIndex >= (ipd->len+6) / 7) - return (val&0xffff0000) + 0x10000; - else - return val+1; -} - -void CodeDisassemblyWindow::DoInitListbox(HWND hwndList) { -// SendMessage(hwndList, LB_SETCOUNT, num_ents, 0); - - for(int i=0; iCtlType != ODT_LISTBOX) return FALSE; - - lbent *pent = &lbents[pinfo->itemID]; - - pinfo->itemHeight = 11 * ((pent->len + 6)/7); - return TRUE; -} - -BOOL CodeDisassemblyWindow::DoDrawItem(LPARAM lParam) { - LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam; - lbent *ipd; - - if (lpdis->CtlType != ODT_LISTBOX) return FALSE; - if (!(lpdis->itemAction & ODA_DRAWENTIRE)) return FALSE; - if (lpdis->itemID < 0) return FALSE; - -// ipd = (lbent *)lpdis->itemData; - ipd = &lbents[lpdis->itemID]; - - if (ipd->ip) { - SetBkMode(lpdis->hDC, TRANSPARENT); - SetTextColor(lpdis->hDC, RGB(0x00,0x00,0x00)); - - if (ipd->ip - (unsigned char *)code + (unsigned char *)abase == pFault) { - HBRUSH hbr = CreateSolidBrush(RGB(0xff,0xa0,0x60)); - if (hbr) { - FillRect(lpdis->hDC, &lpdis->rcItem, hbr); - DeleteObject(hbr); - } - } - - int count; - char *dst = buf; - const unsigned char *src = (const unsigned char *)ipd->ip; - int i, left = ipd->len; - - dst += sprintf(dst, "%08lx: ", (long)ipd->ip + vdc.physToVirtOffset); - - for(i=0; i<7; ++i) - if (--left>=0) { - dst += sprintf(dst, "%02x", *src++); - } else { - dst[0] = dst[1] = ' '; - dst += 2; - } - - *dst++ = ' '; - *dst++ = ' '; - - strcpy(dst, VDDisassemble(&vdc, ipd->ip, ipd->len, count)); - - int x = lpdis->rcItem.left; - int y = lpdis->rcItem.top; - - ExtTextOut(lpdis->hDC, x, y, 0, NULL, buf, strlen(buf), NULL); - - while(left>0) { - dst = buf+sprintf(buf, " "); - for(i=0; i<7; ++i) { - if (--left>=0) { - dst += sprintf(dst, "%02x", *src++); - } - } - - y += 11; - ExtTextOut(lpdis->hDC, x, y, 0, NULL, buf, dst-buf, NULL); - } - } - - return TRUE; -} - -BOOL CALLBACK CodeDisassemblyWindow::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - CodeDisassemblyWindow *thisPtr = (CodeDisassemblyWindow *)GetWindowLong(hDlg, DWL_USER); - - switch(msg) { - - case WM_INITDIALOG: - SetWindowLong(hDlg, DWL_USER, lParam); - thisPtr = (CodeDisassemblyWindow *)lParam; - - { - HWND hwndList = GetDlgItem(hDlg, IDC_ASMBOX); - - thisPtr->DoInitListbox(hwndList); - } - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDCANCEL: case IDOK: - EndDialog(hDlg, FALSE); - return TRUE; - } - break; - - case WM_MEASUREITEM: - return thisPtr->DoMeasureItem(lParam); - - case WM_DRAWITEM: - return thisPtr->DoDrawItem(lParam); - } - - return FALSE; -} diff --git a/stepmania/src/Disasm.h b/stepmania/src/Disasm.h deleted file mode 100644 index 2a26996919..0000000000 --- a/stepmania/src/Disasm.h +++ /dev/null @@ -1,88 +0,0 @@ -// from VirtualDub -// Copyright (C) 1998-2001 Avery Lee -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -#ifndef f_DISASM_H -#define f_DISASM_H - -#include - -struct VDDisassemblyContext { - const unsigned char **pRuleSystem; - long (*pSymLookup)(VDDisassemblyContext *pctx, unsigned long virtAddr, char *buf, int buf_len); - - bool bSizeOverride; // 66 - bool bAddressOverride; // 67 - bool bRepnePrefix; // F2 - bool bRepePrefix; // F3 - const char *pszSegmentOverride; - - long physToVirtOffset; - - void *pRawBlock; - char *heap; - char *heap_limit; - int *stack; - - void *pExtraData; - int cbExtraData; -}; - - -bool VDDisasmInit(VDDisassemblyContext *, const char *, const char *); -void VDDisasmDeinit(VDDisassemblyContext *); -char *VDDisassemble(VDDisassemblyContext *pvdc, const unsigned char *source, int bytes, int& count); - - - -class CodeDisassemblyWindow { -private: - static BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); - - void *code, *rbase, *abase; - long length; - void *pFault; - - class lbent { - public: - unsigned char *ip; - int len; - } *lbents; - int num_ents; - - HFONT hFontMono; - - char buf[256]; - -public: - VDDisassemblyContext vdc; - - CodeDisassemblyWindow(void *code, long, void *, void *); - ~CodeDisassemblyWindow(); - - void DoInitListbox(HWND hwndList); - BOOL DoMeasureItem(LPARAM lParam); - BOOL DoDrawItem(LPARAM lParam); - void parse(); - BOOL post(HWND); - long getInstruction(char *buf, long val); - - void setFaultAddress(void *_pFault) { - pFault = _pFault; - } -}; - -#endif diff --git a/stepmania/src/Tls.cpp b/stepmania/src/Tls.cpp deleted file mode 100644 index 1c71ea741a..0000000000 --- a/stepmania/src/Tls.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// from VirtualDub -// Copyright (C) 1998-2001 Avery Lee -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -#include "stdafx.h" -#include "tls.h" -#include "crash.h" - -__declspec(thread) VirtualDubTLSData g_tlsdata; - -void InitThreadData(const char *pszName) { - VirtualDubTLSData *pData = &g_tlsdata; - - __asm { - mov eax,pData - mov dword ptr fs:[14h],eax - } - - VirtualDubInitializeThread(pszName); -} - -void DeinitThreadData() { - VirtualDubDeinitializeThread(); -} - diff --git a/stepmania/src/Tls.h b/stepmania/src/Tls.h deleted file mode 100644 index ff14f4cfa6..0000000000 --- a/stepmania/src/Tls.h +++ /dev/null @@ -1,31 +0,0 @@ -// from VirtualDub -// Copyright (C) 1998-2001 Avery Lee -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -#ifndef f_VIRTUALDUB_TLS_H -#define f_VIRTUALDUB_TLS_H - -struct VirtualDubTLSData { - int tmp[16]; - void *ESPsave; -}; - -extern __declspec(thread) VirtualDubTLSData g_tlsdata; - -void InitThreadData(const char *pszName); -void DeinitThreadData(); - -#endif