Source code

Revision control

Copy as Markdown

Other Tools

/* 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++;↩
}↩
}↩
}↩