83 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			83 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /* Bra86.c -- Converter for x86 code (BCJ)
 | ||
|  | 2017-04-03 : Igor Pavlov : Public domain */ | ||
|  | 
 | ||
|  | #include "Precomp.h"
 | ||
|  | 
 | ||
|  | #include "Bra.h"
 | ||
|  | 
 | ||
|  | #define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
 | ||
|  | 
 | ||
|  | SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) | ||
|  | { | ||
|  |   SizeT pos = 0; | ||
|  |   UInt32 mask = *state & 7; | ||
|  |   if (size < 5) | ||
|  |     return 0; | ||
|  |   size -= 4; | ||
|  |   ip += 5; | ||
|  | 
 | ||
|  |   for (;;) | ||
|  |   { | ||
|  |     Byte *p = data + pos; | ||
|  |     const Byte *limit = data + size; | ||
|  |     for (; p < limit; p++) | ||
|  |       if ((*p & 0xFE) == 0xE8) | ||
|  |         break; | ||
|  | 
 | ||
|  |     { | ||
|  |       SizeT d = (SizeT)(p - data - pos); | ||
|  |       pos = (SizeT)(p - data); | ||
|  |       if (p >= limit) | ||
|  |       { | ||
|  |         *state = (d > 2 ? 0 : mask >> (unsigned)d); | ||
|  |         return pos; | ||
|  |       } | ||
|  |       if (d > 2) | ||
|  |         mask = 0; | ||
|  |       else | ||
|  |       { | ||
|  |         mask >>= (unsigned)d; | ||
|  |         if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1]))) | ||
|  |         { | ||
|  |           mask = (mask >> 1) | 4; | ||
|  |           pos++; | ||
|  |           continue; | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (Test86MSByte(p[4])) | ||
|  |     { | ||
|  |       UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); | ||
|  |       UInt32 cur = ip + (UInt32)pos; | ||
|  |       pos += 5; | ||
|  |       if (encoding) | ||
|  |         v += cur; | ||
|  |       else | ||
|  |         v -= cur; | ||
|  |       if (mask != 0) | ||
|  |       { | ||
|  |         unsigned sh = (mask & 6) << 2; | ||
|  |         if (Test86MSByte((Byte)(v >> sh))) | ||
|  |         { | ||
|  |           v ^= (((UInt32)0x100 << sh) - 1); | ||
|  |           if (encoding) | ||
|  |             v += cur; | ||
|  |           else | ||
|  |             v -= cur; | ||
|  |         } | ||
|  |         mask = 0; | ||
|  |       } | ||
|  |       p[1] = (Byte)v; | ||
|  |       p[2] = (Byte)(v >> 8); | ||
|  |       p[3] = (Byte)(v >> 16); | ||
|  |       p[4] = (Byte)(0 - ((v >> 24) & 1)); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |       mask = (mask >> 1) | 4; | ||
|  |       pos++; | ||
|  |     } | ||
|  |   } | ||
|  | } |