Bra.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /* Bra.c -- Converters for RISC code
  2. 2017-04-04 : Igor Pavlov : Public domain */
  3. #include "Precomp.h"
  4. #include "CpuArch.h"
  5. #include "Bra.h"
  6. SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
  7. {
  8. Byte *p;
  9. const Byte *lim;
  10. size &= ~(size_t)3;
  11. ip += 4;
  12. p = data;
  13. lim = data + size;
  14. if (encoding)
  15. for (;;)
  16. {
  17. for (;;)
  18. {
  19. if (p >= lim)
  20. return p - data;
  21. p += 4;
  22. if (p[-1] == 0xEB)
  23. break;
  24. }
  25. {
  26. UInt32 v = GetUi32(p - 4);
  27. v <<= 2;
  28. v += ip + (UInt32)(p - data);
  29. v >>= 2;
  30. v &= 0x00FFFFFF;
  31. v |= 0xEB000000;
  32. SetUi32(p - 4, v);
  33. }
  34. }
  35. for (;;)
  36. {
  37. for (;;)
  38. {
  39. if (p >= lim)
  40. return p - data;
  41. p += 4;
  42. if (p[-1] == 0xEB)
  43. break;
  44. }
  45. {
  46. UInt32 v = GetUi32(p - 4);
  47. v <<= 2;
  48. v -= ip + (UInt32)(p - data);
  49. v >>= 2;
  50. v &= 0x00FFFFFF;
  51. v |= 0xEB000000;
  52. SetUi32(p - 4, v);
  53. }
  54. }
  55. }
  56. SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
  57. {
  58. Byte *p;
  59. const Byte *lim;
  60. size &= ~(size_t)1;
  61. p = data;
  62. lim = data + size - 4;
  63. if (encoding)
  64. for (;;)
  65. {
  66. UInt32 b1;
  67. for (;;)
  68. {
  69. UInt32 b3;
  70. if (p > lim)
  71. return p - data;
  72. b1 = p[1];
  73. b3 = p[3];
  74. p += 2;
  75. b1 ^= 8;
  76. if ((b3 & b1) >= 0xF8)
  77. break;
  78. }
  79. {
  80. UInt32 v =
  81. ((UInt32)b1 << 19)
  82. + (((UInt32)p[1] & 0x7) << 8)
  83. + (((UInt32)p[-2] << 11))
  84. + (p[0]);
  85. p += 2;
  86. {
  87. UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
  88. v += cur;
  89. }
  90. p[-4] = (Byte)(v >> 11);
  91. p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
  92. p[-2] = (Byte)v;
  93. p[-1] = (Byte)(0xF8 | (v >> 8));
  94. }
  95. }
  96. for (;;)
  97. {
  98. UInt32 b1;
  99. for (;;)
  100. {
  101. UInt32 b3;
  102. if (p > lim)
  103. return p - data;
  104. b1 = p[1];
  105. b3 = p[3];
  106. p += 2;
  107. b1 ^= 8;
  108. if ((b3 & b1) >= 0xF8)
  109. break;
  110. }
  111. {
  112. UInt32 v =
  113. ((UInt32)b1 << 19)
  114. + (((UInt32)p[1] & 0x7) << 8)
  115. + (((UInt32)p[-2] << 11))
  116. + (p[0]);
  117. p += 2;
  118. {
  119. UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
  120. v -= cur;
  121. }
  122. /*
  123. SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
  124. SetUi16(p - 2, (UInt16)(v | 0xF800));
  125. */
  126. p[-4] = (Byte)(v >> 11);
  127. p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
  128. p[-2] = (Byte)v;
  129. p[-1] = (Byte)(0xF8 | (v >> 8));
  130. }
  131. }
  132. }
  133. SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
  134. {
  135. Byte *p;
  136. const Byte *lim;
  137. size &= ~(size_t)3;
  138. ip -= 4;
  139. p = data;
  140. lim = data + size;
  141. for (;;)
  142. {
  143. for (;;)
  144. {
  145. if (p >= lim)
  146. return p - data;
  147. p += 4;
  148. /* if ((v & 0xFC000003) == 0x48000001) */
  149. if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
  150. break;
  151. }
  152. {
  153. UInt32 v = GetBe32(p - 4);
  154. if (encoding)
  155. v += ip + (UInt32)(p - data);
  156. else
  157. v -= ip + (UInt32)(p - data);
  158. v &= 0x03FFFFFF;
  159. v |= 0x48000000;
  160. SetBe32(p - 4, v);
  161. }
  162. }
  163. }
  164. SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
  165. {
  166. Byte *p;
  167. const Byte *lim;
  168. size &= ~(size_t)3;
  169. ip -= 4;
  170. p = data;
  171. lim = data + size;
  172. for (;;)
  173. {
  174. for (;;)
  175. {
  176. if (p >= lim)
  177. return p - data;
  178. /*
  179. v = GetBe32(p);
  180. p += 4;
  181. m = v + ((UInt32)5 << 29);
  182. m ^= (UInt32)7 << 29;
  183. m += (UInt32)1 << 22;
  184. if ((m & ((UInt32)0x1FF << 23)) == 0)
  185. break;
  186. */
  187. p += 4;
  188. if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
  189. (p[-4] == 0x7F && (p[-3] >= 0xC0)))
  190. break;
  191. }
  192. {
  193. UInt32 v = GetBe32(p - 4);
  194. v <<= 2;
  195. if (encoding)
  196. v += ip + (UInt32)(p - data);
  197. else
  198. v -= ip + (UInt32)(p - data);
  199. v &= 0x01FFFFFF;
  200. v -= (UInt32)1 << 24;
  201. v ^= 0xFF000000;
  202. v >>= 2;
  203. v |= 0x40000000;
  204. SetBe32(p - 4, v);
  205. }
  206. }
  207. }