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
ARM_Convert(Byte * data,SizeT size,UInt32 ip,int encoding)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
ARMT_Convert(Byte * data,SizeT size,UInt32 ip,int encoding)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
PPC_Convert(Byte * data,SizeT size,UInt32 ip,int encoding)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
SPARC_Convert(Byte * data,SizeT size,UInt32 ip,int encoding)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