Bra86.c 1.8 KB

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