diff --git a/sourcehook/generate/sh_memfuncinfo.hxx b/sourcehook/generate/sh_memfuncinfo.hxx index b89633f..7a90291 100644 --- a/sourcehook/generate/sh_memfuncinfo.hxx +++ b/sourcehook/generate/sh_memfuncinfo.hxx @@ -54,16 +54,16 @@ namespace SourceHook # if SH_COMP == SH_COMP_GCC - template<> struct MFI_Impl<8> // All of these have size==8 + template<> struct MFI_Impl<2*SH_PTRSIZE> // All of these have size==8/16 { struct GCC_MemFunPtr { union { void *funcadr; // always even - int vtable_index_plus1; // = vindex+1, always odd + intptr_t vtable_index_plus1; // = vindex+1, always odd }; - int delta; + intptr_t delta; }; template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) { @@ -71,7 +71,7 @@ namespace SourceHook out.thisptroffs = mfp_detail->delta; if (mfp_detail->vtable_index_plus1 & 1) { - out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / 4; + out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / SH_PTRSIZE; out.vtbloffs = 0; out.isVirtual = true; } @@ -147,7 +147,7 @@ namespace SourceHook } } - template<> struct MFI_Impl<4> // simple ones + template<> struct MFI_Impl<1*SH_PTRSIZE> // simple ones { template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) { @@ -158,7 +158,7 @@ namespace SourceHook } }; - template<> struct MFI_Impl<8> // more complicated ones! + template<> struct MFI_Impl<2*SH_PTRSIZE> // more complicated ones! { struct MSVC_MemFunPtr2 { @@ -175,7 +175,7 @@ namespace SourceHook }; // By Don Clugston, adapted - template<> struct MFI_Impl<12> // WOW IT"S GETTING BIGGER OMGOMOGMG + template<> struct MFI_Impl<3*SH_PTRSIZE> // WOW IT"S GETTING BIGGER OMGOMOGMG { class __single_inheritance GenericClass; class GenericClass {}; @@ -228,7 +228,7 @@ namespace SourceHook // unknown_inheritance classes go here // This is probably the ugliest bit of code I've ever written. Look at the casts! // There is a compiler bug in MSVC6 which prevents it from using this code. - template<> struct MFI_Impl<16> // THE BIGGEST ONE!!!1GABEN + template<> struct MFI_Impl<4*SH_PTRSIZE> // THE BIGGEST ONE!!!1GABEN { template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) { diff --git a/sourcehook/generate/sourcehook.hxx b/sourcehook/generate/sourcehook.hxx index ef97685..91a4e8a 100755 --- a/sourcehook/generate/sourcehook.hxx +++ b/sourcehook/generate/sourcehook.hxx @@ -63,6 +63,8 @@ # define vsnprintf _vsnprintf #endif +#define SH_PTRSIZE sizeof(void*) + #include "FastDelegate.h" #include "sh_memfuncinfo.h" #include "sh_memory.h" @@ -86,8 +88,8 @@ enum META_RES namespace SourceHook { - const int STRBUF_LEN=8192; // In bytes, for "vafmt" functions - + const int STRBUF_LEN=4096; // In bytes, for "vafmt" functions + /** * @brief An empty class. No inheritance used. Used for original-function-call hacks */ @@ -677,8 +679,9 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C ////////////////////////////////////////////////////////////////////////// // SH_CALL +#if SH_COMP == SH_COMP_MSVC -#define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ +# define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ { \ using namespace ::SourceHook; \ MemFuncInfo mfi; \ @@ -699,6 +702,34 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C return (reinterpret_cast(adjustedthisptr)->*u.mfpnew)call; \ } +#elif SH_COMP == SH_COMP_GCC + +# define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ +{ \ + using namespace ::SourceHook; \ + MemFuncInfo mfi; \ + GetFuncInfo(m_CC->ptr, m_MFP, mfi); \ + OrigVTables::const_iterator iter = m_CC->vt.find(mfi.thisptroffs + mfi.vtbloffs); \ + if (iter == m_CC->vt.end() || mfi.vtblindex >= (int)iter->second.size() || iter->second[mfi.vtblindex] == NULL) \ + return (m_CC->ptr->*m_MFP)call; \ + \ + /* It's hooked. Call the original function. */ \ + union \ + { \ + RetType(EmptyClass::*mfpnew)prms; \ + struct \ + { \ + void *addr; \ + intptr_t adjustor; \ + } s; \ + } u; \ + u.s.addr = iter->second[mfi.vtblindex]; \ + u.s.adjustor = mfi.thisptroffs; \ + \ + return (reinterpret_cast(m_CC->ptr)->*u.mfpnew)call; \ +} + +#endif namespace SourceHook { diff --git a/sourcehook/sh_memfuncinfo.h b/sourcehook/sh_memfuncinfo.h index 5e9eaa4..aaece18 100644 --- a/sourcehook/sh_memfuncinfo.h +++ b/sourcehook/sh_memfuncinfo.h @@ -54,16 +54,16 @@ namespace SourceHook # if SH_COMP == SH_COMP_GCC - template<> struct MFI_Impl<8> // All of these have size==8 + template<> struct MFI_Impl<2*SH_PTRSIZE> // All of these have size==8/16 { struct GCC_MemFunPtr { union { void *funcadr; // always even - int vtable_index_plus1; // = vindex+1, always odd + intptr_t vtable_index_plus1; // = vindex+1, always odd }; - int delta; + intptr_t delta; }; template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) { @@ -71,7 +71,7 @@ namespace SourceHook out.thisptroffs = mfp_detail->delta; if (mfp_detail->vtable_index_plus1 & 1) { - out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / 4; + out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / SH_PTRSIZE; out.vtbloffs = 0; out.isVirtual = true; } @@ -147,7 +147,7 @@ namespace SourceHook } } - template<> struct MFI_Impl<4> // simple ones + template<> struct MFI_Impl<1*SH_PTRSIZE> // simple ones { template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) { @@ -158,7 +158,7 @@ namespace SourceHook } }; - template<> struct MFI_Impl<8> // more complicated ones! + template<> struct MFI_Impl<2*SH_PTRSIZE> // more complicated ones! { struct MSVC_MemFunPtr2 { @@ -175,7 +175,7 @@ namespace SourceHook }; // By Don Clugston, adapted - template<> struct MFI_Impl<12> // WOW IT"S GETTING BIGGER OMGOMOGMG + template<> struct MFI_Impl<3*SH_PTRSIZE> // WOW IT"S GETTING BIGGER OMGOMOGMG { class __single_inheritance GenericClass; class GenericClass {}; @@ -228,7 +228,7 @@ namespace SourceHook // unknown_inheritance classes go here // This is probably the ugliest bit of code I've ever written. Look at the casts! // There is a compiler bug in MSVC6 which prevents it from using this code. - template<> struct MFI_Impl<16> // THE BIGGEST ONE!!!1GABEN + template<> struct MFI_Impl<4*SH_PTRSIZE> // THE BIGGEST ONE!!!1GABEN { template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) { diff --git a/sourcehook/sh_memory.h b/sourcehook/sh_memory.h index 04d9644..ecf303f 100644 --- a/sourcehook/sh_memory.h +++ b/sourcehook/sh_memory.h @@ -34,8 +34,8 @@ // We need to align addr down to pagesize on linux // We assume PAGESIZE is a power of two -# define SH_LALIGN(x) (void*)((int)(x) & ~(PAGESIZE-1)) -# define SH_LALDIF(x) ((int)(x) & (PAGESIZE-1)) +# define SH_LALIGN(x) (void*)((intptr_t)(x) & ~(PAGESIZE-1)) +# define SH_LALDIF(x) ((intptr_t)(x) & (PAGESIZE-1)) # else # error Unsupported OS/Compiler # endif diff --git a/sourcehook/sourcehook.h b/sourcehook/sourcehook.h index b0dd7f7..3ad0275 100644 --- a/sourcehook/sourcehook.h +++ b/sourcehook/sourcehook.h @@ -63,6 +63,8 @@ # define vsnprintf _vsnprintf #endif +#define SH_PTRSIZE sizeof(void*) + #include "FastDelegate.h" #include "sh_memfuncinfo.h" #include "sh_memory.h" @@ -86,8 +88,8 @@ enum META_RES namespace SourceHook { - const int STRBUF_LEN=8192; // In bytes, for "vafmt" functions - + const int STRBUF_LEN=4096; // In bytes, for "vafmt" functions + /** * @brief An empty class. No inheritance used. Used for original-function-call hacks */ @@ -1491,8 +1493,9 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C ////////////////////////////////////////////////////////////////////////// // SH_CALL +#if SH_COMP == SH_COMP_MSVC -#define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ +# define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ { \ using namespace ::SourceHook; \ MemFuncInfo mfi; \ @@ -1513,6 +1516,34 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C return (reinterpret_cast(adjustedthisptr)->*u.mfpnew)call; \ } +#elif SH_COMP == SH_COMP_GCC + +# define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ +{ \ + using namespace ::SourceHook; \ + MemFuncInfo mfi; \ + GetFuncInfo(m_CC->ptr, m_MFP, mfi); \ + OrigVTables::const_iterator iter = m_CC->vt.find(mfi.thisptroffs + mfi.vtbloffs); \ + if (iter == m_CC->vt.end() || mfi.vtblindex >= (int)iter->second.size() || iter->second[mfi.vtblindex] == NULL) \ + return (m_CC->ptr->*m_MFP)call; \ + \ + /* It's hooked. Call the original function. */ \ + union \ + { \ + RetType(EmptyClass::*mfpnew)prms; \ + struct \ + { \ + void *addr; \ + intptr_t adjustor; \ + } s; \ + } u; \ + u.s.addr = iter->second[mfi.vtblindex]; \ + u.s.adjustor = mfi.thisptroffs; \ + \ + return (reinterpret_cast(m_CC->ptr)->*u.mfpnew)call; \ +} + +#endif namespace SourceHook { diff --git a/sourcehook/test/testevents.h b/sourcehook/test/testevents.h index 622b181..7485ccb 100644 --- a/sourcehook/test/testevents.h +++ b/sourcehook/test/testevents.h @@ -100,8 +100,7 @@ namespace } } -//#define CHECK_STATES(mwah, myerr) if (!StatesOk mwah) { error=myerr; return false; } else if (g_Verbose) { std::cout << "No error: " << myerr << std::endl; } -#define CHECK_STATES(mwah, myerr) if (!StatesOk mwah) { error=myerr; return false; } +#define CHECK_STATES(mwah, myerr) if (!StatesOk mwah) { error=myerr; return false; } else if (g_Verbose) { std::cout << "No error: " << myerr << std::endl; } #define MAKE_STATE(name) struct name : State { \ virtual void Dump() { \