diff options
author | 2025-04-17 01:39:10 +0100 | |
---|---|---|
committer | 2025-04-17 20:02:18 +0100 | |
commit | 8a669bc96ffdb9d0f6f54e464da11e3375c80a55 (patch) | |
tree | 569dac0cd082ad25e779a69f0bcceff5ca212bb1 /src/kvsys.c | |
parent | 0b40d4d9ea1cbfbb92795e0d6f26cf108f2dec5f (diff) | |
download | sst-8a669bc96ffdb9d0f6f54e464da11e3375c80a55.tar.gz sst-8a669bc96ffdb9d0f6f54e464da11e3375c80a55.zip |
Add type-safety to virtual calls and accessors
This probably should have been the design from the start.
It's still possible to use void pointers, and this is done in a couple
of places for simplicity, but wherever possible, we have actual structs
for things now.
Additionally, in places where vtables are fiddled with, e.g. vtable
hooks, we have actual struct definitions with vtable pointers so there's
need for pointer-casting horror.
Diffstat (limited to 'src/kvsys.c')
-rw-r--r-- | src/kvsys.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/src/kvsys.c b/src/kvsys.c index 7996928..9c0f75c 100644 --- a/src/kvsys.c +++ b/src/kvsys.c @@ -16,8 +16,6 @@ */ #include "abi.h" -#include "con_.h" -#include "engineapi.h" #include "extmalloc.h" #include "errmsg.h" #include "feature.h" @@ -25,19 +23,21 @@ #include "hook.h" #include "kvsys.h" #include "langext.h" -#include "mem.h" #include "os.h" #include "vcall.h" #include "x86.h" FEATURE() -void *KeyValuesSystem(); // vstlib symbol -static void *kvs; +struct IKeyValuesSystem { void **vtable; }; + +struct IKeyValuesSystem *KeyValuesSystem(); // vstlib symbol +static struct IKeyValuesSystem *kvs; static int vtidx_GetSymbolForString = 3, vtidx_GetStringForSymbol = 4; static bool iskvv2 = false; -DECL_VFUNC_DYN(int, GetSymbolForString, const char *, bool) -DECL_VFUNC_DYN(const char *, GetStringForSymbol, int) +DECL_VFUNC_DYN(struct IKeyValuesSystem, int, GetSymbolForString, const char *, + bool) +DECL_VFUNC_DYN(struct IKeyValuesSystem, const char *, GetStringForSymbol, int) const char *kvsys_symtostr(int sym) { return GetStringForSymbol(kvs, sym); } int kvsys_strtosym(const char *s) { return GetSymbolForString(kvs, s, true); } @@ -100,16 +100,16 @@ INIT { // kvs ABI check is probably relevant for other games, but none that we // currently actively support if (GAMETYPE_MATCHES(L4D2x)) { - void **kvsvt = mem_loadptr(kvs); - detectabichange(kvsvt); - if_cold (!os_mprot(kvsvt + vtidx_GetStringForSymbol, sizeof(void *), - PAGE_READWRITE)) { + void **vtable = kvs->vtable; + detectabichange(vtable); + if_cold (!os_mprot(vtable + vtidx_GetStringForSymbol, + sizeof(void *), PAGE_READWRITE)) { errmsg_warnx("couldn't make KeyValuesSystem vtable writable"); errmsg_note("won't be able to prevent any nag messages"); } else { orig_GetStringForSymbol = (GetStringForSymbol_func)hook_vtable( - kvsvt, vtidx_GetStringForSymbol, + vtable, vtidx_GetStringForSymbol, (void *)hook_GetStringForSymbol); } } @@ -118,7 +118,7 @@ INIT { END { if (orig_GetStringForSymbol) { - unhook_vtable(*(void ***)kvs, vtidx_GetStringForSymbol, + unhook_vtable(kvs->vtable, vtidx_GetStringForSymbol, (void *)orig_GetStringForSymbol); } } |