diff --git a/metamod/msvc/metamod.vcxproj b/metamod/msvc/metamod.vcxproj index 114a127..892b93f 100644 --- a/metamod/msvc/metamod.vcxproj +++ b/metamod/msvc/metamod.vcxproj @@ -196,6 +196,7 @@ + @@ -228,6 +229,7 @@ + diff --git a/metamod/msvc/metamod.vcxproj.filters b/metamod/msvc/metamod.vcxproj.filters index d11fa0b..da7aeac 100644 --- a/metamod/msvc/metamod.vcxproj.filters +++ b/metamod/msvc/metamod.vcxproj.filters @@ -86,6 +86,9 @@ Source Files + + Source Files + @@ -172,6 +175,9 @@ Source Files + + Source Files + diff --git a/metamod/src/callback_jit.cpp b/metamod/src/callback_jit.cpp index c4b012b..2f4df25 100644 --- a/metamod/src/callback_jit.cpp +++ b/metamod/src/callback_jit.cpp @@ -15,12 +15,13 @@ private: size_t CUniqueLabel::m_unique_index; -class CForwardCallbackJIT : public jitasm::function +class CForwardCallbackJIT : public jitasm::function { public: CForwardCallbackJIT(jitdata_t* jitdata); void naked_main(); void call_func(Reg32 addr); + void jit_debug(const char* format, ...); private: jitdata_t* m_jitdata; @@ -52,6 +53,8 @@ CForwardCallbackJIT::CForwardCallbackJIT(jitdata_t* jitdata) : m_jitdata(jitdata void CForwardCallbackJIT::naked_main() { + jit_debug("Enter %s\n", m_jitdata->name); + // prologue push(ebx); push(ebp); @@ -151,6 +154,7 @@ void CForwardCallbackJIT::naked_main() mov(dword_ptr[globals + mg_status], eax); // NULL } + jit_debug("Calling pre [%s] for plug [%s]\n", m_jitdata->name, plug->description()); call_func(ecx); mov(edx, dword_ptr[globals + mg_mres]); @@ -174,6 +178,7 @@ void CForwardCallbackJIT::naked_main() jz("skip_original"); { if (m_jitdata->pfn_original) { + //jit_debug("Call original %s\n", m_jitdata->name); mov(ecx, m_jitdata->pfn_original); call_func(ecx); } @@ -232,6 +237,7 @@ void CForwardCallbackJIT::naked_main() mov(dword_ptr[globals + mg_status], eax); // NULL } + jit_debug("Calling post [%s] for plug [%s]\n", m_jitdata->name, plug->description()); call_func(ecx); mov(edx, dword_ptr[globals + mg_mres]); @@ -271,6 +277,7 @@ void CForwardCallbackJIT::naked_main() mov(esp, ebp); pop(ebp); pop(ebx); + jit_debug("Leave %s\n", m_jitdata->name); ret(); } @@ -301,6 +308,31 @@ void CForwardCallbackJIT::call_func(Reg32 addr) add(esp, m_jitdata->args_count * sizeof(int)); } +void CForwardCallbackJIT::jit_debug(const char* format, ...) +{ +#ifdef JIT_DEBUG + va_list argptr; + char string[1024] = ""; + + va_start(argptr, format); + Q_vsnprintf(string, sizeof string, format, argptr); + va_end(argptr); + + char* memory_leak = Q_strdup(string); // yes, I'm lazy + static size_t print_ptr = size_t(&printf); + static size_t fprint_ptr = size_t(&mdebug_to_file); + + pushad(); + push(size_t(memory_leak)); + call(dword_ptr[size_t(&print_ptr)]); +#ifdef JIT_DEBUG_FILE + call(dword_ptr[size_t(&fprint_ptr)]); +#endif + add(esp, 4); + popad(); +#endif +} + CJit::CJit() : m_callback_allocator(static_allocator::mp_rwx), m_tramp_allocator(static_allocator::mp_rwx) { } diff --git a/metamod/src/callback_jit.h b/metamod/src/callback_jit.h index a9640f7..c78b471 100644 --- a/metamod/src/callback_jit.h +++ b/metamod/src/callback_jit.h @@ -16,6 +16,10 @@ struct jitdata_t int plugins_count; size_t table_offset; // from MPlugin size_t post_table_offset; // from MPlugin + +#ifdef JIT_DEBUG + const char* name; +#endif }; struct compile_data_t @@ -85,6 +89,7 @@ public: size_t compile_tramp(size_t ptr_to_func/*, size_t hook, size_t hook_time*/); void clear_callbacks(); void clear_tramps(); + size_t find_new_retaddr(size_t pfn); private: static bool is_hook_needed(jitdata_t* jitdata); diff --git a/metamod/src/dllapi.cpp b/metamod/src/dllapi.cpp index 510c616..21d8d70 100644 --- a/metamod/src/dllapi.cpp +++ b/metamod/src/dllapi.cpp @@ -224,6 +224,10 @@ void compile_dllfunc_callbacks() jitdata.mm_hook_time = cd.mm_hook_time; jitdata.mm_hook = cd.mm_hook; +#ifdef JIT_DEBUG + jitdata.name = cd.name; +#endif + *(size_t *)(size_t(&sFunctionTable) + cd.offset) = g_jit.compile_callback(&jitdata); } } @@ -245,6 +249,10 @@ void compile_newdllfunc_callbacks() jitdata.mm_hook_time = cd.mm_hook_time; jitdata.mm_hook = cd.mm_hook; +#ifdef JIT_DEBUG + jitdata.name = cd.name; +#endif + *(size_t *)(size_t(&sNewFunctionTable) + cd.offset) = g_jit.compile_callback(&jitdata); } } diff --git a/metamod/src/engine_api.cpp b/metamod/src/engine_api.cpp index b047efc..8513363 100644 --- a/metamod/src/engine_api.cpp +++ b/metamod/src/engine_api.cpp @@ -253,6 +253,10 @@ void compile_engfuncs_callbacks() jitdata.mm_hook_time = cd.mm_hook_time; jitdata.mm_hook = cd.mm_hook; +#ifdef JIT_DEBUG + jitdata.name = cd.name; +#endif + *(size_t *)(size_t(&g_meta_engfuncs_jit) + cd.offset) = g_jit.compile_callback(&jitdata); } } diff --git a/metamod/src/metamod.cpp b/metamod/src/metamod.cpp index 30a9490..f9486e9 100644 --- a/metamod/src/metamod.cpp +++ b/metamod/src/metamod.cpp @@ -426,6 +426,10 @@ void meta_rebuild_callbacks() { META_LOG("dll: Rebuilding callbacks..."); +#ifdef JIT_DEBUG_FILE + mdebug_to_file("dll: Rebuilding callbacks...\n"); +#endif + g_jit.clear_callbacks(); compile_engine_callbacks(); diff --git a/metamod/src/precompiled.h b/metamod/src/precompiled.h index 45a2602..aa09fd2 100644 --- a/metamod/src/precompiled.h +++ b/metamod/src/precompiled.h @@ -26,6 +26,7 @@ #include #include "osdep.h" +#include "mdebug.h" #include "api_info.h" #include "commands_meta.h" #include "metamod.h" diff --git a/metamod/src/utils.h b/metamod/src/utils.h index 049e71b..7828636 100644 --- a/metamod/src/utils.h +++ b/metamod/src/utils.h @@ -53,6 +53,8 @@ private: size_t m_used = 0; std::vector m_pages; memory_protection m_protection; + + friend class CJit; }; bool is_yes(const char* str);