diff options
| author | tma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-10-13 14:47:00 +0000 | 
|---|---|---|
| committer | tma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-10-13 14:47:00 +0000 | 
| commit | 2409247307a2fdf0266a8bd7cd39526f06bea0d3 (patch) | |
| tree | 3db0f1aeac11c230a2cfeca37c911cb2fec92d04 /code/qcommon | |
| parent | 0ef0850cce08475bd990dd1d3e8865e48995b0ee (diff) | |
| download | ioquake3-aero-2409247307a2fdf0266a8bd7cd39526f06bea0d3.tar.gz ioquake3-aero-2409247307a2fdf0266a8bd7cd39526f06bea0d3.zip  | |
* (Non-trivial) fix to the "opStack corrupted in compiled code" bug
git-svn-id: svn://svn.icculus.org/quake3/trunk@156 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/qcommon')
| -rw-r--r-- | code/qcommon/qfiles.h | 6 | ||||
| -rw-r--r-- | code/qcommon/vm.c | 90 | ||||
| -rw-r--r-- | code/qcommon/vm_local.h | 3 | ||||
| -rw-r--r-- | code/qcommon/vm_x86.c | 6 | 
4 files changed, 86 insertions, 19 deletions
diff --git a/code/qcommon/qfiles.h b/code/qcommon/qfiles.h index 3fd44ed..1aab668 100644 --- a/code/qcommon/qfiles.h +++ b/code/qcommon/qfiles.h @@ -43,7 +43,8 @@ QVM files  ========================================================================  */ -#define	VM_MAGIC	0x12721444 +#define	VM_MAGIC			0x12721444 +#define	VM_MAGIC_VER2	0x12721445  typedef struct {  	int		vmMagic; @@ -56,6 +57,9 @@ typedef struct {  	int		dataLength;  	int		litLength;			// ( dataLength - litLength ) should be byteswapped on load  	int		bssLength;			// zero filled memory appended to datalength + +	//!!! below here is VM_MAGIC_VER2 !!! +	int		jtrgLength;			// number of jump table targets  } vmHeader_t; diff --git a/code/qcommon/vm.c b/code/qcommon/vm.c index 080599d..c5f2c75 100644 --- a/code/qcommon/vm.c +++ b/code/qcommon/vm.c @@ -381,7 +381,7 @@ vm_t *VM_Restart( vm_t *vm ) {  	// load the image  	Com_Printf( "VM_Restart()\n", filename );  	Com_sprintf( filename, sizeof(filename), "vm/%s.qvm", vm->name ); -	Com_Printf( "Loading vm file %s.\n", filename ); +	Com_Printf( "Loading vm file %s...\n", filename );  	length = FS_ReadFile( filename, (void **)&header );  	if ( !header ) {  		Com_Error( ERR_DROP, "VM_Restart failed.\n" ); @@ -392,14 +392,28 @@ vm_t *VM_Restart( vm_t *vm ) {  		((int *)header)[i] = LittleLong( ((int *)header)[i] );  	} -	// validate -	if ( header->vmMagic != VM_MAGIC -		|| header->bssLength < 0  -		|| header->dataLength < 0  -		|| header->litLength < 0  -		|| header->codeLength <= 0 ) { -		VM_Free( vm ); -		Com_Error( ERR_FATAL, "%s has bad header", filename ); +	if( header->vmMagic == VM_MAGIC_VER2 ) { +		Com_Printf( "...which has vmMagic VM_MAGIC_VER2\n" ); +		// validate +		if ( header->vmMagic != VM_MAGIC_VER2 +			|| header->jtrgLength < 0  +			|| header->bssLength < 0  +			|| header->dataLength < 0  +			|| header->litLength < 0  +			|| header->codeLength <= 0 ) { +			VM_Free( vm ); +			Com_Error( ERR_FATAL, "%s has bad header", filename ); +		} +	} else { +		// validate +		if ( header->vmMagic != VM_MAGIC +			|| header->bssLength < 0  +			|| header->dataLength < 0  +			|| header->litLength < 0  +			|| header->codeLength <= 0 ) { +			VM_Free( vm ); +			Com_Error( ERR_FATAL, "%s has bad header", filename ); +		}  	}  	// round up to next power of 2 so all data operations can @@ -420,6 +434,19 @@ vm_t *VM_Restart( vm_t *vm ) {  		*(int *)(vm->dataBase + i) = LittleLong( *(int *)(vm->dataBase + i ) );  	} +	if( header->vmMagic == VM_MAGIC_VER2 ) { +		vm->numJumpTableTargets = header->jtrgLength >> 2; +		Com_Printf( "Loading %d jump table targets\n", vm->numJumpTableTargets ); +		Com_Memset( vm->jumpTableTargets, 0, header->jtrgLength ); +		Com_Memcpy( vm->jumpTableTargets, (byte *)header + header->dataOffset + +				header->dataLength + header->litLength, header->jtrgLength ); + +		// byte swap the longs +		for ( i = 0 ; i < header->jtrgLength ; i += 4 ) { +			*(int *)(vm->jumpTableTargets + i) = LittleLong( *(int *)(vm->jumpTableTargets + i ) ); +		} +	} +  	// free the original file  	FS_FreeFile( header ); @@ -504,7 +531,7 @@ vm_t *VM_Create( const char *module, long (*systemCalls)(long *),  	// load the image  	Com_sprintf( filename, sizeof(filename), "vm/%s.qvm", vm->name ); -	Com_Printf( "Loading vm file %s.\n", filename ); +	Com_Printf( "Loading vm file %s...\n", filename );  	length = FS_ReadFile( filename, (void **)&header );  	if ( !header ) {  		Com_Printf( "Failed.\n" ); @@ -517,14 +544,28 @@ vm_t *VM_Create( const char *module, long (*systemCalls)(long *),  		((int *)header)[i] = LittleLong( ((int *)header)[i] );  	} -	// validate -	if ( header->vmMagic != VM_MAGIC -		|| header->bssLength < 0  -		|| header->dataLength < 0  -		|| header->litLength < 0  -		|| header->codeLength <= 0 ) { -		VM_Free( vm ); -		Com_Error( ERR_FATAL, "%s has bad header", filename ); +	if( header->vmMagic == VM_MAGIC_VER2 ) { +		Com_Printf( "...which has vmMagic VM_MAGIC_VER2\n" ); +		// validate +		if ( header->vmMagic != VM_MAGIC_VER2 +			|| header->jtrgLength < 0  +			|| header->bssLength < 0  +			|| header->dataLength < 0  +			|| header->litLength < 0  +			|| header->codeLength <= 0 ) { +			VM_Free( vm ); +			Com_Error( ERR_FATAL, "%s has bad header", filename ); +		} +	} else { +		// validate +		if ( header->vmMagic != VM_MAGIC +			|| header->bssLength < 0  +			|| header->dataLength < 0  +			|| header->litLength < 0  +			|| header->codeLength <= 0 ) { +			VM_Free( vm ); +			Com_Error( ERR_FATAL, "%s has bad header", filename ); +		}  	}  	// round up to next power of 2 so all data operations can @@ -546,6 +587,19 @@ vm_t *VM_Create( const char *module, long (*systemCalls)(long *),  		*(int *)(vm->dataBase + i) = LittleLong( *(int *)(vm->dataBase + i ) );  	} +	if( header->vmMagic == VM_MAGIC_VER2 ) { +		vm->numJumpTableTargets = header->jtrgLength >> 2; +		Com_Printf( "Loading %d jump table targets\n", vm->numJumpTableTargets ); +		vm->jumpTableTargets = Hunk_Alloc( header->jtrgLength, h_high ); +		Com_Memcpy( vm->jumpTableTargets, (byte *)header + header->dataOffset + +				header->dataLength + header->litLength, header->jtrgLength ); + +		// byte swap the longs +		for ( i = 0 ; i < header->jtrgLength ; i += 4 ) { +			*(int *)(vm->jumpTableTargets + i) = LittleLong( *(int *)(vm->jumpTableTargets + i ) ); +		} +	} +  	// allocate space for the jump targets, which will be filled in by the compile/prep functions  	vm->instructionPointersLength = header->instructionCount * 4;  	vm->instructionPointers = Hunk_Alloc( vm->instructionPointersLength, h_high ); diff --git a/code/qcommon/vm_local.h b/code/qcommon/vm_local.h index f6fc043..eb58fff 100644 --- a/code/qcommon/vm_local.h +++ b/code/qcommon/vm_local.h @@ -161,6 +161,9 @@ struct vm_s {  // fqpath member added 7/20/02 by T.Ray  	char		fqpath[MAX_QPATH+1] ; + +	byte		*jumpTableTargets; +	int			numJumpTableTargets;  }; diff --git a/code/qcommon/vm_x86.c b/code/qcommon/vm_x86.c index a46161a..63b3e1b 100644 --- a/code/qcommon/vm_x86.c +++ b/code/qcommon/vm_x86.c @@ -419,6 +419,12 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {  	Com_Memset(jused, 0, header->instructionCount+2); +	// ensure that the optimisation pass knows about all the jump +	// table targets +	for( i = 0; i < vm->numJumpTableTargets; i++ ) { +		jused[ *(int *)(vm->jumpTableTargets + ( i * sizeof( int ) ) ) ] = 1; +	} +  	for(pass=0;pass<2;pass++) {  	oc0 = -23423;  	oc1 = -234354;  | 
