From 29a776b8ddea4224bab1c90fcb45bc43dc1e9955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 25 Sep 2024 19:25:17 +0200 Subject: [PATCH 1/5] Adds support for RSP in Value::RegisterIndirect arguments. --- src/jit.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jit.rs b/src/jit.rs index d58a5900..5c14f19b 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -974,7 +974,10 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { Value::RegisterIndirect(reg, offset, user_provided) => { debug_assert!(!user_provided); if is_stack_argument { + debug_assert_ne!(reg, RSP); self.emit_ins(X86Instruction::push(reg, Some(X86IndirectAccess::Offset(offset)))); + } else if reg == RSP { + self.emit_ins(X86Instruction::load(OperandSize::S64, RSP, dst, X86IndirectAccess::OffsetIndexShift(offset, RSP, 0))); } else { self.emit_ins(X86Instruction::load(OperandSize::S64, reg, dst, X86IndirectAccess::Offset(offset))); } @@ -984,6 +987,8 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { if is_stack_argument { self.emit_ins(X86Instruction::push(reg, None)); self.emit_ins(X86Instruction::alu(OperandSize::S64, 0x81, 0, RSP, offset as i64, Some(X86IndirectAccess::OffsetIndexShift(0, RSP, 0)))); + } else if reg == RSP { + self.emit_ins(X86Instruction::lea(OperandSize::S64, RSP, dst, Some(X86IndirectAccess::OffsetIndexShift(offset, RSP, 0)))); } else { self.emit_ins(X86Instruction::lea(OperandSize::S64, reg, dst, Some(X86IndirectAccess::Offset(offset)))); } From 495b6fe412d45dadaac98053b894c1586e66ca4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 25 Sep 2024 19:24:00 +0200 Subject: [PATCH 2/5] Pass value to store as RSP based RegisterIndirect argument. --- src/jit.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/jit.rs b/src/jit.rs index 5c14f19b..3495a2a3 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -1105,6 +1105,7 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { }, } + let stack_slot_of_value_to_store = X86IndirectAccess::OffsetIndexShift(-112, RSP, 0); match value { Some(Value::Register(reg)) => { self.emit_ins(X86Instruction::mov(OperandSize::S64, reg, REGISTER_OTHER_SCRATCH)); @@ -1118,6 +1119,7 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { } _ => {} } + self.emit_ins(X86Instruction::store(OperandSize::S64, REGISTER_OTHER_SCRATCH, RSP, stack_slot_of_value_to_store)); if self.config.enable_address_translation { let access_type = if value.is_none() { AccessType::Load } else { AccessType::Store }; @@ -1554,7 +1556,7 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { }; self.emit_rust_call(Value::Constant64(store, false), &[ Argument { index: 3, value: Value::Register(REGISTER_SCRATCH) }, // Specify first as the src register could be overwritten by other arguments - Argument { index: 2, value: Value::Register(REGISTER_OTHER_SCRATCH) }, + Argument { index: 2, value: Value::RegisterIndirect(RSP, -8, false) }, Argument { index: 4, value: Value::Constant64(0, false) }, // self.pc is set later Argument { index: 1, value: Value::RegisterPlusConstant32(REGISTER_PTR_TO_VM, self.slot_in_vm(RuntimeEnvironmentSlot::MemoryMapping), false) }, Argument { index: 0, value: Value::RegisterPlusConstant32(REGISTER_PTR_TO_VM, self.slot_in_vm(RuntimeEnvironmentSlot::ProgramResult), false) }, From 58ea4914ad0ce5cb48041b1740b6ec20a770665c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 25 Sep 2024 19:50:52 +0200 Subject: [PATCH 3/5] Reorders value to store block above. --- src/jit.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/jit.rs b/src/jit.rs index 3495a2a3..7a525aaf 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -1083,6 +1083,22 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { fn emit_address_translation(&mut self, dst: Option, vm_addr: Value, len: u64, value: Option) { debug_assert_ne!(dst.is_some(), value.is_some()); + let stack_slot_of_value_to_store = X86IndirectAccess::OffsetIndexShift(-112, RSP, 0); + match value { + Some(Value::Register(reg)) => { + self.emit_ins(X86Instruction::mov(OperandSize::S64, reg, REGISTER_OTHER_SCRATCH)); + } + Some(Value::Constant64(constant, user_provided)) => { + if user_provided && self.should_sanitize_constant(constant) { + self.emit_sanitized_load_immediate(OperandSize::S64, REGISTER_OTHER_SCRATCH, constant); + } else { + self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_OTHER_SCRATCH, constant)); + } + } + _ => {} + } + self.emit_ins(X86Instruction::store(OperandSize::S64, REGISTER_OTHER_SCRATCH, RSP, stack_slot_of_value_to_store)); + match vm_addr { Value::RegisterPlusConstant64(reg, constant, user_provided) => { if user_provided && self.should_sanitize_constant(constant) { @@ -1105,22 +1121,6 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { }, } - let stack_slot_of_value_to_store = X86IndirectAccess::OffsetIndexShift(-112, RSP, 0); - match value { - Some(Value::Register(reg)) => { - self.emit_ins(X86Instruction::mov(OperandSize::S64, reg, REGISTER_OTHER_SCRATCH)); - } - Some(Value::Constant64(constant, user_provided)) => { - if user_provided && self.should_sanitize_constant(constant) { - self.emit_sanitized_load_immediate(OperandSize::S64, REGISTER_OTHER_SCRATCH, constant); - } else { - self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_OTHER_SCRATCH, constant)); - } - } - _ => {} - } - self.emit_ins(X86Instruction::store(OperandSize::S64, REGISTER_OTHER_SCRATCH, RSP, stack_slot_of_value_to_store)); - if self.config.enable_address_translation { let access_type = if value.is_none() { AccessType::Load } else { AccessType::Store }; let anchor = ANCHOR_TRANSLATE_MEMORY_ADDRESS + len.trailing_zeros() as usize + 4 * (access_type as usize); From 7b6c6e2f2baa0d6dbda88a98c2c9a47c2b43e1e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 25 Sep 2024 19:51:19 +0200 Subject: [PATCH 4/5] Replace usage of REGISTER_OTHER_SCRATCH with REGISTER_SCRATCH and stack_slot_of_value_to_store. --- src/jit.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/jit.rs b/src/jit.rs index 7a525aaf..6fa0d725 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -1086,18 +1086,18 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { let stack_slot_of_value_to_store = X86IndirectAccess::OffsetIndexShift(-112, RSP, 0); match value { Some(Value::Register(reg)) => { - self.emit_ins(X86Instruction::mov(OperandSize::S64, reg, REGISTER_OTHER_SCRATCH)); + self.emit_ins(X86Instruction::store(OperandSize::S64, reg, RSP, stack_slot_of_value_to_store)); } Some(Value::Constant64(constant, user_provided)) => { if user_provided && self.should_sanitize_constant(constant) { - self.emit_sanitized_load_immediate(OperandSize::S64, REGISTER_OTHER_SCRATCH, constant); + self.emit_sanitized_load_immediate(OperandSize::S64, REGISTER_SCRATCH, constant); } else { - self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_OTHER_SCRATCH, constant)); + self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_SCRATCH, constant)); } + self.emit_ins(X86Instruction::store(OperandSize::S64, REGISTER_SCRATCH, RSP, stack_slot_of_value_to_store)); } _ => {} } - self.emit_ins(X86Instruction::store(OperandSize::S64, REGISTER_OTHER_SCRATCH, RSP, stack_slot_of_value_to_store)); match vm_addr { Value::RegisterPlusConstant64(reg, constant, user_provided) => { From 8c5e9a9b151e00f793f3aa419eb538e9eeb689a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Wed, 25 Sep 2024 19:26:41 +0200 Subject: [PATCH 5/5] Same for the case in which address translation is disabled. --- src/jit.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/jit.rs b/src/jit.rs index 6fa0d725..1254109c 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -217,7 +217,7 @@ const REGISTER_PTR_TO_VM: u8 = ARGUMENT_REGISTERS[0]; /// RBX: Program counter limit const REGISTER_INSTRUCTION_METER: u8 = CALLEE_SAVED_REGISTERS[1]; /// R10: Other scratch register -const REGISTER_OTHER_SCRATCH: u8 = CALLER_SAVED_REGISTERS[7]; +// const REGISTER_OTHER_SCRATCH: u8 = CALLER_SAVED_REGISTERS[7]; /// R11: Scratch register const REGISTER_SCRATCH: u8 = CALLER_SAVED_REGISTERS[8]; @@ -1138,13 +1138,15 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { _ => unreachable!(), } } else { + self.emit_ins(X86Instruction::xchg(OperandSize::S64, RSP, REGISTER_MAP[0], Some(stack_slot_of_value_to_store))); // Save REGISTER_MAP[0] and retrieve value to store match len { - 1 => self.emit_ins(X86Instruction::store(OperandSize::S8, REGISTER_OTHER_SCRATCH, REGISTER_SCRATCH, X86IndirectAccess::Offset(0))), - 2 => self.emit_ins(X86Instruction::store(OperandSize::S16, REGISTER_OTHER_SCRATCH, REGISTER_SCRATCH, X86IndirectAccess::Offset(0))), - 4 => self.emit_ins(X86Instruction::store(OperandSize::S32, REGISTER_OTHER_SCRATCH, REGISTER_SCRATCH, X86IndirectAccess::Offset(0))), - 8 => self.emit_ins(X86Instruction::store(OperandSize::S64, REGISTER_OTHER_SCRATCH, REGISTER_SCRATCH, X86IndirectAccess::Offset(0))), + 1 => self.emit_ins(X86Instruction::store(OperandSize::S8, REGISTER_MAP[0], REGISTER_SCRATCH, X86IndirectAccess::Offset(0))), + 2 => self.emit_ins(X86Instruction::store(OperandSize::S16, REGISTER_MAP[0], REGISTER_SCRATCH, X86IndirectAccess::Offset(0))), + 4 => self.emit_ins(X86Instruction::store(OperandSize::S32, REGISTER_MAP[0], REGISTER_SCRATCH, X86IndirectAccess::Offset(0))), + 8 => self.emit_ins(X86Instruction::store(OperandSize::S64, REGISTER_MAP[0], REGISTER_SCRATCH, X86IndirectAccess::Offset(0))), _ => unreachable!(), } + self.emit_ins(X86Instruction::xchg(OperandSize::S64, RSP, REGISTER_MAP[0], Some(stack_slot_of_value_to_store))); // Restore REGISTER_MAP[0] } }