diff options
Diffstat (limited to 'src/l4d1democompat.c')
| -rw-r--r-- | src/l4d1democompat.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/src/l4d1democompat.c b/src/l4d1democompat.c index 1cfe959..4280d53 100644 --- a/src/l4d1democompat.c +++ b/src/l4d1democompat.c @@ -17,15 +17,16 @@ */ #include "accessor.h" +#include "chunklets/x86.h" #include "con_.h" #include "errmsg.h" #include "feature.h" +#include "gametype.h" #include "hook.h" #include "intdefs.h" #include "mem.h" #include "sst.h" #include "vcall.h" -#include "x86.h" #include "x86util.h" FEATURE("Left 4 Dead 1 demo file backwards compatibility") @@ -50,9 +51,8 @@ static GetHostVersion_func orig_GetHostVersion; typedef void (*VCALLCONV ReadDemoHeader_func)(void *); static ReadDemoHeader_func orig_ReadDemoHeader; -static inline bool find_ReadDemoHeader(con_cmdcb listdemo_cb) { +static inline bool find_ReadDemoHeader(const uchar *insns) { // Find the call to ReadDemoHeader in the listdemo callback - const uchar *insns = (const uchar *)listdemo_cb; for (const uchar *p = insns; p - insns < 192;) { if (p[0] == X86_LEA && p[1] == X86_MODRM(2, 1, 4) && p[2] == 0x24 && p[7] == X86_CALL && p[12] == X86_LEA && @@ -115,21 +115,14 @@ static void VCALLCONV hook_ReadDemoHeader(struct CDemoFile *this) { orig_ReadDemoHeader(this); } -#if defined(__clang__) -__attribute__((naked)) -#elif defined(_MSC_VER) -#error Inadequate inline assembly syntax, use Clang instead. -#else -#error No way to do naked functions! We only support Clang at the moment. -#endif -static int hook_midpoint() { - __asm__ volatile ( - "pushl %%eax\n" - "movl %1, %%eax\n" - "movl (%%eax), %%eax\n" // dereference this_protocol - "movl %%eax, %0\n" // store in demoversion - "popl %%eax\n" - "jmpl *%2\n" +static asm_only int hook_midpoint() { + __asm volatile ( + "push eax\n" + "mov eax, %1\n" + "mov eax, [eax]\n" // dereference this_protocol + "mov %0, eax\n" // store in demoversion + "pop eax\n" + "jmp dword ptr %2\n" : "=m" (demoversion) : "m" (this_protocol), "m" (ReadDemoHeader_midpoint) ); @@ -138,7 +131,7 @@ static int hook_midpoint() { INIT { struct con_cmd *cmd_listdemo = con_findcmd("listdemo"); if_cold (!cmd_listdemo) return FEAT_INCOMPAT; // should never happen! - if_cold (!find_ReadDemoHeader(cmd_listdemo->cb)) { + if_cold (!find_ReadDemoHeader(cmd_listdemo->cb_insns)) { errmsg_errorx("couldn't find ReadDemoHeader function"); return FEAT_INCOMPAT; } |
