From 25eabe56e7f567565e6738273fecee4b87204a32 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 12 Apr 2026 01:00:46 +0000 Subject: test table management instructions ({l,s}{g,i,l}dt) these instructions, it turns out, have fixed operand size based on CPU execution mode and regardless of prefixes. good to know! --- src/long_mode/behavior.rs | 24 ++++++++++++++++++------ src/long_mode/mod.rs | 11 +++++++---- 2 files changed, 25 insertions(+), 10 deletions(-) (limited to 'src/long_mode') diff --git a/src/long_mode/behavior.rs b/src/long_mode/behavior.rs index a8d639d..051129d 100644 --- a/src/long_mode/behavior.rs +++ b/src/long_mode/behavior.rs @@ -2209,10 +2209,18 @@ fn opcode2behavior(opc: &Opcode) -> Option { SYSCALL => { panic!("todo: syscall"); }, LSL => { panic!("todo: lsl"); }, LAR => { panic!("todo: lar"); }, - SGDT => { panic!("todo: sgdt"); }, - SIDT => { panic!("todo: sidt"); }, - LGDT => { panic!("todo: lgdt"); }, - LIDT => { panic!("todo: lidt"); }, + SGDT => BehaviorDigest::empty() + .set_pl_special() + .set_operand(0, Access::Write), + SIDT => BehaviorDigest::empty() + .set_pl_special() + .set_operand(0, Access::Write), + LGDT => BehaviorDigest::empty() + .set_pl0() + .set_operand(0, Access::Read), + LIDT => BehaviorDigest::empty() + .set_pl0() + .set_operand(0, Access::Read), SMSW => { panic!("todo: smsw"); }, LMSW => { panic!("todo: lmsw"); }, SWAPGS => { panic!("todo: swapgs"); }, @@ -2247,9 +2255,13 @@ fn opcode2behavior(opc: &Opcode) -> Option { RDPMC => BehaviorDigest::empty() .set_implicit_ops(RDPMC_IDX) .set_pl_special(), - SLDT => { panic!("todo: sldt"); }, + SLDT => BehaviorDigest::empty() + .set_pl_special() + .set_operand(0, Access::Write), STR => { panic!("todo: str"); }, - LLDT => { panic!("todo: lldt"); }, + LLDT => BehaviorDigest::empty() + .set_pl0() + .set_operand(0, Access::Read), LTR => { panic!("todo: ltr"); }, VERR => { panic!("todo: verr"); }, VERW => { panic!("todo: verw"); }, diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 117643a..7915dc0 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -8246,7 +8246,7 @@ fn read_operands< } else { instruction.opcode = Opcode::SGDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 10; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 1 { @@ -8301,7 +8301,7 @@ fn read_operands< } else { instruction.opcode = Opcode::SIDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 10; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 2 { @@ -8340,7 +8340,10 @@ fn read_operands< } else { instruction.opcode = Opcode::LGDT; instruction.operand_count = 1; - instruction.mem_size = 63; + // quoth SDM: + // > In 64-bit mode, the operand size is fixed at 8+2 bytes. The instruction + // > stores an 8-byte base and a 2-byte limit. + instruction.mem_size = 10; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 3 { @@ -8404,7 +8407,7 @@ fn read_operands< } else { instruction.opcode = Opcode::LIDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 10; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 4 { -- cgit v1.1