From 4ed68f73dae9e7621d7d7512b5feb686e9440bb2 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Thu, 6 Jan 2022 23:39:21 +0000 Subject: Tidy up stubs, make vstdlib a stub, build on Linux Important note: it doesn't WORK on Linux, and there's tons of warnings and stuff, but it's easier to work on when all the compiler output and whatnot is there. --- src/con_.c | 6 ++++-- src/con_.h | 2 +- src/demorec.c | 9 ++++++--- src/gameinfo.c | 9 ++++----- src/os.h | 1 + src/sst.c | 33 ++++++++++----------------------- src/stubs/stub.h | 13 +++++++++++++ src/stubs/tier0.c | 9 +++++++++ src/stubs/vstdlib.c | 7 +++++++ src/tier0stub.c | 19 ------------------- 10 files changed, 55 insertions(+), 53 deletions(-) create mode 100644 src/stubs/stub.h create mode 100644 src/stubs/tier0.c create mode 100644 src/stubs/vstdlib.c delete mode 100644 src/tier0stub.c (limited to 'src') diff --git a/src/con_.c b/src/con_.c index 1c9d4a7..be3f20c 100644 --- a/src/con_.c +++ b/src/con_.c @@ -16,6 +16,7 @@ */ #include +#include // should be implied by stdlib but glibc is dumb (offsetof) #include #include @@ -294,7 +295,7 @@ static void VCALLCONV Create_var(void *thisoff, const char *name, void *_con_vtab_cmd[14 + NVDTOR] = { (void *)&dtor, #ifndef _WIN32 - (void *)&dtor2, + (void *)&dtor, #endif (void *)&IsCommand_cmd, (void *)&IsFlagSet_cmd, @@ -312,10 +313,11 @@ void *_con_realvtab_var[20] = { &varrtti, #else // this, among many other things, will be totally different on linux +#warning FIX THIS TOO! #endif (void *)&dtor, #ifndef _WIN32 - (void *)&dtor2, + (void *)&dtor, #endif (void *)&IsCommand_var, (void *)&IsFlagSet_var, diff --git a/src/con_.h b/src/con_.h index bfc8c47..653bdad 100644 --- a/src/con_.h +++ b/src/con_.h @@ -127,7 +127,7 @@ struct con_cmd { // ConCommand in engine // con_var will be a bit different on linux; see offset_to_top etc. #ifdef __linux__ -#error FIXME: redo multi-vtable crap for itanium ABI! +#warning FIXME: redo multi-vtable crap for itanium ABI! #endif struct con_var { // ConVar in engine diff --git a/src/demorec.c b/src/demorec.c index 76e7f00..1a988ed 100644 --- a/src/demorec.c +++ b/src/demorec.c @@ -161,7 +161,8 @@ static inline void *find_demorecorder(struct con_cmd *cmd_stop) { } } #else -#error TODO(linux): implement linux equivalent (cdecl!) +#warning TODO(linux): implement linux equivalent (cdecl!) + return 0; #endif } return 0; @@ -203,7 +204,8 @@ static inline bool find_recmembers(void *stop_recording_func) { return false; } #else // linux is probably different here idk -#error TODO(linux): implement linux equivalent +#warning TODO(linux): implement linux equivalent + return false; #endif } return false; @@ -228,7 +230,8 @@ static bool find_WriteMessages(void) { #ifdef _WIN32 {0x56, 0x57, 0x8B, 0xF1, 0x8D, 0xBE, 0x8C, 0x06, 0x00, 0x00, 0x57, 0xE8}; #else -#error This is possibly different on Linux too, have a look! +#warning This is possibly different on Linux too, have a look! +{-1, -1, -1, -1, -1, -1}; #endif if (!memcmp(insns, bytes, sizeof(bytes))) { ssize off = mem_loadoffset(insns + sizeof(bytes)); diff --git a/src/gameinfo.c b/src/gameinfo.c index 32f5051..de5fafc 100644 --- a/src/gameinfo.c +++ b/src/gameinfo.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #ifdef _WIN32 @@ -49,9 +48,9 @@ const os_char *gameinfo_serverlib = _gameinfo_serverlib; // magical argc/argv grabber so we don't have to go through procfs #ifdef __linux__ -static const char *prog_argv; +static const char *const *prog_argv; static int storeargs(int argc, char *argv[]) { - prog_argv = argv; + prog_argv = (const char *const *)argv; return 0; } __attribute__((used, section(".init_array"))) @@ -116,7 +115,7 @@ static inline void do_gamelib_search(const char *p, uint len, bool isgamebin) { api_needs_null_term[len] = L'\0'; if (!PathIsRelativeA(api_needs_null_term)) #else - if (*p == "/") // so much easier :') + if (*p == '/') // so much easier :') #endif { // the mod path is absolute, so we're not sticking anything else in @@ -313,7 +312,7 @@ bool gameinfo_init(void) { // also do the executable name check just for portal2_linux if (!strcmp(exename, "portal2_linux")) modname = "portal2"; // ah, the sane, straightforward world of unix command line arguments :) - for (char **pp = prog_argv + 1; *pp; ++pp) { + for (const char *const *pp = prog_argv + 1; *pp; ++pp) { if (!strcmp(*pp, "-game")) { if (!*++pp) break; modname = *pp; diff --git a/src/os.h b/src/os.h index 654e754..d231e67 100644 --- a/src/os.h +++ b/src/os.h @@ -25,6 +25,7 @@ * between Windows and not-Windows under the rug. */ +#include #include #ifdef _WIN32 #define NOMINMAX diff --git a/src/sst.c b/src/sst.c index 94e1661..9cf21c2 100644 --- a/src/sst.c +++ b/src/sst.c @@ -84,6 +84,9 @@ static const char *VCALLCONV GetStringForSymbol_hook(void *this, int s) { return ret; } +// vstdlib symbol, only currently used in l4d2 but exists everywhere so oh well +IMPORT void *KeyValuesSystem(void); + static bool do_load(ifacefactory enginef, ifacefactory serverf) { factory_engine = enginef; factory_server = serverf; #ifndef __linux__ @@ -133,31 +136,15 @@ nc: gamedata_init(); // NOTE: this is technically redundant for early versions but I CBA writing // a version check; it's easier to just do this unilaterally. if (GAMETYPE_MATCHES(L4D2)) { -#ifdef _WIN32 - // XXX: not sure if vstdlib should be done dynamically like this or just - // another stub like tier0? - void *vstdlib = GetModuleHandleW(L"vstdlib.dll"); - if (!vstdlib) { - con_warn("sst: warning: couldn't get vstdlib, won't be able to " - "prevent nag message\n"); + void *kvs = KeyValuesSystem(); + kvsvt = *(void ***)kvs; + if (!os_mprot(kvsvt + 4, sizeof(void *), PAGE_READWRITE)) { + con_warn("sst: warning: couldn't unprotect KeyValuesSystem " + "vtable; won't be able to prevent nag message\n"); goto e; } - void *(*KeyValuesSystem)(void) = (void *(*)(void))os_dlsym(vstdlib, - "KeyValuesSystem"); - if (KeyValuesSystem) { - void *kvs = KeyValuesSystem(); - kvsvt = *(void ***)kvs; - if (!os_mprot(kvsvt + 4, sizeof(void *), PAGE_READWRITE)) { - con_warn("sst: warning: couldn't unprotect KeyValuesSystem " - "vtable; won't be able to prevent nag message\n"); - goto e; - } - orig_GetStringForSymbol = (GetStringForSymbol_func)hook_vtable( - kvsvt, 4, (void *)GetStringForSymbol_hook); - } -#else -#warning TODO(linux) suitably abstract this stuff to Linux! -#endif + orig_GetStringForSymbol = (GetStringForSymbol_func)hook_vtable(kvsvt, + 4, (void *)GetStringForSymbol_hook); } e: con_colourmsg(RGBA(64, 255, 64, 255), diff --git a/src/stubs/stub.h b/src/stubs/stub.h new file mode 100644 index 0000000..75d377c --- /dev/null +++ b/src/stubs/stub.h @@ -0,0 +1,13 @@ +// We produce dummy libraries for vstdlib and tier0 to allow linking without +// dlsym faff. These macros are because Windows needs additional care because +// it's dumb. + +#ifdef _WIN32 +#define F(name) __declspec(dllexport) void name(void) {} +#define V(name) __declspec(dllexport) void *name; +#else +#define F(name) void *name; +#define V(name) void *name; +#endif + +// vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/stubs/tier0.c b/src/stubs/tier0.c new file mode 100644 index 0000000..2c9c578 --- /dev/null +++ b/src/stubs/tier0.c @@ -0,0 +1,9 @@ +/* This file is dedicated to the public domain. */ + +#include "stub.h" + +F(Msg) +F(Warning) +V(g_pMemAlloc) + +// vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/stubs/vstdlib.c b/src/stubs/vstdlib.c new file mode 100644 index 0000000..d3a63b0 --- /dev/null +++ b/src/stubs/vstdlib.c @@ -0,0 +1,7 @@ +/* This file is dedicated to the public domain. */ + +#include "stub.h" + +F(KeyValuesSystem) + +// vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/tier0stub.c b/src/tier0stub.c deleted file mode 100644 index a043bea..0000000 --- a/src/tier0stub.c +++ /dev/null @@ -1,19 +0,0 @@ -/* This file is dedicated to the public domain. */ - -// Produce a dummy tier0.dll/libtier0.so to allow linking without dlsym faff. -// Windows needs additional care because it's dumb. - -#ifdef _WIN32 -#define F(name) __declspec(dllexport) void name(void) {} -#define V(name) __declspec(dllexport) void *name; -#else -#define F(name) void *name; -#define V(name) void *name; -#endif - -F(Msg); -F(Warning); -// F(Error); // unused in plugin -V(g_pMemAlloc); - -// vi: sw=4 ts=4 noet tw=80 cc=80 -- cgit v1.2.3