1use super::types::ClrTypeReference;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum ClrOpcode {
6 Nop,
7 LdcI4M1,
8 LdcI40,
9 LdcI41,
10 LdcI42,
11 LdcI43,
12 LdcI44,
13 LdcI45,
14 LdcI46,
15 LdcI47,
16 LdcI48,
17 LdcI4S,
18 LdcI4,
19 LdcI8,
20 LdcR4,
21 LdcR8,
22 Ldnull,
23 Ldstr,
24 Ldarg0,
25 Ldarg1,
26 Ldarg2,
27 Ldarg3,
28 Ldloc0,
29 Ldloc1,
30 Ldloc2,
31 Ldloc3,
32 Stloc0,
33 Stloc1,
34 Stloc2,
35 Stloc3,
36 Call,
37 Callvirt,
38 Ret,
39 Newobj,
40 Pop,
41 Dup,
42 Add,
43 Sub,
44 Mul,
45 Div,
46 Ceq,
47 Cgt,
48 Clt,
49 And,
50 Or,
51 Br,
52 Brtrue,
53 Brfalse,
54 Ldloc,
55 Stloc,
56 Ldarg,
57 Starg,
58 Ldloca,
59 Ldfld,
60 Stfld,
61 Ldelem,
62 Stelem,
63 Ldlen,
64 Newarr,
65 Box,
66 Unbox,
67 ConvI4,
68 ConvI8,
69 ConvR4,
70 ConvR8,
71 LdindI4,
72 LdindI8,
73 LdindR4,
74 LdindR8,
75 LdindRef,
76 StindI4,
77 StindI8,
78 StindR4,
79 StindR8,
80 StindRef,
81}
82
83impl ClrOpcode {
84 pub fn to_byte(&self) -> u8 {
86 match self {
87 ClrOpcode::Nop => 0x00,
88 ClrOpcode::LdcI4M1 => 0x15,
89 ClrOpcode::LdcI40 => 0x16,
90 ClrOpcode::LdcI41 => 0x17,
91 ClrOpcode::LdcI42 => 0x18,
92 ClrOpcode::LdcI43 => 0x19,
93 ClrOpcode::LdcI44 => 0x1A,
94 ClrOpcode::LdcI45 => 0x1B,
95 ClrOpcode::LdcI46 => 0x1C,
96 ClrOpcode::LdcI47 => 0x1D,
97 ClrOpcode::LdcI48 => 0x1E,
98 ClrOpcode::LdcI4S => 0x1F,
99 ClrOpcode::LdcI4 => 0x20,
100 ClrOpcode::LdcI8 => 0x21,
101 ClrOpcode::LdcR4 => 0x22,
102 ClrOpcode::LdcR8 => 0x23,
103 ClrOpcode::Ldnull => 0x14,
104 ClrOpcode::Ldstr => 0x72,
105 ClrOpcode::Ldarg0 => 0x02,
106 ClrOpcode::Ldarg1 => 0x03,
107 ClrOpcode::Ldarg2 => 0x04,
108 ClrOpcode::Ldarg3 => 0x05,
109 ClrOpcode::Ldloc0 => 0x06,
110 ClrOpcode::Ldloc1 => 0x07,
111 ClrOpcode::Ldloc2 => 0x08,
112 ClrOpcode::Ldloc3 => 0x09,
113 ClrOpcode::Stloc0 => 0x0A,
114 ClrOpcode::Stloc1 => 0x0B,
115 ClrOpcode::Stloc2 => 0x0C,
116 ClrOpcode::Stloc3 => 0x0D,
117 ClrOpcode::Call => 0x28,
118 ClrOpcode::Callvirt => 0x6F,
119 ClrOpcode::Ret => 0x2A,
120 ClrOpcode::Newobj => 0x73,
121 ClrOpcode::Pop => 0x25,
122 ClrOpcode::Dup => 0x25,
123 ClrOpcode::Add => 0x58,
124 ClrOpcode::Sub => 0x59,
125 ClrOpcode::Mul => 0x5A,
126 ClrOpcode::Div => 0x5B,
127 ClrOpcode::Ceq => 0xFE, ClrOpcode::Cgt => 0xFE, ClrOpcode::Clt => 0xFE, ClrOpcode::And => 0x5F,
131 ClrOpcode::Or => 0x60,
132 ClrOpcode::Br => 0x38,
133 ClrOpcode::Brtrue => 0x3A,
134 ClrOpcode::Brfalse => 0x3B,
135 ClrOpcode::Ldloc => 0xFE, ClrOpcode::Stloc => 0xFE, ClrOpcode::Ldarg => 0xFE, ClrOpcode::Starg => 0xFE, ClrOpcode::Ldloca => 0xFE, ClrOpcode::Ldfld => 0x7B,
141 ClrOpcode::Stfld => 0x7C,
142 ClrOpcode::Ldelem => 0xA3,
143 ClrOpcode::Stelem => 0xA4,
144 ClrOpcode::Ldlen => 0x8E,
145 ClrOpcode::Newarr => 0x8D,
146 ClrOpcode::Box => 0x8C,
147 ClrOpcode::Unbox => 0x79,
148 ClrOpcode::ConvI4 => 0x67,
149 ClrOpcode::ConvI8 => 0x68,
150 ClrOpcode::ConvR4 => 0x69,
151 ClrOpcode::ConvR8 => 0x6A,
152 ClrOpcode::LdindI4 => 0x4A,
153 ClrOpcode::LdindI8 => 0x4B,
154 ClrOpcode::LdindR4 => 0x4C,
155 ClrOpcode::LdindR8 => 0x4D,
156 ClrOpcode::LdindRef => 0x50,
157 ClrOpcode::StindI4 => 0x54,
158 ClrOpcode::StindI8 => 0x55,
159 ClrOpcode::StindR4 => 0x56,
160 ClrOpcode::StindR8 => 0x57,
161 ClrOpcode::StindRef => 0x51,
162 }
163 }
164
165 pub fn from_str(s: &str) -> Option<Self> {
167 match s.to_lowercase().as_str() {
168 "nop" => Some(ClrOpcode::Nop),
169 "ldc.i4.m1" => Some(ClrOpcode::LdcI4M1),
170 "ldc.i4.0" => Some(ClrOpcode::LdcI40),
171 "ldc.i4.1" => Some(ClrOpcode::LdcI41),
172 "ldc.i4.2" => Some(ClrOpcode::LdcI42),
173 "ldc.i4.3" => Some(ClrOpcode::LdcI43),
174 "ldc.i4.4" => Some(ClrOpcode::LdcI44),
175 "ldc.i4.5" => Some(ClrOpcode::LdcI45),
176 "ldc.i4.6" => Some(ClrOpcode::LdcI46),
177 "ldc.i4.7" => Some(ClrOpcode::LdcI47),
178 "ldc.i4.8" => Some(ClrOpcode::LdcI48),
179 "ldc.i4.s" => Some(ClrOpcode::LdcI4S),
180 "ldc.i4" => Some(ClrOpcode::LdcI4),
181 "ldc.i8" => Some(ClrOpcode::LdcI8),
182 "ldc.r4" => Some(ClrOpcode::LdcR4),
183 "ldc.r8" => Some(ClrOpcode::LdcR8),
184 "ldnull" => Some(ClrOpcode::Ldnull),
185 "ldstr" => Some(ClrOpcode::Ldstr),
186 "ldarg.0" => Some(ClrOpcode::Ldarg0),
187 "ldarg.1" => Some(ClrOpcode::Ldarg1),
188 "ldarg.2" => Some(ClrOpcode::Ldarg2),
189 "ldarg.3" => Some(ClrOpcode::Ldarg3),
190 "ldloc.0" => Some(ClrOpcode::Ldloc0),
191 "ldloc.1" => Some(ClrOpcode::Ldloc1),
192 "ldloc.2" => Some(ClrOpcode::Ldloc2),
193 "ldloc.3" => Some(ClrOpcode::Ldloc3),
194 "stloc.0" => Some(ClrOpcode::Stloc0),
195 "stloc.1" => Some(ClrOpcode::Stloc1),
196 "stloc.2" => Some(ClrOpcode::Stloc2),
197 "stloc.3" => Some(ClrOpcode::Stloc3),
198 "call" => Some(ClrOpcode::Call),
199 "callvirt" => Some(ClrOpcode::Callvirt),
200 "ret" => Some(ClrOpcode::Ret),
201 "newobj" => Some(ClrOpcode::Newobj),
202 "pop" => Some(ClrOpcode::Pop),
203 "dup" => Some(ClrOpcode::Dup),
204 "add" => Some(ClrOpcode::Add),
205 "sub" => Some(ClrOpcode::Sub),
206 "mul" => Some(ClrOpcode::Mul),
207 "div" => Some(ClrOpcode::Div),
208 "ceq" => Some(ClrOpcode::Ceq),
209 "cgt" => Some(ClrOpcode::Cgt),
210 "clt" => Some(ClrOpcode::Clt),
211 "and" => Some(ClrOpcode::And),
212 "or" => Some(ClrOpcode::Or),
213 "br" => Some(ClrOpcode::Br),
214 "brtrue" => Some(ClrOpcode::Brtrue),
215 "brfalse" => Some(ClrOpcode::Brfalse),
216 "ldloc" => Some(ClrOpcode::Ldloc),
217 "stloc" => Some(ClrOpcode::Stloc),
218 "ldarg" => Some(ClrOpcode::Ldarg),
219 "starg" => Some(ClrOpcode::Starg),
220 "ldloca" => Some(ClrOpcode::Ldloca),
221 "ldfld" => Some(ClrOpcode::Ldfld),
222 "stfld" => Some(ClrOpcode::Stfld),
223 "ldelem" => Some(ClrOpcode::Ldelem),
224 "stelem" => Some(ClrOpcode::Stelem),
225 "ldlen" => Some(ClrOpcode::Ldlen),
226 "newarr" => Some(ClrOpcode::Newarr),
227 "box" => Some(ClrOpcode::Box),
228 "unbox" => Some(ClrOpcode::Unbox),
229 "conv.i4" => Some(ClrOpcode::ConvI4),
230 "conv.i8" => Some(ClrOpcode::ConvI8),
231 "conv.r4" => Some(ClrOpcode::ConvR4),
232 "conv.r8" => Some(ClrOpcode::ConvR8),
233 "ldind.i4" => Some(ClrOpcode::LdindI4),
234 "ldind.i8" => Some(ClrOpcode::LdindI8),
235 "ldind.r4" => Some(ClrOpcode::LdindR4),
236 "ldind.r8" => Some(ClrOpcode::LdindR8),
237 "ldind.ref" => Some(ClrOpcode::LdindRef),
238 "stind.i4" => Some(ClrOpcode::StindI4),
239 "stind.i8" => Some(ClrOpcode::StindI8),
240 "stind.r4" => Some(ClrOpcode::StindR4),
241 "stind.r8" => Some(ClrOpcode::StindR8),
242 "stind.ref" => Some(ClrOpcode::StindRef),
243 _ => None,
244 }
245 }
246
247 pub fn as_str(&self) -> &'static str {
249 match self {
250 ClrOpcode::Nop => "nop",
251 ClrOpcode::LdcI4M1 => "ldc.i4.m1",
252 ClrOpcode::LdcI40 => "ldc.i4.0",
253 ClrOpcode::LdcI41 => "ldc.i4.1",
254 ClrOpcode::LdcI42 => "ldc.i4.2",
255 ClrOpcode::LdcI43 => "ldc.i4.3",
256 ClrOpcode::LdcI44 => "ldc.i4.4",
257 ClrOpcode::LdcI45 => "ldc.i4.5",
258 ClrOpcode::LdcI46 => "ldc.i4.6",
259 ClrOpcode::LdcI47 => "ldc.i4.7",
260 ClrOpcode::LdcI48 => "ldc.i4.8",
261 ClrOpcode::LdcI4S => "ldc.i4.s",
262 ClrOpcode::LdcI4 => "ldc.i4",
263 ClrOpcode::LdcI8 => "ldc.i8",
264 ClrOpcode::LdcR4 => "ldc.r4",
265 ClrOpcode::LdcR8 => "ldc.r8",
266 ClrOpcode::Ldnull => "ldnull",
267 ClrOpcode::Ldstr => "ldstr",
268 ClrOpcode::Ldarg0 => "ldarg.0",
269 ClrOpcode::Ldarg1 => "ldarg.1",
270 ClrOpcode::Ldarg2 => "ldarg.2",
271 ClrOpcode::Ldarg3 => "ldarg.3",
272 ClrOpcode::Ldloc0 => "ldloc.0",
273 ClrOpcode::Ldloc1 => "ldloc.1",
274 ClrOpcode::Ldloc2 => "ldloc.2",
275 ClrOpcode::Ldloc3 => "ldloc.3",
276 ClrOpcode::Stloc0 => "stloc.0",
277 ClrOpcode::Stloc1 => "stloc.1",
278 ClrOpcode::Stloc2 => "stloc.2",
279 ClrOpcode::Stloc3 => "stloc.3",
280 ClrOpcode::Call => "call",
281 ClrOpcode::Callvirt => "callvirt",
282 ClrOpcode::Ret => "ret",
283 ClrOpcode::Newobj => "newobj",
284 ClrOpcode::Pop => "pop",
285 ClrOpcode::Dup => "dup",
286 ClrOpcode::Add => "add",
287 ClrOpcode::Sub => "sub",
288 ClrOpcode::Mul => "mul",
289 ClrOpcode::Div => "div",
290 ClrOpcode::Ceq => "ceq",
291 ClrOpcode::Cgt => "cgt",
292 ClrOpcode::Clt => "clt",
293 ClrOpcode::And => "and",
294 ClrOpcode::Or => "or",
295 ClrOpcode::Br => "br",
296 ClrOpcode::Brtrue => "brtrue",
297 ClrOpcode::Brfalse => "brfalse",
298 ClrOpcode::Ldloc => "ldloc",
299 ClrOpcode::Stloc => "stloc",
300 ClrOpcode::Ldarg => "ldarg",
301 ClrOpcode::Starg => "starg",
302 ClrOpcode::Ldloca => "ldloca",
303 ClrOpcode::Ldfld => "ldfld",
304 ClrOpcode::Stfld => "stfld",
305 ClrOpcode::Ldelem => "ldelem",
306 ClrOpcode::Stelem => "stelem",
307 ClrOpcode::Ldlen => "ldlen",
308 ClrOpcode::Newarr => "newarr",
309 ClrOpcode::Box => "box",
310 ClrOpcode::Unbox => "unbox",
311 ClrOpcode::ConvI4 => "conv.i4",
312 ClrOpcode::ConvI8 => "conv.i8",
313 ClrOpcode::ConvR4 => "conv.r4",
314 ClrOpcode::ConvR8 => "conv.r8",
315 ClrOpcode::LdindI4 => "ldind.i4",
316 ClrOpcode::LdindI8 => "ldind.i8",
317 ClrOpcode::LdindR4 => "ldind.r4",
318 ClrOpcode::LdindR8 => "ldind.r8",
319 ClrOpcode::LdindRef => "ldind.ref",
320 ClrOpcode::StindI4 => "stind.i4",
321 ClrOpcode::StindI8 => "stind.i8",
322 ClrOpcode::StindR4 => "stind.r4",
323 ClrOpcode::StindR8 => "stind.r8",
324 ClrOpcode::StindRef => "stind.ref",
325 }
326 }
327}
328
329#[derive(Debug, Clone, PartialEq)]
331pub struct ClrInstruction {
332 pub opcode: ClrOpcode,
333 pub operand: Option<ClrInstructionOperand>,
334 pub offset: u32,
335}
336
337#[derive(Debug, Clone, PartialEq)]
339pub enum ClrInstructionOperand {
340 Int32(i32),
341 Int64(i64),
342 Float32(f32),
343 Float64(f64),
344 String(String),
345 Type(ClrTypeReference),
346 Method(String, Option<String>, Vec<ClrTypeReference>, Box<ClrTypeReference>), Field(String, Option<String>, Box<ClrTypeReference>), Branch(i32), Switch(Vec<i32>), }