ShellcodeGenerator/
Mips.rs

1pub mod Linux;
2
3
4use crate::Endian;
5
6
7#[derive (Clone, Copy, Debug, Eq, PartialEq)]
8enum MipsInstructionOpcode
9{
10	REG = 0b000000,
11	ADDI = 0b001000,
12	ADDIU = 0b001001,
13	SLTI = 0b001010,
14	SLTIU = 0b001011,
15	ANDI = 0b001100,
16	ORI = 0b001101,
17	XORI = 0b001110,
18	LUI = 0b001111,
19	LB = 0b100000,
20	LH = 0b100001,
21	LW = 0b100011,
22	LHU = 0b100101,
23	SH = 0b101001,
24	SW = 0b101011,
25	SB = 0b101000,
26	BEQ = 0b000100,
27	BNE = 0b000101,
28}
29
30
31#[derive (Clone, Copy, Debug, Eq, PartialEq)]
32enum MipsInstructionFunctionCode
33{
34	SYSCALL = 0b001100,
35	SYNC = 0x001111,
36	MFHI = 0b010000,
37	MTHI = 0b010001,
38	MFLO = 0b010010,
39	MTLO = 0b010011,
40	MULT = 0b011000,
41	MULTU = 0b011001,
42	DIV = 0b011010,
43	DIVU = 0b011011,
44	ADD = 0b100000,
45	ADDU = 0b100001,
46	SUB = 0b100010,
47	SUBU = 0b100011,
48	AND = 0b100100,
49	OR = 0b100101,
50	XOR = 0b100110,
51	NOR = 0b100111,
52	SLT = 0b101010,
53	SLTU = 0b101011,
54}
55
56
57// $zero: 0
58// $v0-$v1: 2-3
59// $a0-$a3: 4-7
60// $t0-$t7: 8-15
61// $s0-$s7: 16-23
62// $t8-$t9: 24-25
63// $gp: 28
64// $sp: 29
65// $fp: 30
66// $ra: 31
67#[derive (Clone, Copy, Debug, Eq, PartialEq)]
68pub enum MipsRegister
69{
70	ZERO = 0,
71	UNKNOWN1 = 1,
72	V0 = 2,
73	V1 = 3,
74	A0 = 4,
75	A1 = 5,
76	A2 = 6,
77	A3 = 7,
78	T0 = 8,
79	T1 = 9,
80	T2 = 10,
81	T3 = 11,
82	T4 = 12,
83	T5 = 13,
84	T6 = 14,
85	T7 = 15,
86	S0 = 16,
87	S1 = 17,
88	S2 = 18,
89	S3 = 19,
90	S4 = 20,
91	S5 = 21,
92	S6 = 22,
93	S7 = 23,
94	T8 = 24,
95	T9 = 25,
96	UNKNOWN26 = 26,
97	UNKNOWN27 = 27,
98	GP = 28,
99	SP = 29,
100	FP = 30,
101	RA = 31,
102}
103
104impl TryFrom<usize> for MipsRegister
105{
106	type Error = ();
107
108	fn try_from (value: usize) -> Result<Self, Self::Error>
109	{
110		match value
111		{
112			x if x == Self::ZERO as usize => Ok(Self::ZERO),
113			x if x == Self::UNKNOWN1 as usize => Ok(Self::UNKNOWN1),
114			x if x == Self::V0 as usize => Ok(Self::V0),
115			x if x == Self::V1 as usize => Ok(Self::V1),
116			x if x == Self::A0 as usize => Ok(Self::A0),
117			x if x == Self::A1 as usize => Ok(Self::A1),
118			x if x == Self::A2 as usize => Ok(Self::A2),
119			x if x == Self::A3 as usize => Ok(Self::A3),
120			x if x == Self::T0 as usize => Ok(Self::T0),
121			x if x == Self::T1 as usize => Ok(Self::T1),
122			x if x == Self::T2 as usize => Ok(Self::T2),
123			x if x == Self::T3 as usize => Ok(Self::T3),
124			x if x == Self::T4 as usize => Ok(Self::T4),
125			x if x == Self::T5 as usize => Ok(Self::T5),
126			x if x == Self::T6 as usize => Ok(Self::T6),
127			x if x == Self::T7 as usize => Ok(Self::T7),
128			x if x == Self::S0 as usize => Ok(Self::S0),
129			x if x == Self::S1 as usize => Ok(Self::S1),
130			x if x == Self::S2 as usize => Ok(Self::S2),
131			x if x == Self::S3 as usize => Ok(Self::S3),
132			x if x == Self::S4 as usize => Ok(Self::S4),
133			x if x == Self::S5 as usize => Ok(Self::S5),
134			x if x == Self::S6 as usize => Ok(Self::S6),
135			x if x == Self::S7 as usize => Ok(Self::S7),
136			x if x == Self::T8 as usize => Ok(Self::T8),
137			x if x == Self::T9 as usize => Ok(Self::T9),
138			x if x == Self::UNKNOWN26 as usize => Ok(Self::UNKNOWN26),
139			x if x == Self::UNKNOWN27 as usize => Ok(Self::UNKNOWN27),
140			x if x == Self::GP as usize => Ok(Self::GP),
141			x if x == Self::SP as usize => Ok(Self::SP),
142			x if x == Self::FP as usize => Ok(Self::FP),
143			x if x == Self::RA as usize => Ok(Self::RA),
144			_ => Err(()),
145		}
146	}
147}
148
149
150#[derive (Clone, Copy, Debug, Eq, PartialEq)]
151struct RTypeInstruction
152{
153	opcode: MipsInstructionOpcode,
154	rs: MipsRegister,
155	rt: MipsRegister,
156	rd: MipsRegister,
157	shamt: usize,
158	funct: MipsInstructionFunctionCode,
159}
160
161impl RTypeInstruction
162{
163	pub fn New (opcode: MipsInstructionOpcode, rs: MipsRegister, rt: MipsRegister, rd: MipsRegister, shamt: usize, funct: MipsInstructionFunctionCode) -> Self
164	{
165		Self
166		{
167			opcode,
168			rs,
169			rt,
170			rd,
171			shamt,
172			funct,
173		}
174	}
175
176	pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
177	{
178		let op = (self.opcode as usize)&0b111111;
179		let rs = (self.rs as usize)&0b11111;
180		let rt = (self.rt as usize)&0b11111;
181		let rd = (self.rd as usize)&0b11111;
182		let shamt = self.shamt&0b11111;
183		let funct = (self.funct as usize)&0b111111;
184
185		let code: u32 = ((op<<26) | (rs<<21) | (rt<<16) | (rd<<11) | (shamt<<6) | funct) as u32;
186
187		if endian == Endian::BIG
188		{
189			code.to_be_bytes ().to_vec ()
190		}
191		else
192		{
193			code.to_le_bytes ().to_vec ()
194		}
195	}
196
197	pub fn ToAssemblySource (&self) -> String
198	{
199		unimplemented! ();
200	}
201}
202
203
204#[derive (Clone, Copy, Debug, Eq, PartialEq)]
205struct ITypeInstruction
206{
207	opcode: MipsInstructionOpcode,
208	rs: MipsRegister,
209	rt: MipsRegister,
210	addrImm: u16,
211}
212
213impl ITypeInstruction
214{
215	pub fn New (opcode: MipsInstructionOpcode, rs: MipsRegister, rt: MipsRegister, addrImm: u16) -> Self
216	{
217		Self
218		{
219			opcode,
220			rs,
221			rt,
222			addrImm,
223		}
224	}
225
226	pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
227	{
228		let op = (self.opcode as usize)&0b111111;
229		let rs = (self.rs as usize)&0b11111;
230		let rt = (self.rt as usize)&0b11111;
231
232		let code: u32 = ((op<<26) | (rs<<21) | (rt<<16) | self.addrImm as usize) as u32;
233
234		if endian == Endian::BIG
235		{
236			code.to_be_bytes ().to_vec ()
237		}
238		else
239		{
240			code.to_le_bytes ().to_vec ()
241		}
242	}
243
244	pub fn ToAssemblySource (&self) -> String
245	{
246		unimplemented! ();
247	}
248}
249
250
251#[derive (Clone, Copy, Debug, Eq, PartialEq)]
252struct JTypeInstruction
253{
254	opcode: MipsInstructionOpcode,
255	targetAddress: usize,
256}
257
258impl JTypeInstruction
259{
260	pub fn New (opcode: MipsInstructionOpcode, targetAddress: usize) -> Self
261	{
262		Self
263		{
264			opcode,
265			targetAddress,
266		}
267	}
268
269	// always in big endian
270	pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
271	{
272		let op = (self.opcode as usize)&0b111111;
273		let targetAddress = self.targetAddress&0b1111_1111_1111_1111_1111_1111_11;
274
275		let code: u32 = ((op<<26) | targetAddress) as u32;
276
277		if endian == Endian::BIG
278		{
279			code.to_be_bytes ().to_vec ()
280		}
281		else
282		{
283			code.to_le_bytes ().to_vec ()
284		}
285	}
286
287	pub fn ToAssemblySource (&self) -> String
288	{
289		unimplemented! ();
290	}
291}
292
293
294#[derive (Clone, Copy, Debug, Eq, PartialEq)]
295enum MipsInstruction
296{
297	RType(RTypeInstruction),
298	IType(ITypeInstruction),
299	JType(JTypeInstruction),
300}
301
302impl MipsInstruction
303{
304	pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
305	{
306		match self
307		{
308			Self::RType(instruction) => instruction.ToByteArray (endian),
309			Self::IType(instruction) => instruction.ToByteArray (endian),
310			Self::JType(instruction) => instruction.ToByteArray (endian),
311		}
312	}
313
314	pub fn ToAssemblySource (&self) -> String
315	{
316		match self
317		{
318			Self::RType(instruction) => instruction.ToAssemblySource (),
319			Self::IType(instruction) => instruction.ToAssemblySource (),
320			Self::JType(instruction) => instruction.ToAssemblySource (),
321		}
322	}
323}