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