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

Commit

Permalink
Enables the new opcodes conditionally in the interpreter and JIT.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Oct 3, 2024
1 parent 1a1c148 commit 98769f8
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 2 deletions.
50 changes: 49 additions & 1 deletion src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {

// BPF_ST class
ebpf::ST_B_IMM if !self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add( insn.off as i64) as u64;
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, insn.imm, vm_addr, u8);
},
ebpf::ST_H_IMM if !self.executable.get_sbpf_version().move_memory_instruction_classes() => {
Expand Down Expand Up @@ -258,11 +258,19 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
ebpf::SUB32_REG => self.reg[dst] = (self.reg[dst] as i32).wrapping_sub(self.reg[src] as i32) as u64,
ebpf::MUL32_IMM if !self.executable.get_sbpf_version().enable_pqr() => self.reg[dst] = (self.reg[dst] as i32).wrapping_mul(insn.imm as i32) as u64,
ebpf::MUL32_REG if !self.executable.get_sbpf_version().enable_pqr() => self.reg[dst] = (self.reg[dst] as i32).wrapping_mul(self.reg[src] as i32) as u64,
ebpf::LD_1B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[src] as i64).wrapping_add(insn.off as i64) as u64;
self.reg[dst] = translate_memory_access!(self, load, vm_addr, u8);
},
ebpf::DIV32_IMM if !self.executable.get_sbpf_version().enable_pqr() => self.reg[dst] = (self.reg[dst] as u32 / insn.imm as u32) as u64,
ebpf::DIV32_REG if !self.executable.get_sbpf_version().enable_pqr() => {
throw_error!(DivideByZero; self, self.reg[src], u32);
self.reg[dst] = (self.reg[dst] as u32 / self.reg[src] as u32) as u64;
},
ebpf::LD_2B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[src] as i64).wrapping_add(insn.off as i64) as u64;
self.reg[dst] = translate_memory_access!(self, load, vm_addr, u16);
},
ebpf::OR32_IMM => self.reg[dst] = (self.reg[dst] as u32 | insn.imm as u32) as u64,
ebpf::OR32_REG => self.reg[dst] = (self.reg[dst] as u32 | self.reg[src] as u32) as u64,
ebpf::AND32_IMM => self.reg[dst] = (self.reg[dst] as u32 & insn.imm as u32) as u64,
Expand All @@ -272,11 +280,19 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
ebpf::RSH32_IMM => self.reg[dst] = (self.reg[dst] as u32).wrapping_shr(insn.imm as u32) as u64,
ebpf::RSH32_REG => self.reg[dst] = (self.reg[dst] as u32).wrapping_shr(self.reg[src] as u32) as u64,
ebpf::NEG32 if self.executable.get_sbpf_version().enable_neg() => self.reg[dst] = (self.reg[dst] as i32).wrapping_neg() as u64 & (u32::MAX as u64),
ebpf::LD_4B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[src] as i64).wrapping_add(insn.off as i64) as u64;
self.reg[dst] = translate_memory_access!(self, load, vm_addr, u32);
},
ebpf::MOD32_IMM if !self.executable.get_sbpf_version().enable_pqr() => self.reg[dst] = (self.reg[dst] as u32 % insn.imm as u32) as u64,
ebpf::MOD32_REG if !self.executable.get_sbpf_version().enable_pqr() => {
throw_error!(DivideByZero; self, self.reg[src], u32);
self.reg[dst] = (self.reg[dst] as u32 % self.reg[src] as u32) as u64;
},
ebpf::LD_8B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[src] as i64).wrapping_add(insn.off as i64) as u64;
self.reg[dst] = translate_memory_access!(self, load, vm_addr, u64);
},
ebpf::XOR32_IMM => self.reg[dst] = (self.reg[dst] as u32 ^ insn.imm as u32) as u64,
ebpf::XOR32_REG => self.reg[dst] = (self.reg[dst] as u32 ^ self.reg[src] as u32) as u64,
ebpf::MOV32_IMM => self.reg[dst] = insn.imm as u32 as u64,
Expand Down Expand Up @@ -314,12 +330,28 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
},
ebpf::SUB64_REG => self.reg[dst] = self.reg[dst].wrapping_sub(self.reg[src]),
ebpf::MUL64_IMM if !self.executable.get_sbpf_version().enable_pqr() => self.reg[dst] = self.reg[dst].wrapping_mul(insn.imm as u64),
ebpf::ST_1B_IMM if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, insn.imm, vm_addr, u8);
},
ebpf::MUL64_REG if !self.executable.get_sbpf_version().enable_pqr() => self.reg[dst] = self.reg[dst].wrapping_mul(self.reg[src]),
ebpf::ST_1B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, self.reg[src], vm_addr, u8);
},
ebpf::DIV64_IMM if !self.executable.get_sbpf_version().enable_pqr() => self.reg[dst] /= insn.imm as u64,
ebpf::ST_2B_IMM if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, insn.imm, vm_addr, u16);
},
ebpf::DIV64_REG if !self.executable.get_sbpf_version().enable_pqr() => {
throw_error!(DivideByZero; self, self.reg[src], u64);
self.reg[dst] /= self.reg[src];
},
ebpf::ST_2B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, self.reg[src], vm_addr, u16);
},
ebpf::OR64_IMM => self.reg[dst] |= insn.imm as u64,
ebpf::OR64_REG => self.reg[dst] |= self.reg[src],
ebpf::AND64_IMM => self.reg[dst] &= insn.imm as u64,
Expand All @@ -328,12 +360,28 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
ebpf::LSH64_REG => self.reg[dst] = self.reg[dst].wrapping_shl(self.reg[src] as u32),
ebpf::RSH64_IMM => self.reg[dst] = self.reg[dst].wrapping_shr(insn.imm as u32),
ebpf::RSH64_REG => self.reg[dst] = self.reg[dst].wrapping_shr(self.reg[src] as u32),
ebpf::ST_4B_IMM if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, insn.imm, vm_addr, u32);
},
ebpf::NEG64 if self.executable.get_sbpf_version().enable_neg() => self.reg[dst] = (self.reg[dst] as i64).wrapping_neg() as u64,
ebpf::ST_4B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, self.reg[src], vm_addr, u32);
},
ebpf::MOD64_IMM if !self.executable.get_sbpf_version().enable_pqr() => self.reg[dst] %= insn.imm as u64,
ebpf::ST_8B_IMM if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, insn.imm, vm_addr, u64);
},
ebpf::MOD64_REG if !self.executable.get_sbpf_version().enable_pqr() => {
throw_error!(DivideByZero; self, self.reg[src], u64);
self.reg[dst] %= self.reg[src];
},
ebpf::ST_8B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
let vm_addr = (self.reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
translate_memory_access!(self, store, self.reg[src], vm_addr, u64);
},
ebpf::XOR64_IMM => self.reg[dst] ^= insn.imm as u64,
ebpf::XOR64_REG => self.reg[dst] ^= self.reg[src],
ebpf::MOV64_IMM => self.reg[dst] = insn.imm as u64,
Expand Down
36 changes: 36 additions & 0 deletions src/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,14 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
},
ebpf::MUL32_IMM | ebpf::DIV32_IMM | ebpf::MOD32_IMM if !self.executable.get_sbpf_version().enable_pqr() =>
self.emit_product_quotient_remainder(OperandSize::S32, (insn.opc & ebpf::BPF_ALU_OP_MASK) == ebpf::BPF_MOD, (insn.opc & ebpf::BPF_ALU_OP_MASK) != ebpf::BPF_MUL, (insn.opc & ebpf::BPF_ALU_OP_MASK) == ebpf::BPF_MUL, dst, dst, Some(insn.imm)),
ebpf::LD_1B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(Some(dst), Value::RegisterPlusConstant64(src, insn.off as i64, true), 1, None);
},
ebpf::MUL32_REG | ebpf::DIV32_REG | ebpf::MOD32_REG if !self.executable.get_sbpf_version().enable_pqr() =>
self.emit_product_quotient_remainder(OperandSize::S32, (insn.opc & ebpf::BPF_ALU_OP_MASK) == ebpf::BPF_MOD, (insn.opc & ebpf::BPF_ALU_OP_MASK) != ebpf::BPF_MUL, (insn.opc & ebpf::BPF_ALU_OP_MASK) == ebpf::BPF_MUL, src, dst, None),
ebpf::LD_2B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(Some(dst), Value::RegisterPlusConstant64(src, insn.off as i64, true), 2, None);
},
ebpf::OR32_IMM => self.emit_sanitized_alu(OperandSize::S32, 0x09, 1, dst, insn.imm),
ebpf::OR32_REG => self.emit_ins(X86Instruction::alu(OperandSize::S32, 0x09, src, dst, 0, None)),
ebpf::AND32_IMM => self.emit_sanitized_alu(OperandSize::S32, 0x21, 4, dst, insn.imm),
Expand All @@ -517,6 +523,12 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
ebpf::RSH32_IMM => self.emit_shift(OperandSize::S32, 5, REGISTER_SCRATCH, dst, Some(insn.imm)),
ebpf::RSH32_REG => self.emit_shift(OperandSize::S32, 5, src, dst, None),
ebpf::NEG32 if self.executable.get_sbpf_version().enable_neg() => self.emit_ins(X86Instruction::alu(OperandSize::S32, 0xf7, 3, dst, 0, None)),
ebpf::LD_4B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(Some(dst), Value::RegisterPlusConstant64(src, insn.off as i64, true), 4, None);
},
ebpf::LD_8B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(Some(dst), Value::RegisterPlusConstant64(src, insn.off as i64, true), 8, None);
},
ebpf::XOR32_IMM => self.emit_sanitized_alu(OperandSize::S32, 0x31, 6, dst, insn.imm),
ebpf::XOR32_REG => self.emit_ins(X86Instruction::alu(OperandSize::S32, 0x31, src, dst, 0, None)),
ebpf::MOV32_IMM => {
Expand Down Expand Up @@ -573,8 +585,20 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
ebpf::SUB64_REG => self.emit_ins(X86Instruction::alu(OperandSize::S64, 0x29, src, dst, 0, None)),
ebpf::MUL64_IMM | ebpf::DIV64_IMM | ebpf::MOD64_IMM if !self.executable.get_sbpf_version().enable_pqr() =>
self.emit_product_quotient_remainder(OperandSize::S64, (insn.opc & ebpf::BPF_ALU_OP_MASK) == ebpf::BPF_MOD, (insn.opc & ebpf::BPF_ALU_OP_MASK) != ebpf::BPF_MUL, (insn.opc & ebpf::BPF_ALU_OP_MASK) == ebpf::BPF_MUL, dst, dst, Some(insn.imm)),
ebpf::ST_1B_IMM if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(None, Value::RegisterPlusConstant64(dst, insn.off as i64, true), 1, Some(Value::Constant64(insn.imm, true)));
},
ebpf::ST_2B_IMM if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(None, Value::RegisterPlusConstant64(dst, insn.off as i64, true), 2, Some(Value::Constant64(insn.imm, true)));
},
ebpf::MUL64_REG | ebpf::DIV64_REG | ebpf::MOD64_REG if !self.executable.get_sbpf_version().enable_pqr() =>
self.emit_product_quotient_remainder(OperandSize::S64, (insn.opc & ebpf::BPF_ALU_OP_MASK) == ebpf::BPF_MOD, (insn.opc & ebpf::BPF_ALU_OP_MASK) != ebpf::BPF_MUL, (insn.opc & ebpf::BPF_ALU_OP_MASK) == ebpf::BPF_MUL, src, dst, None),
ebpf::ST_1B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(None, Value::RegisterPlusConstant64(dst, insn.off as i64, true), 1, Some(Value::Register(src)));
},
ebpf::ST_2B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(None, Value::RegisterPlusConstant64(dst, insn.off as i64, true), 2, Some(Value::Register(src)));
},
ebpf::OR64_IMM => self.emit_sanitized_alu(OperandSize::S64, 0x09, 1, dst, insn.imm),
ebpf::OR64_REG => self.emit_ins(X86Instruction::alu(OperandSize::S64, 0x09, src, dst, 0, None)),
ebpf::AND64_IMM => self.emit_sanitized_alu(OperandSize::S64, 0x21, 4, dst, insn.imm),
Expand All @@ -583,7 +607,19 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
ebpf::LSH64_REG => self.emit_shift(OperandSize::S64, 4, src, dst, None),
ebpf::RSH64_IMM => self.emit_shift(OperandSize::S64, 5, REGISTER_SCRATCH, dst, Some(insn.imm)),
ebpf::RSH64_REG => self.emit_shift(OperandSize::S64, 5, src, dst, None),
ebpf::ST_4B_IMM if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(None, Value::RegisterPlusConstant64(dst, insn.off as i64, true), 4, Some(Value::Constant64(insn.imm, true)));
},
ebpf::NEG64 if self.executable.get_sbpf_version().enable_neg() => self.emit_ins(X86Instruction::alu(OperandSize::S64, 0xf7, 3, dst, 0, None)),
ebpf::ST_4B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(None, Value::RegisterPlusConstant64(dst, insn.off as i64, true), 4, Some(Value::Register(src)));
},
ebpf::ST_8B_IMM if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(None, Value::RegisterPlusConstant64(dst, insn.off as i64, true), 8, Some(Value::Constant64(insn.imm, true)));
},
ebpf::ST_8B_REG if self.executable.get_sbpf_version().move_memory_instruction_classes() => {
self.emit_address_translation(None, Value::RegisterPlusConstant64(dst, insn.off as i64, true), 8, Some(Value::Register(src)));
},
ebpf::XOR64_IMM => self.emit_sanitized_alu(OperandSize::S64, 0x31, 6, dst, insn.imm),
ebpf::XOR64_REG => self.emit_ins(X86Instruction::alu(OperandSize::S64, 0x31, src, dst, 0, None)),
ebpf::MOV64_IMM => {
Expand Down
Binary file modified tests/elfs/relative_call.so
Binary file not shown.
Binary file modified tests/elfs/reloc_64_relative_data.so
Binary file not shown.
Binary file modified tests/elfs/rodata_section.so
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2172,7 +2172,7 @@ fn test_err_mem_access_out_of_bound() {
let mut prog = [0; 32];
prog[0] = ebpf::MOV32_IMM;
prog[8] = ebpf::HOR64_IMM;
prog[16] = ebpf::ST_B_IMM;
prog[16] = ebpf::ST_1B_IMM;
prog[24] = ebpf::EXIT;
let loader = Arc::new(BuiltinProgram::new_mock());
for address in [0x2u64, 0x8002u64, 0x80000002u64, 0x8000000000000002u64] {
Expand Down

0 comments on commit 98769f8

Please sign in to comment.