From 3c65a4fc284639e4a6dcc6dc65fe9190a3cbb999 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 21 Aug 2024 17:44:42 +1000 Subject: [PATCH] Dynamically load all imagehlp functions --- Makefile | 2 +- misc/windows/min-imagehlp.h | 41 +++++++++++++++++++++++++++++++++++++ readme.md | 10 ++++----- src/ClassiCube.vcxproj | 16 +++++++-------- src/Commands.c | 8 ++++---- src/Game.c | 7 ++++--- src/Logger.c | 36 +++++++------------------------- src/Platform_Windows.c | 5 +++-- src/Window_Win.c | 6 +++--- 9 files changed, 76 insertions(+), 55 deletions(-) create mode 100644 misc/windows/min-imagehlp.h diff --git a/Makefile b/Makefile index 9d0f59640..b0d57ee2d 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ ifeq ($(PLAT),mingw) OEXT = .exe CFLAGS += -DUNICODE LDFLAGS = -g - LIBS = -mwindows -lwinmm -limagehlp + LIBS = -mwindows -lwinmm BUILD_DIR = build-win endif diff --git a/misc/windows/min-imagehlp.h b/misc/windows/min-imagehlp.h new file mode 100644 index 000000000..d32c02df0 --- /dev/null +++ b/misc/windows/min-imagehlp.h @@ -0,0 +1,41 @@ +static DWORD_PTR (WINAPI *_SymGetModuleBase)(HANDLE process, DWORD_PTR addr); +static PVOID (WINAPI *_SymFunctionTableAccess)(HANDLE process, DWORD_PTR addr); +static BOOL (WINAPI *_SymInitialize)(HANDLE process, PCSTR userSearchPath, BOOL fInvadeProcess); + +static BOOL (WINAPI *_SymGetSymFromAddr)(HANDLE process, DWORD_PTR addr, DWORD_PTR* displacement, IMAGEHLP_SYMBOL* sym); +static BOOL (WINAPI *_SymGetModuleInfo) (HANDLE process, DWORD_PTR addr, IMAGEHLP_MODULE* module); +static BOOL (WINAPI *_SymGetLineFromAddr)(HANDLE hProcess, DWORD_PTR addr, DWORD* displacement, IMAGEHLP_LINE* line); /* displacement is intentionally DWORD */ + +static BOOL (WINAPI *_EnumerateLoadedModules)(HANDLE process, PENUMLOADED_MODULES_CALLBACK callback, PVOID userContext); + +static BOOL (WINAPI *_StackWalk)(DWORD machineType, HANDLE process, HANDLE thread, STACKFRAME* stackFrame, PVOID contextRecord, + PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE TranslateAddress); + +static void ImageHlp_LoadDynamicFuncs(void) { + static const struct DynamicLibSym funcs[] = { + #ifdef _IMAGEHLP64 + { "EnumerateLoadedModules64", (void**)&_EnumerateLoadedModules}, + { "SymFunctionTableAccess64", (void**)&_SymFunctionTableAccess}, + { "SymInitialize", (void**)&_SymInitialize }, + { "SymGetModuleBase64", (void**)&_SymGetModuleBase }, + { "SymGetModuleInfo64", (void**)&_SymGetModuleInfo }, + { "SymGetLineFromAddr64", (void**)&_SymGetLineFromAddr }, + { "SymGetSymFromAddr64", (void**)&_SymGetSymFromAddr }, + { "StackWalk64", (void**)&_StackWalk }, + #else + { "EnumerateLoadedModules", (void**)&_EnumerateLoadedModules }, + { "SymFunctionTableAccess", (void**)&_SymFunctionTableAccess }, + { "SymInitialize", (void**)&_SymInitialize }, + { "SymGetModuleBase", (void**)&_SymGetModuleBase }, + { "SymGetModuleInfo", (void**)&_SymGetModuleInfo }, + { "SymGetLineFromAddr", (void**)&_SymGetLineFromAddr }, + { "SymGetSymFromAddr", (void**)&_SymGetSymFromAddr }, + { "StackWalk", (void**)&_StackWalk }, + #endif + }; + + static const cc_string imagehlp = String_FromConst("IMAGEHLP.DLL"); + void* lib; + DynamicLib_LoadAll(&imagehlp, funcs, Array_Elems(funcs), &lib); +} \ No newline at end of file diff --git a/readme.md b/readme.md index b1f5c10e8..8b4b7645b 100644 --- a/readme.md +++ b/readme.md @@ -112,14 +112,14 @@ I am assuming you used the installer from https://sourceforge.net/projects/mingw 1. Install MinGW-W64 2. Use either *Run Terminal* from Start Menu or run *mingw-w64.bat* in the installation folder 3. Navigate to the directory with ClassiCube's source code -4. Enter `gcc -fno-math-errno *.c -o ClassiCube.exe -mwindows -lwinmm -limagehlp` +4. Enter `gcc -fno-math-errno *.c -o ClassiCube.exe -mwindows -lwinmm` ##### Using MinGW I am assuming you used the installer from https://osdn.net/projects/mingw/ 1. Install MinGW. You need mingw32-base-bin and msys-base-bin packages. 2. Run *msys.bat* in the *C:\MinGW\msys\1.0* folder. 2. Navigate to the directory with ClassiCube's source code -4. Enter `gcc -fno-math-errno *.c -o ClassiCube.exe -mwindows -lwinmm -limagehlp` +4. Enter `gcc -fno-math-errno *.c -o ClassiCube.exe -mwindows -lwinmm` ##### Using TCC (Tiny C Compiler) Setting up TCC: @@ -131,7 +131,7 @@ Setting up TCC: Compiling with TCC: 1. Navigate to the directory with ClassiCube's source code 2. In `ExtMath.c`, change `fabsf` to `fabs` and `sqrtf` to `sqrt` -3. Enter `tcc.exe -o ClassiCube.exe *.c -lwinmm -limagehlp -lgdi32 -luser32 -lcomdlg32 -lshell32`
+3. Enter `tcc.exe -o ClassiCube.exe *.c -lwinmm -lgdi32 -luser32 -lcomdlg32 -lshell32`
(Note: You may need to specify the full path to `tcc.exe` instead of just `tcc.exe`) ## Compiling - Linux @@ -144,11 +144,11 @@ Install appropriate libs as required. For ubuntu these are: libx11-dev, libxi-de ##### Cross compiling for Windows (32 bit): -```i686-w64-mingw32-gcc -fno-math-errno src/*.c -o ClassiCube.exe -mwindows -lwinmm -limagehlp``` +```i686-w64-mingw32-gcc -fno-math-errno src/*.c -o ClassiCube.exe -mwindows -lwinmm``` ##### Cross compiling for Windows (64 bit): -```x86_64-w64-mingw32-gcc -fno-math-errno src/*.c -o ClassiCube.exe -mwindows -lwinmm -limagehlp``` +```x86_64-w64-mingw32-gcc -fno-math-errno src/*.c -o ClassiCube.exe -mwindows -lwinmm``` ##### Raspberry Pi Although the regular linux compiliation flags will work fine, to take full advantage of the hardware: diff --git a/src/ClassiCube.vcxproj b/src/ClassiCube.vcxproj index 79fa87cd5..384376b88 100644 --- a/src/ClassiCube.vcxproj +++ b/src/ClassiCube.vcxproj @@ -188,7 +188,7 @@ true 5.02 main - opengl32.lib;ws2_32.lib;Wininet.lib;dbghelp.lib;Winmm.lib;crypt32.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies) + opengl32.lib;Winmm.lib;crypt32.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies) @@ -208,7 +208,7 @@ Windows true main - opengl32.lib;ws2_32.lib;Wininet.lib;crypt32.lib;dbghelp.lib;Winmm.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies) + opengl32.lib;Winmm.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies) @@ -230,7 +230,7 @@ true 5.02 main - opengl32.lib;ws2_32.lib;Wininet.lib;dbghelp.lib;Winmm.lib;crypt32.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies) + opengl32.lib;Winmm.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies) @@ -252,7 +252,7 @@ true 5.02 main - opengl32.lib;ws2_32.lib;Wininet.lib;dbghelp.lib;Winmm.lib;crypt32.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies) + opengl32.lib;Winmm.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies) @@ -281,7 +281,7 @@ 5.02 Default main - opengl32.lib;ws2_32.lib;Wininet.lib;crypt32.lib;dbghelp.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies) + opengl32.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies) @@ -308,7 +308,7 @@ true true main - opengl32.lib;ws2_32.lib;Wininet.lib;crypt32.lib;dbghelp.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies) + opengl32.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies) @@ -338,7 +338,7 @@ 5.02 Default main - opengl32.lib;ws2_32.lib;Wininet.lib;crypt32.lib;dbghelp.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies) + opengl32.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies) @@ -368,7 +368,7 @@ 5.02 Default main - opengl32.lib;ws2_32.lib;Wininet.lib;crypt32.lib;dbghelp.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies) + opengl32.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies) diff --git a/src/Commands.c b/src/Commands.c index 9375d810e..dc8903a87 100644 --- a/src/Commands.c +++ b/src/Commands.c @@ -309,9 +309,10 @@ static struct ChatCommand MotdCommand = { *########################################################################################################################*/ static void PlaceCommand_Execute(const cc_string* args, int argsCount) { + cc_string name; + cc_uint8 off; int block; IVec3 pos; - cc_uint8 off; if (argsCount == 2) { Chat_AddRaw("&eToo few arguments."); @@ -335,8 +336,7 @@ static void PlaceCommand_Execute(const cc_string* args, int argsCount) { Chat_AddRaw("&eCould not parse coordinates."); return; } - } - else { + } else { IVec3_Floor(&pos, &Entities.CurPlayer->Base.Position); } @@ -346,7 +346,7 @@ static void PlaceCommand_Execute(const cc_string* args, int argsCount) { } Game_ChangeBlock(pos.x, pos.y, pos.z, block); - cc_string name = Block_UNSAFE_GetName(block); + name = Block_UNSAFE_GetName(block); Chat_Add4("&eSuccessfully placed %s block at (%i, %i, %i).", &name, &pos.x, &pos.y, &pos.z); } diff --git a/src/Game.c b/src/Game.c index 2789769c6..266a00804 100644 --- a/src/Game.c +++ b/src/Game.c @@ -728,15 +728,16 @@ int Game_MapState(int deviceIndex) { static CC_INLINE void Game_RenderFrame(void) { struct ScheduledTask entTask; - float t; + double deltaD; + float t, delta; cc_uint64 render = Stopwatch_Measure(); cc_uint64 elapsed = Stopwatch_ElapsedMicroseconds(frameStart, render); /* avoid large delta with suspended process */ if (elapsed > 5000000) elapsed = 5000000; - double deltaD = (int)elapsed / (1000.0 * 1000.0); - float delta = (float)deltaD; + deltaD = (int)elapsed / (1000.0 * 1000.0); + delta = (float)deltaD; Window_ProcessEvents(delta); if (delta <= 0.0f) return; diff --git a/src/Logger.c b/src/Logger.c index 0ddb8e4c2..d4d08568e 100644 --- a/src/Logger.c +++ b/src/Logger.c @@ -18,6 +18,8 @@ #include #include + /* Compatibility version so compiling works on older Windows SDKs */ + #include "../misc/windows/min-imagehlp.h" static HANDLE curProcess = CUR_PROCESS_HANDLE; #elif defined CC_BUILD_OPENBSD || defined CC_BUILD_HAIKU || defined CC_BUILD_SERENITY #include @@ -203,8 +205,6 @@ static void PrintFrame(cc_string* str, cc_uintptr addr, cc_uintptr symAddr, cons #if defined CC_BUILD_WIN struct SymbolAndName { IMAGEHLP_SYMBOL symbol; char name[256]; }; -static BOOL (WINAPI *_SymGetSymFromAddr)(HANDLE process, DWORD_PTR addr, DWORD_PTR* displacement, IMAGEHLP_SYMBOL* sym); -static BOOL (WINAPI *_SymGetModuleInfo) (HANDLE process, DWORD_PTR addr, IMAGEHLP_MODULE* module); static void DumpFrame(HANDLE process, cc_string* trace, cc_uintptr addr) { char strBuffer[512]; cc_string str; @@ -232,7 +232,7 @@ static void DumpFrame(HANDLE process, cc_string* trace, cc_uintptr addr) { { IMAGEHLP_LINE line = { 0 }; DWORD lineOffset; line.SizeOfStruct = sizeof(IMAGEHLP_LINE); - if (SymGetLineFromAddr(process, addr, &lineOffset, &line)) { + if (_SymGetLineFromAddr(process, addr, &lineOffset, &line)) { String_Format2(&str, " line %i in %c\r\n", &line.LineNumber, line.FileName); } } @@ -286,9 +286,6 @@ static void DumpFrame(cc_string* trace, void* addr) { *-------------------------------------------------------Backtracing-------------------------------------------------------* *#########################################################################################################################*/ #if defined CC_BUILD_WIN -static DWORD_PTR (WINAPI *_SymGetModuleBase)(HANDLE process, DWORD_PTR addr); -static PVOID (WINAPI *_SymFunctionTableAccess)(HANDLE process, DWORD_PTR addr); -static BOOL (WINAPI *_SymInitialize)(HANDLE process, PCSTR userSearchPath, BOOL fInvadeProcess); static PVOID WINAPI FunctionTableAccessCallback(HANDLE process, DWORD_PTR addr) { if (!_SymFunctionTableAccess) return NULL; @@ -341,10 +338,11 @@ static int GetFrames(CONTEXT* ctx, cc_uintptr* addrs, int max) { return RtlCaptureStackBackTrace(0, max, (void**)addrs, NULL); #endif thread = GetCurrentThread(); + if (!_StackWalk) return 0; for (count = 0; count < max; count++) { - if (!StackWalk(type, curProcess, thread, &frame, ctx, ReadMemCallback, + if (!_StackWalk(type, curProcess, thread, &frame, ctx, ReadMemCallback, FunctionTableAccessCallback, GetModuleBaseCallback, NULL)) break; if (!frame.AddrFrame.Offset) break; addrs[count] = frame.AddrPC.Offset; @@ -960,7 +958,7 @@ static BOOL CALLBACK DumpModule(const char* name, ULONG_PTR base, ULONG size, vo Logger_Log(&str); return true; } -static BOOL (WINAPI *_EnumerateLoadedModules)(HANDLE process, PENUMLOADED_MODULES_CALLBACK callback, PVOID userContext); + static void DumpMisc(void) { static const cc_string modules = String_FromConst("-- modules --\r\n"); if (spRegister >= 0xFFFF) DumpStack(); @@ -1115,29 +1113,9 @@ static LONG WINAPI UnhandledFilter(struct _EXCEPTION_POINTERS* info) { } void Logger_Hook(void) { - static const struct DynamicLibSym funcs[] = { - #ifdef _IMAGEHLP64 - { "EnumerateLoadedModules64", (void**)&_EnumerateLoadedModules}, - { "SymFunctionTableAccess64", (void**)&_SymFunctionTableAccess}, - { "SymGetModuleBase64", (void**)&_SymGetModuleBase }, - { "SymGetModuleInfo64", (void**)&_SymGetModuleInfo }, - { "SymGetSymFromAddr64", (void**)&_SymGetSymFromAddr }, - { "SymInitialize", (void**)&_SymInitialize }, - #else - { "EnumerateLoadedModules", (void**)&_EnumerateLoadedModules }, - { "SymFunctionTableAccess", (void**)&_SymFunctionTableAccess }, - { "SymGetModuleBase", (void**)&_SymGetModuleBase }, - { "SymGetModuleInfo", (void**)&_SymGetModuleInfo }, - { "SymGetSymFromAddr", (void**)&_SymGetSymFromAddr }, - { "SymInitialize", (void**)&_SymInitialize }, - #endif - }; - static const cc_string imagehlp = String_FromConst("IMAGEHLP.DLL"); OSVERSIONINFOA osInfo; - void* lib; - SetUnhandledExceptionFilter(UnhandledFilter); - DynamicLib_LoadAll(&imagehlp, funcs, Array_Elems(funcs), &lib); + ImageHlp_LoadDynamicFuncs(); /* Windows 9x requires process IDs instead - see old DBGHELP docs */ /* https://documentation.help/DbgHelp/documentation.pdf */ diff --git a/src/Platform_Windows.c b/src/Platform_Windows.c index 32e98832c..5cb21187b 100644 --- a/src/Platform_Windows.c +++ b/src/Platform_Windows.c @@ -131,9 +131,9 @@ void Platform_Log(const char* msg, int len) { OutputDebugStringA("\n"); } -static VOID (WINAPI *_GetSystemTimeAsFileTime)(LPFILETIME sysTime); +static void (WINAPI *_GetSystemTimeAsFileTime)(LPFILETIME sysTime); /* Fallback support for NT 3.5 */ -static VOID WINAPI Fallback_GetSystemTimeAsFileTime(LPFILETIME sysTime) { +static void WINAPI Fallback_GetSystemTimeAsFileTime(LPFILETIME sysTime) { SYSTEMTIME curTime; GetSystemTime(&curTime); SystemTimeToFileTime(&curTime, sysTime); @@ -143,6 +143,7 @@ static VOID WINAPI Fallback_GetSystemTimeAsFileTime(LPFILETIME sysTime) { #define FILETIME_UNIX_EPOCH 11644473600ULL #define FileTime_TotalSecs(time) ((time / 10000000) + FILETIME_EPOCH) #define FileTime_UnixTime(time) ((time / 10000000) - FILETIME_UNIX_EPOCH) + TimeMS DateTime_CurrentUTC(void) { FILETIME ft; cc_uint64 raw; diff --git a/src/Window_Win.c b/src/Window_Win.c index 05396257c..94e87a50c 100644 --- a/src/Window_Win.c +++ b/src/Window_Win.c @@ -445,8 +445,8 @@ void Clipboard_GetText(cc_string* value) { HWND hwnd = Window_Main.Handle.ptr; cc_bool unicode; HANDLE hGlobal; - LPVOID src; SIZE_T size; + void* src; int i; /* retry up to 50 times */ @@ -857,11 +857,11 @@ static void GLContext_SelectGraphicsMode(struct GraphicsMode* mode) { } void GLContext_Create(void) { + static const cc_string glPath = String_FromConst("OPENGL32.dll"); struct GraphicsMode mode; + InitGraphicsMode(&mode); GLContext_SelectGraphicsMode(&mode); - - static const cc_string glPath = String_FromConst("OPENGL32.dll"); gl_lib = DynamicLib_Load2(&glPath); ctx_handle = wglCreateContext(win_DC);