diff --git a/sourcehook/sourcehook.cpp b/sourcehook/sourcehook.cpp index 5ecea96..b946cec 100644 --- a/sourcehook/sourcehook.cpp +++ b/sourcehook/sourcehook.cpp @@ -473,38 +473,6 @@ namespace SourceHook } } -#ifdef __linux__ - // Windows has an implentation for this already, but Linux does not :( - static bool CSourceHookImpl::IsBadReadPtr(const void *ptr, size_t len) - { - void(*prevHandler)(int sig); - m_BadReadCalled = true; - - if (setjmp(m_BadReadJmpBuf)) - return true; - - prevHandler = signal(SIGSEGV, BadReadHandler); - - volatile const char *p = reinterpret_cast(ptr); - char dummy; - - for (size_t i = 0; i < len; i++) - dummy = p[i]; - - m_BadReadCalled = false; - - signal(SIGSEGV, prevHandler); - - return false; - } - - static void CSourceHookImpl::BadReadHandler(int sig) - { - if (m_BadReadCalled) - longjmp(m_BadReadJmpBuf, 1); - } -#endif - CSourceHookImpl::HookManInfoList::iterator CSourceHookImpl::FindHookMan(HookManInfoList::iterator begin, HookManInfoList::iterator end, const char *proto, int vtblofs, int vtblidx) { @@ -619,4 +587,36 @@ namespace SourceHook { return m_IfacePtr; } + +#ifdef __linux__ + // Windows has an implementation for this already, but Linux does not :( + bool IsBadReadPtr(const void *ptr, size_t len) + { + void(*prevHandler)(int sig); + g_BadReadCalled = true; + + if (setjmp(g_BadReadJmpBuf)) + return true; + + prevHandler = signal(SIGSEGV, BadReadHandler); + + volatile const char *p = reinterpret_cast(ptr); + char dummy; + + for (size_t i = 0; i < len; i++) + dummy = p[i]; + + g_BadReadCalled = false; + + signal(SIGSEGV, prevHandler); + + return false; + } + + void CSourceHookImpl::BadReadHandler(int sig) + { + if (g_BadReadCalled) + longjmp(g_BadReadJmpBuf, 1); + } +#endif } diff --git a/sourcehook/sourcehook_impl.h b/sourcehook/sourcehook_impl.h index 3f521f5..0e64892 100644 --- a/sourcehook/sourcehook_impl.h +++ b/sourcehook/sourcehook_impl.h @@ -82,22 +82,6 @@ namespace SourceHook void RemoveCallClassPatch(CallClassInfo &cc, int vtbl_offs, int vtbl_idx); void RemoveCallClassPatches(void *ifaceptr, int vtbl_offs, int vtbl_idx); -#ifdef __linux__ - /** - * @brief Checks to see if a memory value can be read from a given pointer. - * - * @return True if the value can be read and false if it cannot. - * - * @param ptr The pointer to the memory value. - * @param len The length of the memory value to be read from the pointer. - */ - static bool IsBadReadPtr(const void *ptr, size_t len); - static void BadReadHandler(int sig); - - bool m_BadReadCalled; - jmp_buf m_BadReadJmpBuf; -#endif - META_RES m_Status, m_PrevRes, m_CurRes; const void *m_OrigRet; const void *m_OverrideRet; @@ -215,6 +199,22 @@ namespace SourceHook virtual void SetOrigRet(const void *ptr); //!< Sets the original return pointer virtual void SetOverrideRet(const void *ptr); //!< Sets the override result pointer }; + +#ifdef __linux__ + /** + * @brief Checks to see if a memory value can be read from a given pointer. + * + * @return True if the value can be read and false if it cannot. + * + * @param ptr The pointer to the memory value. + * @param len The length of the memory value to be read from the pointer. + */ + bool IsBadReadPtr(const void *ptr, size_t len); + void BadReadHandler(int sig); + + bool g_BadReadCalled; + jmp_buf g_BadReadJmpBuf; +#endif } #endif