From 0a39607d690755c5f7f7462677fb75580946be2c Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 21 Aug 2021 17:10:39 -0700 Subject: add description reporting for segment prefixes and opcodes for 32-bit and 16-bit --- src/protected_mode/mod.rs | 78 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) (limited to 'src/protected_mode/mod.rs') diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 572513d..20125ca 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -5802,7 +5802,11 @@ fn read_sib< } #[allow(non_snake_case)] -fn read_M_16bit::Address, ::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result { +fn read_M_16bit< + T: Reader<::Address, ::Word>, + S: DescriptionSink +>(words: &mut T, instr: &mut Instruction, modrm: u8, sink: &mut S) -> Result { + let modrm_start = words.offset() as u32 * 8 - 8; let modbits = modrm >> 6; let mmm = modrm & 7; if modbits == 0b00 && mmm == 0b110 { @@ -5842,6 +5846,12 @@ fn read_M_16bit::Address, { + sink.record( + modrm_start + 6, + modrm_start + 7, + InnerDescription::Misc("mmm selects a dereference with no displacement (mod bits: 00)") + .with_id(modrm_start + 0) + ); if mmm > 3 { Ok(OperandSpec::Deref) } else { @@ -5849,7 +5859,21 @@ fn read_M_16bit::Address, { + let disp_start = words.offset() as u32 * 8; instr.disp = read_num(words, 1)? as i8 as i32 as u32; + let disp_end = words.offset() as u32 * 8; + sink.record( + modrm_start + 6, + modrm_start + 7, + InnerDescription::Misc("mmm selects a dereference with 8-bit displacement (mod bits: 01)") + .with_id(modrm_start + 0) + ); + sink.record( + disp_start, + disp_end - 1, + InnerDescription::Number("displacement", instr.disp as i64) + .with_id(disp_start + 3) + ); if mmm > 3 { if instr.disp != 0 { Ok(OperandSpec::RegDisp) @@ -5865,7 +5889,21 @@ fn read_M_16bit::Address, { + let disp_start = words.offset() as u32 * 8; instr.disp = read_num(words, 2)? as i16 as i32 as u32; + let disp_end = words.offset() as u32 * 8; + sink.record( + modrm_start + 6, + modrm_start + 7, + InnerDescription::Misc("mmm selects a dereference with 16-bit displacement (mod bits: 10)") + .with_id(modrm_start + 0) + ); + sink.record( + disp_start, + disp_end - 1, + InnerDescription::Number("displacement", instr.disp as i64) + .with_id(disp_start + 3) + ); if mmm > 3 { if instr.disp != 0 { Ok(OperandSpec::RegDisp) @@ -5894,7 +5932,7 @@ fn read_M< let modrm_start = words.offset() as u32 * 8 - 8; if instr.prefixes.address_size() { - return read_M_16bit(words, instr, modrm); + return read_M_16bit(words, instr, modrm, sink); } instr.regs[1].bank = RegisterBank::D; let modbits = modrm >> 6; @@ -7396,7 +7434,7 @@ fn read_with_annotations< let record: OpcodeRecord = loop { let record = next_rec; - if let Interpretation::Instruction(_) = record.0 { + if let Interpretation::Instruction(opc) = record.0 { if words.offset() > 1 { sink.record( words.offset() as u32 * 8 - 8 - 1, words.offset() as u32 * 8 - 8 - 1, @@ -7404,6 +7442,16 @@ fn read_with_annotations< .with_id(words.offset() as u32 * 8 - 9) ); } + if opc != Opcode::Invalid { + sink.record((words.offset() - 1) as u32 * 8, (words.offset() - 1) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::Opcode(opc), + id: words.offset() as u32 * 8 - 8, + }); + } + sink.record((words.offset() - 1) as u32 * 8, (words.offset() - 1) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::OperandCode(record.1), + id: words.offset() as u32 * 8 - 8 + 1, + }); break record; } else { let b = nextb; @@ -7436,21 +7484,45 @@ fn read_with_annotations< }; match b { 0x26 => { + sink.record((words.offset() - 2) as u32 * 8, (words.offset() - 2) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::SegmentPrefix(Segment::ES), + id: words.offset() as u32 * 8 - 16, + }); prefixes.set_es(); }, 0x2e => { + sink.record((words.offset() - 2) as u32 * 8, (words.offset() - 2) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::SegmentPrefix(Segment::CS), + id: words.offset() as u32 * 8 - 16, + }); prefixes.set_cs(); }, 0x36 => { + sink.record((words.offset() - 2) as u32 * 8, (words.offset() - 2) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::SegmentPrefix(Segment::SS), + id: words.offset() as u32 * 8 - 16, + }); prefixes.set_ss(); }, 0x3e => { + sink.record((words.offset() - 2) as u32 * 8, (words.offset() - 2) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::SegmentPrefix(Segment::DS), + id: words.offset() as u32 * 8 - 16, + }); prefixes.set_ds(); }, 0x64 => { + sink.record((words.offset() - 2) as u32 * 8, (words.offset() - 2) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::SegmentPrefix(Segment::FS), + id: words.offset() as u32 * 8 - 16, + }); prefixes.set_fs(); }, 0x65 => { + sink.record((words.offset() - 2) as u32 * 8, (words.offset() - 2) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::SegmentPrefix(Segment::GS), + id: words.offset() as u32 * 8 - 16, + }); prefixes.set_gs(); }, 0x66 => { -- cgit v1.1