diff options
Diffstat (limited to 'src/qcommon/vm_x86_64.c')
-rw-r--r-- | src/qcommon/vm_x86_64.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/src/qcommon/vm_x86_64.c b/src/qcommon/vm_x86_64.c index 13c39172..6b335447 100644 --- a/src/qcommon/vm_x86_64.c +++ b/src/qcommon/vm_x86_64.c @@ -55,6 +55,8 @@ static FILE* qdasmout; #define Dfprintf(args...) #endif +#define VM_FREEBUFFERS(vm) do {assembler_init(0); VM_Destroy_Compiled(vm);} while(0) + void assembler_set_output(char* buf); size_t assembler_get_code_size(void); void assembler_init(int pass); @@ -252,6 +254,7 @@ void emit(const char* fmt, ...) #define CHECK_INSTR(nr) \ do { if(nr < 0 || nr >= header->instructionCount) { \ + VM_FREEBUFFERS(vm); \ Com_Error( ERR_DROP, \ "%s: jump target 0x%x out of range at offset %d", __func__, nr, pc ); \ } } while(0) @@ -430,6 +433,8 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) { // const optimization unsigned got_const = 0, const_value = 0; + + vm->codeBase = NULL; gettimeofday(&tvstart, NULL); @@ -442,15 +447,17 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) { #ifdef VM_X86_64_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"); + if(vm->codeBase == MAP_FAILED) + Com_Error(ERR_FATAL, "VM_CompileX86_64: can't mmap memory"); #elif __WIN64__ // allocate memory with write permissions under windows. vm->codeBase = VirtualAlloc(NULL, compiledOfs, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); if(!vm->codeBase) - Com_Error(ERR_DROP, "VM_CompileX86: VirtualAlloc failed"); + Com_Error(ERR_FATAL, "VM_CompileX86_64: VirtualAlloc failed"); #else vm->codeBase = malloc(compiledOfs); + if(!vm_codeBase) + Com_Error(ERR_FATAL, "VM_CompileX86_64: Failed to allocate memory"); #endif assembler_set_output((char*)vm->codeBase); @@ -931,7 +938,9 @@ emit_do_syscall: } - if(got_const) { + if(got_const) + { + VM_FREEBUFFERS(vm); Com_Error(ERR_DROP, "leftover const\n"); } @@ -944,14 +953,14 @@ emit_do_syscall: #ifdef VM_X86_64_MMAP if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC)) - Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed"); + Com_Error(ERR_FATAL, "VM_CompileX86_64: mprotect failed"); #elif __WIN64__ { DWORD oldProtect = 0; // remove write permissions; give exec permision if(!VirtualProtect(vm->codeBase, compiledOfs, PAGE_EXECUTE_READ, &oldProtect)) - Com_Error(ERR_DROP, "VM_CompileX86: VirtualProtect failed"); + Com_Error(ERR_FATAL, "VM_CompileX86_64: VirtualProtect failed"); } #endif @@ -988,11 +997,16 @@ emit_do_syscall: void VM_Destroy_Compiled(vm_t* self) { -#ifdef _WIN32 - VirtualFree(self->codeBase, 0, MEM_RELEASE); + if(self && self->codeBase) + { +#ifdef VM_X86_64_MMAP + munmap(self->codeBase, self->codeLength); +#elif __WIN64__ + VirtualFree(self->codeBase, 0, MEM_RELEASE); #else - munmap(self->codeBase, self->codeLength); + free(self->codeBase); #endif + } } /* |