mirror of
https://github.com/ZDoom/zdbsp.git
synced 2024-11-10 06:31:35 +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 )
|
||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||
else( WIN32 )
|
||||
set( BACKPATCH 0 )
|
||||
CHECK_FUNCTION_EXISTS(mprotect HAVE_MPROTECT)
|
||||
if( HAVE_MPROTECT )
|
||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||
else( HAVE_MPROTECT )
|
||||
set( BACKPATCH 0 )
|
||||
endif( HAVE_MPROTECT )
|
||||
endif( WIN32 )
|
||||
set( FULL_SSE2 0 CACHE BOOL "Use SSE2 math everywhere." )
|
||||
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 _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
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
|
||||
calleroffset = CallerOffset;
|
||||
#endif
|
||||
// printf ("Patching for SSE %d\n", SSELevel);
|
||||
// printf ("Patching for SSE %d @ %p %d\n", SSELevel, calleroffset, *calleroffset);
|
||||
|
||||
if (SSELevel == 2)
|
||||
{
|
||||
|
@ -1095,10 +1100,23 @@ int ClassifyLineBackpatchC (node_t &node, const FSimpleVert *v1, const FSimpleVe
|
|||
}
|
||||
|
||||
// Patch the caller.
|
||||
#ifdef _WIN32
|
||||
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;
|
||||
#ifdef _WIN32
|
||||
VirtualProtect (calleroffset, 4, oldprotect, &oldprotect);
|
||||
#else
|
||||
mprotect(callerpage, protectlen, PROT_READ|PROT_EXEC);
|
||||
#endif
|
||||
}
|
||||
|
||||
// And return by calling the real function.
|
||||
|
|
Loading…
Reference in a new issue