Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor - lduw to hor64 #496

Merged
merged 2 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

use self::InstructionType::{
AluBinary, AluUnary, CallImm, CallReg, Endian, JumpConditional, JumpUnconditional, LoadAbs,
LoadDwImm, LoadInd, LoadReg, LoadUwImm, NoOperand, StoreImm, StoreReg, Syscall,
LoadDwImm, LoadInd, LoadReg, NoOperand, StoreImm, StoreReg, Syscall,
};
use crate::{
asm_parser::{
Expand All @@ -28,7 +28,6 @@ use std::{collections::HashMap, sync::Arc};
enum InstructionType {
AluBinary,
AluUnary,
LoadUwImm,
LoadDwImm,
LoadAbs,
LoadInd,
Expand Down Expand Up @@ -60,6 +59,7 @@ fn make_instruction_map() -> HashMap<String, (InstructionType, u8)> {
("xor", ebpf::BPF_XOR),
("mov", ebpf::BPF_MOV),
("arsh", ebpf::BPF_ARSH),
("hor", ebpf::BPF_HOR),
];

let mem_sizes = [
Expand Down Expand Up @@ -94,7 +94,6 @@ fn make_instruction_map() -> HashMap<String, (InstructionType, u8)> {
entry("syscall", Syscall, ebpf::CALL_IMM);
entry("call", CallImm, ebpf::CALL_IMM);
entry("callx", CallReg, ebpf::CALL_REG);
entry("lduw", LoadUwImm, ebpf::LD_UW_IMM);
entry("lddw", LoadDwImm, ebpf::LD_DW_IMM);

// AluUnary.
Expand Down Expand Up @@ -340,7 +339,6 @@ pub fn assemble<C: ContextObject>(
insn(opc, 0, 1, 0, target_pc as i64)
}
(Endian(size), [Register(dst)]) => insn(opc, *dst, 0, 0, size),
(LoadUwImm, [Register(dst), Integer(imm)]) => insn(opc, *dst, 0, 0, *imm),
(LoadDwImm, [Register(dst), Integer(imm)]) => {
insn(opc, *dst, 0, 0, (*imm << 32) >> 32)
}
Expand Down
2 changes: 1 addition & 1 deletion src/disassembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ pub fn disassemble_instruction<C: ContextObject>(
let desc;
match insn.opc {
// BPF_LD class
ebpf::LD_UW_IMM => { name = "lduw"; desc = format!("{} r{:}, {:#x}", name, insn.dst, insn.imm); },
ebpf::LD_DW_IMM => { name = "lddw"; desc = format!("{} r{:}, {:#x}", name, insn.dst, insn.imm); },

// BPF_LDX class
Expand Down Expand Up @@ -201,6 +200,7 @@ pub fn disassemble_instruction<C: ContextObject>(
ebpf::MOV64_REG => { name = "mov64"; desc = alu_reg_str(name, insn); },
ebpf::ARSH64_IMM => { name = "arsh64"; desc = alu_imm_str(name, insn); },
ebpf::ARSH64_REG => { name = "arsh64"; desc = alu_reg_str(name, insn); },
ebpf::HOR64_IMM => { name = "hor64"; desc = alu_reg_str(name, insn); },

// BPF_JMP class
ebpf::JA => {
Expand Down
6 changes: 4 additions & 2 deletions src/ebpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ pub const BPF_ARSH: u8 = 0xc0;
pub const BPF_END: u8 = 0xd0;
/// BPF ALU/ALU64 operation code: signed division.
pub const BPF_SDIV: u8 = 0xe0;
/// BPF ALU/ALU64 operation code: high or.
pub const BPF_HOR: u8 = 0xf0;

// Operation codes -- BPF_JMP class:
/// BPF JMP operation code: jump.
Expand Down Expand Up @@ -186,8 +188,6 @@ pub const BPF_JSLE: u8 = 0xd0;
// (Following operation names are not “official”, but may be proper to rbpf; Linux kernel only
// combines above flags and does not attribute a name per operation.)

/// BPF opcode: `lduw dst, imm` /// `dst |= imm << 32`.
pub const LD_UW_IMM: u8 = BPF_LD | BPF_IMM | BPF_W;
/// BPF opcode: `lddw dst, imm` /// `dst = imm`.
pub const LD_DW_IMM: u8 = BPF_LD | BPF_IMM | BPF_DW;
/// BPF opcode: `ldxb dst, [src + off]` /// `dst = (src + off) as u8`.
Expand Down Expand Up @@ -337,6 +337,8 @@ pub const ARSH64_REG: u8 = BPF_ALU64 | BPF_X | BPF_ARSH;
pub const SDIV64_IMM: u8 = BPF_ALU64 | BPF_K | BPF_SDIV;
/// BPF opcode: `sdiv64 dst, src` /// `dst s/= src`.
pub const SDIV64_REG: u8 = BPF_ALU64 | BPF_X | BPF_SDIV;
/// BPF opcode: `hor64 dst, imm` /// `dst |= imm << 32`.
pub const HOR64_IMM: u8 = BPF_ALU64 | BPF_K | BPF_HOR;

/// BPF opcode: `ja +off` /// `PC += off`.
pub const JA: u8 = BPF_JMP | BPF_JA;
Expand Down
6 changes: 3 additions & 3 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,6 @@ impl<'a, 'b, V: Verifier, C: ContextObject> Interpreter<'a, 'b, V, C> {
self.vm.stack_pointer = self.vm.stack_pointer.overflowing_add(insn.imm as u64).0;
}

ebpf::LD_UW_IMM if self.executable.get_sbpf_version().disable_lddw() => {
self.reg[dst] |= (insn.imm as u64).wrapping_shl(32);
}
ebpf::LD_DW_IMM => {
ebpf::augment_lddw_unchecked(self.program, &mut insn);
instruction_width = 2;
Expand Down Expand Up @@ -392,6 +389,9 @@ impl<'a, 'b, V: Verifier, C: ContextObject> Interpreter<'a, 'b, V, C> {
ebpf::MOV64_REG => self.reg[dst] = self.reg[src],
ebpf::ARSH64_IMM => self.reg[dst] = (self.reg[dst] as i64).wrapping_shr(insn.imm as u32) as u64,
ebpf::ARSH64_REG => self.reg[dst] = (self.reg[dst] as i64).wrapping_shr(self.reg[src] as u32) as u64,
ebpf::HOR64_IMM if self.executable.get_sbpf_version().disable_lddw() => {
self.reg[dst] |= (insn.imm as u64).wrapping_shl(32);
}

// BPF_JMP class
ebpf::JA => { self.pc = (self.pc as isize + insn.off as isize) as usize; },
Expand Down
6 changes: 3 additions & 3 deletions src/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,6 @@ impl<'a, V: Verifier, C: ContextObject> JitCompiler<'a, V, C> {
self.emit_ins(X86Instruction::alu(OperandSize::S64, 0x81, 0, RBP, insn.imm, Some(stack_ptr_access)));
}

ebpf::LD_UW_IMM => {
self.emit_sanitized_alu(OperandSize::S64, 0x09, 1, dst, (insn.imm as u64).wrapping_shl(32) as i64);
}
ebpf::LD_DW_IMM => {
self.emit_validate_and_profile_instruction_count(true, Some(self.pc + 2));
self.pc += 1;
Expand Down Expand Up @@ -590,6 +587,9 @@ impl<'a, V: Verifier, C: ContextObject> JitCompiler<'a, V, C> {
ebpf::MOV64_REG => self.emit_ins(X86Instruction::mov(OperandSize::S64, src, dst)),
ebpf::ARSH64_IMM => self.emit_shift(OperandSize::S64, 7, R11, dst, Some(insn.imm)),
ebpf::ARSH64_REG => self.emit_shift(OperandSize::S64, 7, src, dst, None),
ebpf::HOR64_IMM => {
self.emit_sanitized_alu(OperandSize::S64, 0x09, 1, dst, (insn.imm as u64).wrapping_shl(32) as i64);
}

// BPF_JMP class
ebpf::JA => {
Expand Down
3 changes: 2 additions & 1 deletion src/static_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@ impl<'a> Analysis<'a> {
state.0 = *basic_block_start;
for insn in self.instructions[basic_block.instructions.clone()].iter() {
match insn.opc {
ebpf::LD_UW_IMM | ebpf::LD_DW_IMM => {
ebpf::LD_DW_IMM => {
bind(&mut state, insn, true, DataResource::Register(insn.dst));
}
ebpf::LD_B_REG | ebpf::LD_H_REG | ebpf::LD_W_REG | ebpf::LD_DW_REG => {
Expand Down Expand Up @@ -987,6 +987,7 @@ impl<'a> Analysis<'a> {
| ebpf::MOD64_IMM
| ebpf::XOR64_IMM
| ebpf::ARSH64_IMM
| ebpf::HOR64_IMM
| ebpf::NEG32
| ebpf::NEG64
| ebpf::LE
Expand Down
2 changes: 1 addition & 1 deletion src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ impl Verifier for RequisiteVerifier {
}

match insn.opc {
ebpf::LD_UW_IMM if sbpf_version.disable_lddw() => {},
ebpf::LD_DW_IMM if !sbpf_version.disable_lddw() => {
check_load_dw(prog, insn_ptr)?;
insn_ptr += 1;
Expand Down Expand Up @@ -334,6 +333,7 @@ impl Verifier for RequisiteVerifier {
ebpf::MOV64_REG => {},
ebpf::ARSH64_IMM => { check_imm_shift(&insn, insn_ptr, 64)?; },
ebpf::ARSH64_REG => {},
ebpf::HOR64_IMM if sbpf_version.disable_lddw() => {},

// BPF_JMP class
ebpf::JA => { check_jmp_offset(prog, insn_ptr, &function_range)?; },
Expand Down
Binary file modified tests/elfs/reloc_64_64.so
Binary file not shown.
Binary file modified tests/elfs/reloc_64_relative.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.
Binary file modified tests/elfs/struct_func_pointer.so
Binary file not shown.
Binary file modified tests/elfs/syscall_static.so
Binary file not shown.
26 changes: 13 additions & 13 deletions tests/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ fn test_arsh32_high_shift() {
"
mov r0, 8
mov32 r1, 0x00000001
lduw r1, 0x00000001
hor64 r1, 0x00000001
arsh32 r0, r1
exit",
[],
Expand Down Expand Up @@ -796,7 +796,7 @@ fn test_div32_high_divisor() {
"
mov r0, 12
mov32 r1, 0x00000004
lduw r1, 0x00000001
hor64 r1, 0x00000001
div32 r0, r1
exit",
[],
Expand All @@ -811,7 +811,7 @@ fn test_div32_imm() {
test_interpreter_and_jit_asm!(
"
mov32 r0, 0x0000000c
lduw r0, 0x00000001
hor64 r0, 0x00000001
div32 r0, 4
exit",
[],
Expand All @@ -826,7 +826,7 @@ fn test_div32_reg() {
test_interpreter_and_jit_asm!(
"
mov32 r0, 0x0000000c
lduw r0, 0x00000001
hor64 r0, 0x00000001
mov r1, 4
div32 r0, r1
exit",
Expand All @@ -842,7 +842,7 @@ fn test_sdiv32_imm() {
test_interpreter_and_jit_asm!(
"
mov32 r0, -0x80000000
lduw r0, 0x00000001
hor64 r0, 0x00000001
sdiv32 r0, 4
exit",
[],
Expand All @@ -857,7 +857,7 @@ fn test_sdiv32_neg_imm() {
test_interpreter_and_jit_asm!(
"
mov32 r0, 0x0000000c
lduw r0, 0x00000001
hor64 r0, 0x00000001
sdiv32 r0, -1
exit",
[],
Expand All @@ -872,7 +872,7 @@ fn test_sdiv32_reg() {
test_interpreter_and_jit_asm!(
"
mov32 r0, -0x80000000
lduw r0, 0x00000001
hor64 r0, 0x00000001
mov r1, 4
sdiv32 r0, r1
exit",
Expand All @@ -888,7 +888,7 @@ fn test_sdiv32_neg_reg() {
test_interpreter_and_jit_asm!(
"
mov32 r0, 0x0000000c
lduw r0, 0x00000001
hor64 r0, 0x00000001
mov r1, -1
sdiv32 r0, r1
exit",
Expand Down Expand Up @@ -1104,7 +1104,7 @@ fn test_mod32_imm() {
test_interpreter_and_jit_asm!(
"
mov32 r0, 0x00000003
lduw r0, 0x00000001
hor64 r0, 0x00000001
mod32 r0, 3
exit",
[],
Expand Down Expand Up @@ -1314,11 +1314,11 @@ fn test_err_instruction_count_lddw_capped() {
// BPF_LD : Loads

#[test]
fn test_lduw() {
fn test_hor64() {
test_interpreter_and_jit_asm!(
"
lduw r0, 0x10203040
lduw r0, 0x01020304
hor64 r0, 0x10203040
hor64 r0, 0x01020304
exit",
[],
(),
Expand Down Expand Up @@ -2716,7 +2716,7 @@ fn test_err_mem_access_out_of_bound() {
let mem = [0; 512];
let mut prog = [0; 32];
prog[0] = ebpf::MOV32_IMM;
prog[8] = ebpf::LD_UW_IMM;
prog[8] = ebpf::HOR64_IMM;
prog[16] = ebpf::ST_B_IMM;
prog[24] = ebpf::EXIT;
let loader = Arc::new(BuiltinProgram::new_mock());
Expand Down