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

Commit

Permalink
Refactor - lduw to hor64 (#496)
Browse files Browse the repository at this point in the history
* Makes "lduw" an arithmetic class instruction "hor64".

* Adjusts the test ELFs.
  • Loading branch information
Lichtso authored Aug 3, 2023
1 parent d56e0e1 commit d43d962
Show file tree
Hide file tree
Showing 14 changed files with 29 additions and 28 deletions.
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 @@ -805,7 +805,7 @@ fn test_div32_high_divisor() {
"
mov r0, 12
mov32 r1, 0x00000004
lduw r1, 0x00000001
hor64 r1, 0x00000001
div32 r0, r1
exit",
[],
Expand All @@ -820,7 +820,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 @@ -835,7 +835,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 @@ -851,7 +851,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 @@ -866,7 +866,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 @@ -881,7 +881,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 @@ -897,7 +897,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 @@ -1113,7 +1113,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 @@ -1323,11 +1323,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 @@ -2725,7 +2725,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

0 comments on commit d43d962

Please sign in to comment.