mirror of
https://github.com/ZDoom/zdbsp.git
synced 2024-11-22 03:41:29 +00:00
- Added backpatching support to systems with mprotect() (e.g. Linux).
SVN r2412 (trunk)
This commit is contained in:
parent
08216817e5
commit
733b292130
2 changed files with 25 additions and 2 deletions
|
@ -34,7 +34,12 @@ if( SSE_MATTERS )
|
||||||
if( WIN32 )
|
if( WIN32 )
|
||||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||||
else( WIN32 )
|
else( WIN32 )
|
||||||
|
CHECK_FUNCTION_EXISTS(mprotect HAVE_MPROTECT)
|
||||||
|
if( HAVE_MPROTECT )
|
||||||
|
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||||
|
else( HAVE_MPROTECT )
|
||||||
set( BACKPATCH 0 )
|
set( BACKPATCH 0 )
|
||||||
|
endif( HAVE_MPROTECT )
|
||||||
endif( WIN32 )
|
endif( WIN32 )
|
||||||
set( FULL_SSE2 0 CACHE BOOL "Use SSE2 math everywhere." )
|
set( FULL_SSE2 0 CACHE BOOL "Use SSE2 math everywhere." )
|
||||||
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
||||||
|
|
|
@ -1054,8 +1054,13 @@ void FNodeBuilder::PrintSet (int l, DWORD set)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BACKPATCH
|
#ifdef BACKPATCH
|
||||||
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
extern "C" int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
extern "C" int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||||
|
@ -1076,7 +1081,7 @@ int ClassifyLineBackpatchC (node_t &node, const FSimpleVert *v1, const FSimpleVe
|
||||||
#else
|
#else
|
||||||
calleroffset = CallerOffset;
|
calleroffset = CallerOffset;
|
||||||
#endif
|
#endif
|
||||||
// printf ("Patching for SSE %d\n", SSELevel);
|
// printf ("Patching for SSE %d @ %p %d\n", SSELevel, calleroffset, *calleroffset);
|
||||||
|
|
||||||
if (SSELevel == 2)
|
if (SSELevel == 2)
|
||||||
{
|
{
|
||||||
|
@ -1095,10 +1100,23 @@ int ClassifyLineBackpatchC (node_t &node, const FSimpleVert *v1, const FSimpleVe
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch the caller.
|
// Patch the caller.
|
||||||
|
#ifdef _WIN32
|
||||||
if (VirtualProtect (calleroffset, 4, PAGE_EXECUTE_READWRITE, &oldprotect))
|
if (VirtualProtect (calleroffset, 4, PAGE_EXECUTE_READWRITE, &oldprotect))
|
||||||
|
#else
|
||||||
|
// must make this page-aligned for mprotect
|
||||||
|
long pagesize = sysconf(_SC_PAGESIZE);
|
||||||
|
char *callerpage = (char *)((intptr_t)calleroffset & ~(pagesize - 1));
|
||||||
|
size_t protectlen = (intptr_t)calleroffset + 4 - (intptr_t)callerpage;
|
||||||
|
int ptect;
|
||||||
|
if (!(ptect = mprotect(callerpage, protectlen, PROT_READ|PROT_WRITE|PROT_EXEC)))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
*calleroffset += diff;
|
*calleroffset += diff;
|
||||||
|
#ifdef _WIN32
|
||||||
VirtualProtect (calleroffset, 4, oldprotect, &oldprotect);
|
VirtualProtect (calleroffset, 4, oldprotect, &oldprotect);
|
||||||
|
#else
|
||||||
|
mprotect(callerpage, protectlen, PROT_READ|PROT_EXEC);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// And return by calling the real function.
|
// And return by calling the real function.
|
||||||
|
|
Loading…
Reference in a new issue