diff options
author | Tim Angus <tim@ngus.net> | 2011-01-24 22:07:34 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:17:54 +0000 |
commit | f96ae257eab6fae9b4b4f4409c58dbce6915ac35 (patch) | |
tree | c9828a3c3726d4b260493a710fd1f2f9f7bc6056 /src/qcommon | |
parent | a0101a6294268ef392b3fa4ecad12706e6cf4cf3 (diff) |
* Merge ioq3-r1813
Diffstat (limited to 'src/qcommon')
-rw-r--r-- | src/qcommon/common.c | 20 | ||||
-rw-r--r-- | src/qcommon/msg.c | 8 | ||||
-rw-r--r-- | src/qcommon/net_ip.c | 73 | ||||
-rw-r--r-- | src/qcommon/q_platform.h | 33 | ||||
-rw-r--r-- | src/qcommon/q_shared.h | 2 | ||||
-rw-r--r-- | src/qcommon/qcommon.h | 26 | ||||
-rw-r--r-- | src/qcommon/vm_interpreted.c | 24 | ||||
-rw-r--r-- | src/qcommon/vm_x86.c | 2 | ||||
-rw-r--r-- | src/qcommon/vm_x86_64.c | 113 | ||||
-rw-r--r-- | src/qcommon/vm_x86_64_assembler.c | 30 |
10 files changed, 221 insertions, 110 deletions
diff --git a/src/qcommon/common.c b/src/qcommon/common.c index d9fb4495..38902e92 100644 --- a/src/qcommon/common.c +++ b/src/qcommon/common.c @@ -82,6 +82,7 @@ cvar_t *com_unfocused; cvar_t *com_maxfpsUnfocused; cvar_t *com_minimized; cvar_t *com_maxfpsMinimized; +cvar_t *com_abnormalExit; // com_speeds times int time_game; @@ -238,7 +239,7 @@ void QDECL Com_DPrintf( const char *fmt, ...) { Com_Error Both client and server can use this, and it will -do the apropriate things. +do the appropriate thing. ============= */ void QDECL Com_Error( int code, const char *fmt, ... ) { @@ -323,7 +324,7 @@ void QDECL Com_Error( int code, const char *fmt, ... ) { com_errorEntered = qfalse; longjmp (abortframe, -1); } else { - CL_Shutdown (); + CL_Shutdown (va("Client fatal crashed: %s", com_errorMessage)); SV_Shutdown (va("Server fatal crashed: %s", com_errorMessage)); } @@ -347,7 +348,7 @@ void Com_Quit_f( void ) { char *p = Cmd_Args( ); if ( !com_errorEntered ) { SV_Shutdown (p[0] ? p : "Server quit"); - CL_Shutdown (); + CL_Shutdown (p[0] ? p : "Client quit"); Com_Shutdown (); FS_Shutdown(qtrue); } @@ -2616,12 +2617,25 @@ void Com_Init( char *commandLine ) { com_maxfpsUnfocused = Cvar_Get( "com_maxfpsUnfocused", "0", CVAR_ARCHIVE ); com_minimized = Cvar_Get( "com_minimized", "0", CVAR_ROM ); com_maxfpsMinimized = Cvar_Get( "com_maxfpsMinimized", "0", CVAR_ARCHIVE ); + com_abnormalExit = Cvar_Get( "com_abnormalExit", "0", CVAR_ROM ); s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ ); com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO ); Sys_Init(); + if( Sys_WritePIDFile( ) ) { +#ifndef DEDICATED + const char *message = "The last time " CLIENT_WINDOW_TITLE " ran, " + "it didn't exit properly. This may be due to inappropriate video " + "settings. Would you like to start with \"safe\" video settings?"; + + if( Sys_Dialog( DT_YES_NO, message, "Abnormal Exit" ) == DR_YES ) { + Cvar_Set( "com_abnormalExit", "1" ); + } +#endif + } + // Pick a random port value Com_RandomBytes( (byte*)&qport, sizeof(int) ); Netchan_Init( qport & 0xffff ); diff --git a/src/qcommon/msg.c b/src/qcommon/msg.c index c85360c4..ba956bc8 100644 --- a/src/qcommon/msg.c +++ b/src/qcommon/msg.c @@ -1033,6 +1033,10 @@ void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to, numFields = sizeof(entityStateFields)/sizeof(entityStateFields[0]); lc = MSG_ReadByte(msg); + if ( lc > numFields || lc < 0 ) { + Com_Error( ERR_DROP, "invalid entityState field count" ); + } + // shownet 2/3 will interleave with other printed info, -1 will // just print the delta records` if ( cl_shownet->integer >= 2 || cl_shownet->integer == -1 ) { @@ -1352,6 +1356,10 @@ void MSG_ReadDeltaPlayerstate (msg_t *msg, playerState_t *from, playerState_t *t numFields = sizeof( playerStateFields ) / sizeof( playerStateFields[0] ); lc = MSG_ReadByte(msg); + if ( lc > numFields || lc < 0 ) { + Com_Error( ERR_DROP, "invalid playerState field count" ); + } + for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) { fromF = (int *)( (byte *)from + field->offset ); toF = (int *)( (byte *)to + field->offset ); diff --git a/src/qcommon/net_ip.c b/src/qcommon/net_ip.c index 2be40a86..c1e527c5 100644 --- a/src/qcommon/net_ip.c +++ b/src/qcommon/net_ip.c @@ -310,11 +310,11 @@ static qboolean Sys_StringToSockaddr(const char *s, struct sockaddr *sadr, int s if(search) { - if(res->ai_addrlen > sadr_len) - res->ai_addrlen = sadr_len; + if(search->ai_addrlen > sadr_len) + search->ai_addrlen = sadr_len; - memcpy(sadr, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); + memcpy(sadr, search->ai_addr, search->ai_addrlen); + freeaddrinfo(search); return qtrue; } @@ -853,9 +853,6 @@ int NET_IPSocket( char *net_interface, int port, int *err ) { // make it broadcast capable if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i) ) == SOCKET_ERROR ) { Com_Printf( "WARNING: NET_IPSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() ); - - // it is not that bad if this one fails. -// return newsocket; } if( !net_interface || !net_interface[0]) { @@ -1035,28 +1032,28 @@ void NET_JoinMulticast6(void) if(curgroup.ipv6mr_interface) { if (setsockopt(multicast6_socket, IPPROTO_IPV6, IPV6_MULTICAST_IF, - (char *) &curgroup.ipv6mr_interface, sizeof(curgroup.ipv6mr_interface)) < 0) + (char *) &curgroup.ipv6mr_interface, sizeof(curgroup.ipv6mr_interface)) < 0) { - Com_Printf("NET_JoinMulticast6: Couldn't set scope on multicast socket: %s\n", NET_ErrorString()); + Com_Printf("NET_JoinMulticast6: Couldn't set scope on multicast socket: %s\n", NET_ErrorString()); - if(multicast6_socket != ip6_socket) - { - closesocket(multicast6_socket); - multicast6_socket = INVALID_SOCKET; - return; + if(multicast6_socket != ip6_socket) + { + closesocket(multicast6_socket); + multicast6_socket = INVALID_SOCKET; + return; } } - } - - if (setsockopt(multicast6_socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *) &curgroup, sizeof(curgroup))) - { - Com_Printf("NET_JoinMulticast6: Couldn't join multicast group: %s\n", NET_ErrorString()); - - if(multicast6_socket != ip6_socket) - { - closesocket(multicast6_socket); - multicast6_socket = INVALID_SOCKET; - return; + } + + if (setsockopt(multicast6_socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *) &curgroup, sizeof(curgroup))) + { + Com_Printf("NET_JoinMulticast6: Couldn't join multicast group: %s\n", NET_ErrorString()); + + if(multicast6_socket != ip6_socket) + { + closesocket(multicast6_socket); + multicast6_socket = INVALID_SOCKET; + return; } } } @@ -1253,10 +1250,10 @@ void NET_OpenSocks( int port ) { /* ===================== -NET_GetLocalAddress +NET_AddLocalAddress ===================== */ -void NET_AddLocalAddress(char *ifname, struct sockaddr *addr, struct sockaddr *netmask) +static void NET_AddLocalAddress(char *ifname, struct sockaddr *addr, struct sockaddr *netmask) { int addrlen; sa_family_t family; @@ -1294,7 +1291,7 @@ void NET_AddLocalAddress(char *ifname, struct sockaddr *addr, struct sockaddr *n } #if defined(__linux__) || defined(MACOSX) || defined(__BSD__) -void NET_GetLocalAddress(void) +static void NET_GetLocalAddress(void) { struct ifaddrs *ifap, *search; @@ -1315,10 +1312,10 @@ void NET_GetLocalAddress(void) } } #else -void NET_GetLocalAddress( void ) { +static void NET_GetLocalAddress( void ) { char hostname[256]; - struct addrinfo hint; - struct addrinfo *res = NULL; + struct addrinfo hint; + struct addrinfo *res = NULL; if(gethostname( hostname, 256 ) == SOCKET_ERROR) return; @@ -1334,7 +1331,7 @@ void NET_GetLocalAddress( void ) { { struct sockaddr_in mask4; struct sockaddr_in6 mask6; - struct addrinfo *search; + struct addrinfo *search; /* On operating systems where it's more difficult to find out the configured interfaces, we'll just assume a * netmask with all bits set. */ @@ -1476,27 +1473,27 @@ static qboolean NET_GetCvars( void ) { #else net_mcast6iface = Cvar_Get( "net_mcast6iface", "", CVAR_LATCH | CVAR_ARCHIVE ); #endif - modified += net_mcast6iface->modified; + modified += net_mcast6iface->modified; net_mcast6iface->modified = qfalse; net_socksEnabled = Cvar_Get( "net_socksEnabled", "0", CVAR_LATCH | CVAR_ARCHIVE ); - modified += net_socksEnabled->modified; + modified += net_socksEnabled->modified; net_socksEnabled->modified = qfalse; net_socksServer = Cvar_Get( "net_socksServer", "", CVAR_LATCH | CVAR_ARCHIVE ); - modified += net_socksServer->modified; + modified += net_socksServer->modified; net_socksServer->modified = qfalse; net_socksPort = Cvar_Get( "net_socksPort", "1080", CVAR_LATCH | CVAR_ARCHIVE ); - modified += net_socksPort->modified; + modified += net_socksPort->modified; net_socksPort->modified = qfalse; net_socksUsername = Cvar_Get( "net_socksUsername", "", CVAR_LATCH | CVAR_ARCHIVE ); - modified += net_socksUsername->modified; + modified += net_socksUsername->modified; net_socksUsername->modified = qfalse; net_socksPassword = Cvar_Get( "net_socksPassword", "", CVAR_LATCH | CVAR_ARCHIVE ); - modified += net_socksPassword->modified; + modified += net_socksPassword->modified; net_socksPassword->modified = qfalse; return modified ? qtrue : qfalse; diff --git a/src/qcommon/q_platform.h b/src/qcommon/q_platform.h index 9405e749..4d4d2856 100644 --- a/src/qcommon/q_platform.h +++ b/src/qcommon/q_platform.h @@ -73,9 +73,33 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // for windows fastcall option #define QDECL -//================================================================= WIN32 === +//================================================================= WIN64/32 === -#ifdef _WIN32 +#if defined(_WIN64) || defined(__WIN64__) + +#undef QDECL +#define QDECL __cdecl + +#if defined( _MSC_VER ) +#define OS_STRING "win_msvc64" +#elif defined __MINGW64__ +#define OS_STRING "win_mingw64" +#endif + +#define ID_INLINE inline +#define PATH_SEP '\\' + +#if defined( __WIN64__ ) +#define ARCH_STRING "x86_64" +#elif defined _M_ALPHA +#define ARCH_STRING "AXP" +#endif + +#define Q3_LITTLE_ENDIAN + +#define DLL_EXT ".dll" + +#elif defined(_WIN32) || defined(__WIN32__) #undef QDECL #define QDECL __cdecl @@ -120,6 +144,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #elif defined __i386__ #define ARCH_STRING "x86" #define Q3_LITTLE_ENDIAN +#elif defined __x86_64__ +#define ARCH_STRING "x86_64" +#define Q3_LITTLE_ENDIAN #endif #define DLL_EXT ".dylib" @@ -201,7 +228,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ifdef __i386__ #define ARCH_STRING "x86" #elif defined __amd64__ -#define ARCH_STRING "x86_64" +#define ARCH_STRING "amd64" #elif defined __axp__ #define ARCH_STRING "alpha" #endif diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h index 44685582..3f2cb9d5 100644 --- a/src/qcommon/q_shared.h +++ b/src/qcommon/q_shared.h @@ -184,6 +184,8 @@ typedef int clipHandle_t; #define MAX_QINT 0x7fffffff #define MIN_QINT (-MAX_QINT-1) +#define ARRAY_LEN(x) (sizeof(x) / sizeof(*x)) + // angle indexes #define PITCH 0 // up / down diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h index 18f4c5e5..09132159 100644 --- a/src/qcommon/qcommon.h +++ b/src/qcommon/qcommon.h @@ -179,7 +179,7 @@ qboolean NET_CompareBaseAdrMask(netadr_t a, netadr_t b, int netmask); qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); qboolean NET_IsLocalAddress (netadr_t adr); const char *NET_AdrToString (netadr_t a); -const char *NET_AdrToStringwPort (netadr_t a); +const char *NET_AdrToStringwPort (netadr_t a); int NET_StringToAdr ( const char *s, netadr_t *a, netadrtype_t family); qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, msg_t *net_message); void NET_JoinMulticast6(void); @@ -923,7 +923,7 @@ void CL_InitKeyCommands( void ); void CL_Init( void ); void CL_Disconnect( qboolean showMainMenu ); -void CL_Shutdown( void ); +void CL_Shutdown( char *finalmsg ); void CL_Frame( int msec ); qboolean CL_GameCommand( void ); void CL_KeyEvent (int key, qboolean down, unsigned time); @@ -1072,6 +1072,7 @@ char *Sys_DefaultAppPath(void); void Sys_SetDefaultHomePath(const char *path); char *Sys_DefaultHomePath(void); +const char *Sys_TempPath(void); const char *Sys_Dirname( char *path ); const char *Sys_Basename( char *path ); char *Sys_ConsoleInput(void); @@ -1084,6 +1085,27 @@ qboolean Sys_LowPhysicalMemory( void ); void Sys_SetEnv(const char *name, const char *value); +typedef enum +{ + DR_YES = 0, + DR_NO = 1, + DR_OK = 0, + DR_CANCEL = 1 +} dialogResult_t; + +typedef enum +{ + DT_INFO, + DT_WARNING, + DT_ERROR, + DT_YES_NO, + DT_OK_CANCEL +} dialogType_t; + +dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title ); + +qboolean Sys_WritePIDFile( void ); + /* This is based on the Adaptive Huffman algorithm described in Sayood's Data * Compression book. The ranks are not actually stored, but implicitly defined * by the location of a node within a doubly-linked list */ diff --git a/src/qcommon/vm_interpreted.c b/src/qcommon/vm_interpreted.c index 53357f5d..2b9ffea6 100644 --- a/src/qcommon/vm_interpreted.c +++ b/src/qcommon/vm_interpreted.c @@ -517,18 +517,20 @@ nextInstruction2: //VM_LogSyscalls( (int *)&image[ programStack + 4 ] ); { - intptr_t* argptr = (intptr_t *)&image[ programStack + 4 ]; - #if __WORDSIZE == 64 - // the vm has ints on the stack, we expect - // longs so we have to convert it - intptr_t argarr[16]; - int i; - for (i = 0; i < 16; ++i) { - argarr[i] = *(int*)&image[ programStack + 4 + 4*i ]; + // the vm has ints on the stack, we expect + // pointers so we might have to convert it + if (sizeof(intptr_t) != sizeof(int)) { + intptr_t argarr[16]; + int *imagePtr = (int *)&image[programStack]; + int i; + for (i = 0; i < 16; ++i) { + argarr[i] = *(++imagePtr); + } + r = vm->systemCall( argarr ); + } else { + intptr_t* argptr = (intptr_t *)&image[ programStack + 4 ]; + r = vm->systemCall( argptr ); } - argptr = argarr; - #endif - r = vm->systemCall( argptr ); } #ifdef DEBUG_VM diff --git a/src/qcommon/vm_x86.c b/src/qcommon/vm_x86.c index dc7f5a67..41806f2a 100644 --- a/src/qcommon/vm_x86.c +++ b/src/qcommon/vm_x86.c @@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* need this on NX enabled systems (i386 with PAE kernel or * noexec32=on x86_64) */ -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) #define VM_X86_MMAP #endif diff --git a/src/qcommon/vm_x86_64.c b/src/qcommon/vm_x86_64.c index 93e25f6d..13c39172 100644 --- a/src/qcommon/vm_x86_64.c +++ b/src/qcommon/vm_x86_64.c @@ -24,11 +24,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // vm_x86_64.c -- load time compiler and execution environment for x86-64 #include "vm_local.h" - -#include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> -#include <sys/wait.h> #include <sys/time.h> #include <time.h> #include <fcntl.h> @@ -36,6 +33,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include <unistd.h> #include <stdarg.h> +#include <inttypes.h> + +#ifdef __WIN64__ + #include <windows.h> + #define CROSSCALL __attribute__ ((sysv_abi))//fool the vm we're SYSV ABI + //#define __USE_MINGW_ANSI_STDIO 1 //very slow - avoid if possible +#else + #include <sys/mman.h> + #include <sys/wait.h> + #define VM_X86_64_MMAP + #define CROSSCALL +#endif + //#define DEBUG_VM #ifdef DEBUG_VM @@ -45,8 +55,6 @@ static FILE* qdasmout; #define Dfprintf(args...) #endif -#define VM_X86_64_MMAP - void assembler_set_output(char* buf); size_t assembler_get_code_size(void); void assembler_init(int pass); @@ -72,11 +80,11 @@ static void VM_Destroy_Compiled(vm_t* self); */ -static long callAsmCall(long callProgramStack, long callSyscallNum) +static int64_t CROSSCALL callAsmCall(int64_t callProgramStack, int64_t callSyscallNum) { vm_t *savedVM; - long ret = 0x77; - long args[11]; + int64_t ret = 0x77; + int64_t args[11]; // int iargs[11]; int i; @@ -232,13 +240,13 @@ void emit(const char* fmt, ...) #define CHECK_INSTR_REG(reg) \ emit("cmpl $%u, %%"#reg, header->instructionCount); \ emit("jb jmp_ok_i_%08x", instruction); \ - emit("movq $%lu, %%rax", (unsigned long)jmpviolation); \ + emit("movq $%"PRIu64", %%rax", (uint64_t)jmpviolation); \ emit("callq *%%rax"); \ emit("jmp_ok_i_%08x:", instruction); #define PREPARE_JMP(reg) \ CHECK_INSTR_REG(reg) \ - emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers); \ + emit("movq $%"PRIu64", %%rbx", (uint64_t)vm->instructionPointers); \ emit("movl (%%rbx, %%rax, 4), %%eax"); \ emit("addq %%r10, %%rax"); @@ -250,7 +258,7 @@ void emit(const char* fmt, ...) #define JMPIARG \ CHECK_INSTR(iarg); \ - emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[iarg]); \ + emit("movq $%"PRIu64", %%rax", vm->codeBase+vm->instructionPointers[iarg]); \ emit("jmpq *%%rax"); #define CONST_OPTIMIZE @@ -340,7 +348,7 @@ void emit(const char* fmt, ...) emit("andl $0x%x, %%ecx", vm->dataMask &~(bytes-1)); \ emit("cmpl %%" #reg ", %%ecx"); \ emit("jz rc_ok_i_%08x", instruction); \ - emit("movq $%lu, %%rax", (unsigned long)memviolation); \ + emit("movq $%"PRIu64", %%rax", (uint64_t)memviolation); \ emit("callq *%%rax"); \ emit("rc_ok_i_%08x:", instruction); #elif 1 @@ -364,7 +372,7 @@ static void* getentrypoint(vm_t* vm) return vm->codeBase; } -static void block_copy_vm(unsigned dest, unsigned src, unsigned count) +static void CROSSCALL block_copy_vm(unsigned dest, unsigned src, unsigned count) { unsigned dataMask = currentVM->dataMask; @@ -379,20 +387,20 @@ static void block_copy_vm(unsigned dest, unsigned src, unsigned count) memcpy(currentVM->dataBase+dest, currentVM->dataBase+src, count); } -static void eop(void) +static void CROSSCALL eop(void) { Com_Error(ERR_DROP, "end of program reached without return!\n"); exit(1); } -static void jmpviolation(void) +static void CROSSCALL jmpviolation(void) { Com_Error(ERR_DROP, "program tried to execute code outside VM\n"); exit(1); } #ifdef DEBUG_VM -static void memviolation(void) +static void CROSSCALL memviolation(void) { Com_Error(ERR_DROP, "program tried to access memory outside VM\n"); exit(1); @@ -431,9 +439,19 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) { { compiledOfs = assembler_get_code_size(); vm->codeLength = compiledOfs; - 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"); + + #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"); + #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"); + #else + vm->codeBase = malloc(compiledOfs); + #endif assembler_set_output((char*)vm->codeBase); } @@ -474,7 +492,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) { else if(op_argsize[op] == 1) { barg = code[pc++]; - Dfprintf(qdasmout, "%s %8hhu\n", opnames[op], barg); + Dfprintf(qdasmout, "%s %8hu\n", opnames[op], barg); } else { @@ -518,7 +536,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) { goto emit_do_syscall; CHECK_INSTR(const_value); - emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[const_value]); + emit("movq $%"PRIu64", %%rax", vm->codeBase+vm->instructionPointers[const_value]); emit("callq *%%rax"); got_const = 0; break; @@ -559,7 +577,7 @@ emit_do_syscall: // first argument already in rdi emit("movq %%rax, %%rsi"); // second argument in rsi } - emit("movq $%lu, %%rax", (unsigned long)callAsmCall); + emit("movq $%"PRIu64", %%rax", (uint64_t)callAsmCall); emit("callq *%%rax"); emit("pop %%rbx"); emit("addq %%rbx, %%rsp"); @@ -726,7 +744,7 @@ emit_do_syscall: MAYBE_EMIT_CONST(); emit("subq $4, %%rsi"); emit("movl 4(%%rsi), %%eax"); // get value from stack - emit("movl $0x%hhx, %%ebx", barg); + emit("movl $0x%hx, %%ebx", barg); emit("addl %%edi, %%ebx"); RANGECHECK(ebx, 4); emit("movl %%eax, 0(%%r8,%%rbx, 1)"); // store in args space @@ -740,11 +758,18 @@ emit_do_syscall: emit("push %%r8"); emit("push %%r9"); emit("push %%r10"); + emit("movq %%rsp, %%rbx"); // we need to align the stack pointer + emit("subq $8, %%rbx"); // | + emit("andq $127, %%rbx"); // | + emit("subq %%rbx, %%rsp"); // <-+ + emit("push %%rbx"); emit("movl 4(%%rsi), %%edi"); // 1st argument dest emit("movl 8(%%rsi), %%esi"); // 2nd argument src emit("movl $%d, %%edx", iarg); // 3rd argument count - emit("movq $%lu, %%rax", (unsigned long)block_copy_vm); + emit("movq $%"PRIu64", %%rax", (uint64_t)block_copy_vm); emit("callq *%%rax"); + emit("pop %%rbx"); + emit("addq %%rbx, %%rsp"); emit("pop %%r10"); emit("pop %%r9"); emit("pop %%r8"); @@ -910,15 +935,25 @@ emit_do_syscall: Com_Error(ERR_DROP, "leftover const\n"); } - emit("movq $%lu, %%rax", (unsigned long)eop); + emit("movq $%"PRIu64", %%rax", (uint64_t)eop); emit("callq *%%rax"); } // pass loop assembler_init(0); - if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC)) - Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed"); + #ifdef VM_X86_64_MMAP + if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC)) + Com_Error(ERR_DROP, "VM_CompileX86: 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"); + } + #endif vm->destroy = VM_Destroy_Compiled; @@ -935,17 +970,19 @@ emit_do_syscall: fclose(qdasmout); #endif #endif - - if(vm->compiled) - { - struct timeval tvdone = {0, 0}; - struct timeval dur = {0, 0}; - Com_Printf( "VM file %s compiled to %i bytes of code (%p - %p)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength ); - gettimeofday(&tvdone, NULL); - timersub(&tvdone, &tvstart, &dur); - Com_Printf( "compilation took %lu.%06lu seconds\n", dur.tv_sec, dur.tv_usec ); - } + #ifndef __WIN64__ //timersub and gettimeofday + if(vm->compiled) + { + struct timeval tvdone = {0, 0}; + struct timeval dur = {0, 0}; + Com_Printf( "VM file %s compiled to %i bytes of code (%p - %p)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength ); + + gettimeofday(&tvdone, NULL); + timersub(&tvdone, &tvstart, &dur); + Com_Printf( "compilation took %"PRIu64".%06"PRIu64" seconds\n", dur.tv_sec, dur.tv_usec ); + } + #endif } @@ -1035,7 +1072,7 @@ int VM_CallCompiled( vm_t *vm, int *args ) { ); if ( opStack != &stack[1] ) { - Com_Error( ERR_DROP, "opStack corrupted in compiled code (offset %ld)\n", (long int) ((void *) &stack[1] - opStack)); + Com_Error( ERR_DROP, "opStack corrupted in compiled code (offset %"PRId64")\n", (int64_t) ((void *) &stack[1] - opStack)); } if ( programStack != stackOnEntry - 48 ) { Com_Error( ERR_DROP, "programStack corrupted in compiled code\n" ); diff --git a/src/qcommon/vm_x86_64_assembler.c b/src/qcommon/vm_x86_64_assembler.c index 46227e6d..99d2898e 100644 --- a/src/qcommon/vm_x86_64_assembler.c +++ b/src/qcommon/vm_x86_64_assembler.c @@ -27,10 +27,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include <string.h> #include <stdarg.h> -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long u64; +#include <inttypes.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; static char* out; static unsigned compiledOfs; @@ -79,7 +81,7 @@ static void emit1(unsigned char v) if(fout) writecnt = fwrite(&v, 1, 1, fout); - debug("%02hhx ", v); + debug("%02hx ", v); } else { @@ -284,7 +286,7 @@ static void labelhash_free(void) min = MIN(min, n); max = MAX(max, n); } - printf("total %u, hsize %lu, zero %u, min %u, max %u\n", t, sizeof(labelhash)/sizeof(labelhash[0]), z, min, max); + printf("total %u, hsize %"PRIu64", zero %u, min %u, max %u\n", t, sizeof(labelhash)/sizeof(labelhash[0]), z, min, max); memset(labelhash, 0, sizeof(labelhash)); } @@ -310,7 +312,7 @@ static const char* argtype2str(argtype_t t) static inline int iss8(u64 v) { - return (labs(v) <= 0x80); + return (llabs(v) <= 0x80); //llabs instead of labs required for __WIN64 } static inline int isu8(u64 v) @@ -320,7 +322,7 @@ static inline int isu8(u64 v) static inline int iss16(u64 v) { - return (labs(v) <= 0x8000); + return (llabs(v) <= 0x8000); } static inline int isu16(u64 v) @@ -330,7 +332,7 @@ static inline int isu16(u64 v) static inline int iss32(u64 v) { - return (labs(v) <= 0x80000000); + return (llabs(v) <= 0x80000000); } static inline int isu32(u64 v) @@ -340,7 +342,7 @@ static inline int isu32(u64 v) static void emit_opsingle(const char* mnemonic, arg_t arg1, arg_t arg2, void* data) { - u8 op = (u8)((unsigned long) data); + u8 op = (u8)((uint64_t) data); if(arg1.type != T_NONE || arg2.type != T_NONE) CRAP_INVALID_ARGS; @@ -503,7 +505,7 @@ static void maybe_emit_displacement(arg_t* arg) /* one byte operator with register added to operator */ static void emit_opreg(const char* mnemonic, arg_t arg1, arg_t arg2, void* data) { - u8 op = (u8)((unsigned long) data); + u8 op = (u8)((uint64_t) data); if(arg1.type != T_REGISTER || arg2.type != T_NONE) CRAP_INVALID_ARGS; @@ -756,7 +758,7 @@ static void emit_condjump(const char* mnemonic, arg_t arg1, arg_t arg2, void* da { unsigned off; int disp; - unsigned char opcode = (unsigned char)(((unsigned long)data)&0xFF); + unsigned char opcode = (unsigned char)(((uint64_t)data)&0xFF); if(arg1.type != T_LABEL || arg2.type != T_NONE) crap("%s: argument must be label", mnemonic); @@ -1153,7 +1155,7 @@ static unsigned char nexttok(const char** str, char* label, u64* val) else if(*s >= '0' && *s <= '9') { char* endptr = NULL; - u64 v = strtol(s, &endptr, 0); + u64 v = strtoull(s, &endptr, 0); if(endptr && (endptr-s == 0)) crap("invalid integer %s", s); if(val) *val = v; @@ -1274,7 +1276,7 @@ tok_memory: } break; default: - crap("invalid token %hhu in %s", *(unsigned char*)s, *str); + crap("invalid token %hu in %s", *(unsigned char*)s, *str); break; } |