From b067453904acbfd84aa41a94adae65fb27521e5b Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 20 Jul 2019 11:36:31 -0700 Subject: more smallering! --- src/lib.rs | 272 ++++++++++--------------------------------------------------- 1 file changed, 45 insertions(+), 227 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 0264a16..34c4470 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1731,13 +1731,7 @@ fn read_operands>( */ OperandCode::Eb_R0 => { let opwidth = 1; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; if r != 0 { instruction.opcode = Opcode::Invalid; @@ -1812,13 +1806,7 @@ fn read_operands>( } OperandCode::ModRM_0x80_Eb_Ib => { let opwidth = 1; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -1833,13 +1821,7 @@ fn read_operands>( }, OperandCode::ModRM_0x81_Ev_Ivs => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -1862,13 +1844,7 @@ fn read_operands>( }, OperandCode::ModRM_0xc0_Eb_Ib => { let opwidth = 1; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -1883,13 +1859,7 @@ fn read_operands>( }, OperandCode::ModRM_0xc1_Ev_Ib => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -1904,13 +1874,7 @@ fn read_operands>( }, OperandCode::ModRM_0xc6_Eb_Ib => { let opwidth = 1; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -1928,13 +1892,7 @@ fn read_operands>( }, OperandCode::ModRM_0xc7_Ev_Iv => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; if r != 0 { instruction.opcode = Opcode::Invalid; @@ -1957,13 +1915,7 @@ fn read_operands>( }, OperandCode::ModRM_0xd0_Eb_1 => { let opwidth = 1; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -1977,13 +1929,7 @@ fn read_operands>( }, OperandCode::ModRM_0xd1_Ev_1 => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -1997,12 +1943,7 @@ fn read_operands>( }, OperandCode::ModRM_0xf6 => { let opwidth = 1; - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { }, Err(reason) => { return Err(reason); } @@ -2043,12 +1984,7 @@ fn read_operands>( }, OperandCode::ModRM_0xf7 => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { }, Err(reason) => { return Err(reason); } @@ -2090,13 +2026,7 @@ fn read_operands>( }, OperandCode::ModRM_0xfe_Eb => { let opwidth = 1; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -2119,13 +2049,7 @@ fn read_operands>( } OperandCode::ModRM_0xff_Ev => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -2148,13 +2072,7 @@ fn read_operands>( } OperandCode::Ev => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, _, m) = octets_of(modrm); + let (mod_bits, _, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -2166,13 +2084,7 @@ fn read_operands>( }, OperandCode::Eb_Gb => { let opwidth = 1; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -2185,13 +2097,7 @@ fn read_operands>( }, OperandCode::Ev_Gv => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { @@ -2204,13 +2110,7 @@ fn read_operands>( }, OperandCode::Gb_Eb => { let opwidth = 1; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) { Ok(()) => { @@ -2223,13 +2123,7 @@ fn read_operands>( }, OperandCode::Gv_Eb => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) { Ok(()) => { @@ -2242,13 +2136,7 @@ fn read_operands>( }, OperandCode::Gv_Ew => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[1], length) { Ok(()) => { @@ -2261,13 +2149,7 @@ fn read_operands>( }, OperandCode::Ew_Sw => { let opwidth = 2; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; if r > 5 { return Err("Invalid r".to_owned()); @@ -2286,13 +2168,7 @@ fn read_operands>( }, OperandCode::Sw_Ew => { let opwidth = 2; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; if r > 5 { return Err("Invalid r".to_owned()); @@ -2312,13 +2188,7 @@ fn read_operands>( // TODO: verify M OperandCode::Gv_Ed => { let opwidth = 4; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) { @@ -2332,13 +2202,7 @@ fn read_operands>( }, OperandCode::Gv_Ev | OperandCode::Gv_M => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) { @@ -2352,13 +2216,7 @@ fn read_operands>( }, OperandCode::E_G_xmm => { let opwidth = 8; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); match read_E_xmm(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { @@ -2372,13 +2230,7 @@ fn read_operands>( }, OperandCode::G_E_xmm => { let opwidth = 8; - // TODO: ... - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); match read_E_xmm(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) { @@ -2483,15 +2335,9 @@ fn read_operands>( } }, OperandCode::ModRM_0x83_Ev_Ibs => { - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let (mod_bits, r, m) = octets_of(modrm); - match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) { Ok(()) => { let opcode = BASE_OPCODE_MAP[r as usize].clone(); @@ -2523,12 +2369,7 @@ fn read_operands>( Ok(()) } OperandCode::ModRM_0x0f00 => { - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; if r == 0 { instruction.opcode = Opcode::SLDT; instruction.operands[1] = Operand::Nothing; @@ -2565,12 +2406,7 @@ fn read_operands>( } OperandCode::ModRM_0x0f01 => { let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes); - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; if r == 0 { if mod_bits == 0b11 { panic!("Unsupported instruction: 0x0f01 with modrm: 11 000 ___"); @@ -2648,12 +2484,7 @@ fn read_operands>( } } OperandCode::ModRM_0x0fae => { - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match r { 0 => { if mod_bits == 0b11 { @@ -2740,12 +2571,7 @@ fn read_operands>( } OperandCode::ModRM_0x0fba => { let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes); - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (mod_bits, r, m) = octets_of(modrm); + let (mod_bits, r, m) = read_modrm(bytes_iter, length)?; match r { 0 | 1 | 2 | 3 => { instruction.opcode = Opcode::Invalid; @@ -2780,12 +2606,7 @@ fn read_operands>( } OperandCode::Rq_Cq_0 => { - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (_, mut r, mut m) = octets_of(modrm); + let (_, mut r, mut m) = read_modrm(bytes_iter, length)?; if instruction.prefixes.rex().r() { r += 0b1000; } @@ -2799,11 +2620,7 @@ fn read_operands>( Ok(()) } OperandCode::Rq_Dq_0 => { - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - let (_, mut r, mut m) = octets_of(modrm); + let (_, mut r, mut m) = read_modrm(bytes_iter, length)?; if instruction.prefixes.rex().r() { r += 0b1000; } @@ -2817,12 +2634,7 @@ fn read_operands>( Ok(()) } OperandCode::Cq_Rq_0 => { - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (_, mut r, mut m) = octets_of(modrm); + let (_, mut r, mut m) = read_modrm(bytes_iter, length)?; if instruction.prefixes.rex().r() { r += 0b1000; } @@ -2836,12 +2648,7 @@ fn read_operands>( Ok(()) } OperandCode::Dq_Rq_0 => { - let modrm = match bytes_iter.next() { - Some(b) => b, - None => return Err("Out of bytes".to_string()) - }; - *length += 1; - let (_, mut r, mut m) = octets_of(modrm); + let (_, mut r, mut m) = read_modrm(bytes_iter, length)?; if instruction.prefixes.rex().r() { r += 0b1000; } @@ -3024,3 +2831,14 @@ fn imm_width_from_prefixes_64(interpretation: SizeCode, prefixes: &Prefixes) -> }, } } + +#[inline] +fn read_modrm>(bytes_iter: &mut T, length: &mut u8) -> Result<(u8, u8, u8), String> { + let modrm = match bytes_iter.next() { + Some(b) => b, + // TODO: ... + None => return Err("Out of bytes".to_string()), + }; + *length += 1; + Ok(octets_of(modrm)) +} -- cgit v1.1