From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jesse Buhagiar Date: Sat, 26 Mar 2022 00:08:46 +1100 Subject: [PATCH] Engine: Use Serenity style PROT_EXEC mmap The code for this was really old and crusty, so let's `ifdef` it out and use some more friendly Serenity style memory code. --- code/qcommon/vm_x86.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/code/qcommon/vm_x86.c b/code/qcommon/vm_x86.c index 8d6321a..d155efc 100644 --- a/code/qcommon/vm_x86.c +++ b/code/qcommon/vm_x86.c @@ -42,6 +42,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif #endif +#ifdef __serenity__ +#include +#include // for `pledge()` +#include +#endif + #if defined (__i386__) || defined(__x86_64__) static void VM_Destroy_Compiled(vm_t* self); @@ -1649,9 +1655,24 @@ void VM_Compile(vm_t *vm, vmHeader_t *header) // copy to an exact sized buffer with the appropriate permission bits vm->codeLength = compiledOfs; #ifdef VM_X86_MMAP +#ifdef __serenity__ + // Round up by a page for `anon_create` (so we don't blow up in the Kernel) + int compiledOfsPageAligned = compiledOfs + (4096u - (compiledOfs % 4096u)); + + // Create the fd... + int fd = anon_create(compiledOfsPageAligned, O_CLOEXEC); + if (fd == -1) + Com_Error(ERR_FATAL, "VM_CompileX86: anon_create failed (a very bad thing!)"); + + vm->codeBase = mmap_with_name(NULL, compiledOfs, PROT_WRITE|PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0, "Quake3 VM Page"); + if(vm->codeBase == MAP_FAILED) + Com_Error(ERR_FATAL, "VM_CompileX86: can't mmap memory"); + close(fd); +#else vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if(vm->codeBase == MAP_FAILED) Com_Error(ERR_FATAL, "VM_CompileX86: can't mmap memory"); +#endif #elif _WIN32 // allocate memory with EXECUTE permissions under windows. vm->codeBase = VirtualAlloc(NULL, compiledOfs, MEM_COMMIT, PAGE_EXECUTE_READWRITE); @@ -1665,9 +1686,13 @@ void VM_Compile(vm_t *vm, vmHeader_t *header) Com_Memcpy( vm->codeBase, buf, compiledOfs ); + #ifdef VM_X86_MMAP - if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC)) - Com_Error(ERR_FATAL, "VM_CompileX86: mprotect failed"); +#ifndef __serenity__ + int rc = mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC); + if(rc) + Com_Error(ERR_FATAL, "VM_CompileX86: mprotect failed with %d", rc); +#endif #elif _WIN32 { DWORD oldProtect = 0;