Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* Bra86.c -- Converter for x86 code (BCJ)
  2. 2013-11-12 : Igor Pavlov : Public domain */
  3.  
  4. #include "Precomp.h"
  5.  
  6. #include "Bra.h"
  7.  
  8. #define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
  9.  
  10. SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
  11. {
  12.   SizeT pos = 0;
  13.   UInt32 mask = *state & 7;
  14.   if (size < 5)
  15.     return 0;
  16.   size -= 4;
  17.   ip += 5;
  18.  
  19.   for (;;)
  20.   {
  21.     Byte *p = data + pos;
  22.     const Byte *limit = data + size;
  23.     for (; p < limit; p++)
  24.       if ((*p & 0xFE) == 0xE8)
  25.         break;
  26.  
  27.     {
  28.       SizeT d = (SizeT)(p - data - pos);
  29.       pos = (SizeT)(p - data);
  30.       if (p >= limit)
  31.       {
  32.         *state = (d > 2 ? 0 : mask >> (unsigned)d);
  33.         return pos;
  34.       }
  35.       if (d > 2)
  36.         mask = 0;
  37.       else
  38.       {
  39.         mask >>= (unsigned)d;
  40.         if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
  41.         {
  42.           mask = (mask >> 1) | 4;
  43.           pos++;
  44.           continue;
  45.         }
  46.       }
  47.     }
  48.  
  49.     if (Test86MSByte(p[4]))
  50.     {
  51.       UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
  52.       UInt32 cur = ip + (UInt32)pos;
  53.       pos += 5;
  54.       if (encoding)
  55.         v += cur;
  56.       else
  57.         v -= cur;
  58.       if (mask != 0)
  59.       {
  60.         unsigned sh = (mask & 6) << 2;
  61.         if (Test86MSByte((Byte)(v >> sh)))
  62.         {
  63.           v ^= (((UInt32)0x100 << sh) - 1);
  64.           if (encoding)
  65.             v += cur;
  66.           else
  67.             v -= cur;
  68.         }
  69.         mask = 0;
  70.       }
  71.       p[1] = (Byte)v;
  72.       p[2] = (Byte)(v >> 8);
  73.       p[3] = (Byte)(v >> 16);
  74.       p[4] = (Byte)(0 - ((v >> 24) & 1));
  75.     }
  76.     else
  77.     {
  78.       mask = (mask >> 1) | 4;
  79.       pos++;
  80.     }
  81.   }
  82. }
  83.