Skip to content
This repository has been archived by the owner on Jan 10, 2025. It is now read-only.

Commit

Permalink
Implements randomized emission of additional NoOps in JIT.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Mar 15, 2021
1 parent c2aec89 commit faa96a6
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::collections::HashMap;
use std::fmt::Formatter;
use std::fmt::Error as FormatterError;
use std::ops::{Index, IndexMut};
use rand::{rngs::ThreadRng, Rng};

use crate::{
vm::{Config, Executable, ProgramResult, InstructionMeter, Tracer, DynTraitFatPointer, SYSCALL_CONTEXT_OBJECTS_OFFSET},
Expand Down Expand Up @@ -123,6 +124,10 @@ impl<E: UserDefinedError, I: InstructionMeter> JitProgram<E, I> {
}
}

// Used for code randomization and defines how many
// additional NoOps per instruction will be emitted on average.
const INSTRUCTION_NOOP_RATIO: f64 = 1.0 / 128.0;

// Special values for target_pc in struct Jump
const TARGET_PC_TRACE: usize = std::usize::MAX - 13;
const TARGET_PC_TRANSLATE_PC: usize = std::usize::MAX - 12;
Expand Down Expand Up @@ -552,6 +557,16 @@ impl X86Instruction {
}
}

/// No operation
fn noop() -> Self {
Self {
size: OperandSize::S32,
opcode: 0x90,
modrm: false,
..Self::default()
}
}

/// Trap / software interrupt
#[allow(dead_code)]
fn interrupt(immediate: u8) -> Self {
Expand Down Expand Up @@ -1072,6 +1087,7 @@ struct JitCompiler {
program_vm_addr: u64,
handler_anchors: HashMap<usize, usize>,
config: Config,
rng: ThreadRng,
}

impl Index<usize> for JitCompiler {
Expand Down Expand Up @@ -1134,6 +1150,7 @@ impl JitCompiler {
program_vm_addr: 0,
handler_anchors: HashMap::new(),
config: *_config,
rng: rand::thread_rng(),
}
}

Expand All @@ -1157,6 +1174,10 @@ impl JitCompiler {

self.result.pc_section[self.pc] = self.offset_in_text_section as u64;

if self.config.enable_code_randomization && self.rng.gen_bool(INSTRUCTION_NOOP_RATIO) {
X86Instruction::noop().emit(self)?;
}

if self.config.enable_instruction_tracing {
X86Instruction::load_immediate(OperandSize::S64, R11, self.pc as i64).emit(self)?;
emit_call(self, TARGET_PC_TRACE)?;
Expand Down
3 changes: 3 additions & 0 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ pub struct Config {
pub enable_instruction_meter: bool,
/// Enable instruction tracing
pub enable_instruction_tracing: bool,
/// Enable randomization in the JIT code emitter
pub enable_code_randomization: bool,
}
impl Default for Config {
fn default() -> Self {
Expand All @@ -184,6 +186,7 @@ impl Default for Config {
stack_frame_size: 4_096,
enable_instruction_meter: true,
enable_instruction_tracing: false,
enable_code_randomization: true,
}
}
}
Expand Down

0 comments on commit faa96a6

Please sign in to comment.