diff options
author | ludwig <ludwig@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2006-03-04 11:14:44 +0000 |
---|---|---|
committer | ludwig <ludwig@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2006-03-04 11:14:44 +0000 |
commit | 9faab37c4c3dd92ce003cd4c177d1cd1fc3bf0e7 (patch) | |
tree | 902ff072baaea7223d055b81b2bafa54831890e7 /code/qcommon/vm_x86.c | |
parent | bb50a3f642af15c8e268c19c930c4481631f7e35 (diff) | |
download | ioquake3-aero-9faab37c4c3dd92ce003cd4c177d1cd1fc3bf0e7.tar.gz ioquake3-aero-9faab37c4c3dd92ce003cd4c177d1cd1fc3bf0e7.zip |
use mmap to allocate memory for generated code to be able to set PROT_EXEC
git-svn-id: svn://svn.icculus.org/quake3/trunk@616 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/qcommon/vm_x86.c')
-rw-r--r-- | code/qcommon/vm_x86.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/code/qcommon/vm_x86.c b/code/qcommon/vm_x86.c index f9677e9..7a0c162 100644 --- a/code/qcommon/vm_x86.c +++ b/code/qcommon/vm_x86.c @@ -31,6 +31,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include <sys/mman.h> // for PROT_ stuff #endif +/* need this on NX enabled systems (i386 with PAE kernel or + * noexec32=on x86_64) */ +#ifdef __linux__ +#define VM_X86_MMAP +#endif + +static void VM_Destroy_Compiled(vm_t* self); + /* eax scratch @@ -1069,34 +1077,40 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) { // copy to an exact size buffer on the hunk vm->codeLength = compiledOfs; - vm->codeBase = Hunk_Alloc( compiledOfs, h_low ); +#ifdef VM_X86_MMAP + vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); + if(vm->codeBase == (void*)-1) + Com_Error(ERR_DROP, "VM_CompileX86: can't mmap memory"); +#else + vm->codeBase = malloc(compiledOfs); +#endif + Com_Memcpy( vm->codeBase, buf, compiledOfs ); + +#ifdef VM_X86_MMAP + if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC)) + Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed"); +#endif + Z_Free( buf ); Z_Free( jused ); Com_Printf( "VM file %s compiled to %i bytes of code\n", vm->name, compiledOfs ); + vm->destroy = VM_Destroy_Compiled; + // offset all the instruction pointers for the new location for ( i = 0 ; i < header->instructionCount ; i++ ) { vm->instructionPointers[i] += (int)vm->codeBase; } +} -#if 0 // ndef _WIN32 - // Must make the newly generated code executable - { - int r; - unsigned long addr; - int psize = getpagesize(); - - addr = ((int)vm->codeBase & ~(psize-1)) - psize; - - r = mprotect((char*)addr, vm->codeLength + (int)vm->codeBase - addr + psize, - PROT_READ | PROT_WRITE | PROT_EXEC ); - - if (r < 0) - Com_Error( ERR_FATAL, "mprotect failed to change PROT_EXEC" ); - } +void VM_Destroy_Compiled(vm_t* self) +{ +#ifdef VM_X86_MMAP + munmap(self->codeBase, self->codeLength); +#else + free(self->codeBase); #endif - } /* |