aboutsummaryrefslogtreecommitdiff
path: root/src/long_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/long_mode')
-rw-r--r--src/long_mode/mod.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 4d663d3..3d6dc2b 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -3828,6 +3828,28 @@ pub enum OperandCode {
Yv_AX = OperandCodeBuilder::new().special_case(101).bits(),
}
+const LOCKABLE_INSTRUCTIONS: &[Opcode] = &[
+ Opcode::ADD,
+ Opcode::ADC,
+ Opcode::AND,
+ Opcode::BTC,
+ Opcode::BTR,
+ Opcode::BTS,
+ Opcode::CMPXCHG,
+ Opcode::CMPXCHG8B,
+ Opcode::CMPXCHG16B,
+ Opcode::DEC,
+ Opcode::INC,
+ Opcode::NEG,
+ Opcode::NOT,
+ Opcode::OR,
+ Opcode::SBB,
+ Opcode::SUB,
+ Opcode::XOR,
+ Opcode::XADD,
+ Opcode::XCHG,
+];
+
fn base_opcode_map(v: u8) -> Opcode {
match v {
0 => Opcode::ADD,
@@ -5650,6 +5672,12 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
}
instruction.length = length;
+ if instruction.prefixes.lock() {
+ if !LOCKABLE_INSTRUCTIONS.contains(&instruction.opcode) || !instruction.operands[0].is_memory() {
+ return Err(DecodeError::InvalidPrefixes);
+ }
+ }
+
if decoder != &InstDecoder::default() {
// we might have to fix up or reject this instruction under whatever cpu features we need to
// pretend to have.