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 dis-/assembler.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Oct 3, 2024
1 parent 04b21e3 commit 1a1c148
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 103 deletions.
64 changes: 40 additions & 24 deletions src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
},
ebpf::{self, Insn},
elf::Executable,
program::{BuiltinProgram, FunctionRegistry},
program::{BuiltinProgram, FunctionRegistry, SBPFVersion},
vm::ContextObject,
};
use std::collections::HashMap;
Expand Down Expand Up @@ -47,7 +47,7 @@ enum InstructionType {
NoOperand,
}

fn make_instruction_map() -> HashMap<String, (InstructionType, u8)> {
fn make_instruction_map(sbpf_version: &SBPFVersion) -> HashMap<String, (InstructionType, u8)> {
let mut result = HashMap::new();

let alu_binary_ops = [
Expand All @@ -66,11 +66,31 @@ fn make_instruction_map() -> HashMap<String, (InstructionType, u8)> {
("hor", ebpf::BPF_HOR),
];

let mem_classes = [
(
"ldx",
LoadReg,
ebpf::BPF_MEM | ebpf::BPF_LDX,
ebpf::BPF_ALU | ebpf::BPF_X,
),
(
"st",
StoreImm,
ebpf::BPF_MEM | ebpf::BPF_ST,
ebpf::BPF_ALU64 | ebpf::BPF_K,
),
(
"stx",
StoreReg,
ebpf::BPF_MEM | ebpf::BPF_STX,
ebpf::BPF_ALU64 | ebpf::BPF_X,
),
];
let mem_sizes = [
("w", ebpf::BPF_W),
("h", ebpf::BPF_H),
("b", ebpf::BPF_B),
("dw", ebpf::BPF_DW),
("b", ebpf::BPF_B, ebpf::BPF_1B),
("h", ebpf::BPF_H, ebpf::BPF_2B),
("w", ebpf::BPF_W, ebpf::BPF_4B),
("dw", ebpf::BPF_DW, ebpf::BPF_8B),
];

let jump_conditions = [
Expand Down Expand Up @@ -189,23 +209,19 @@ fn make_instruction_map() -> HashMap<String, (InstructionType, u8)> {
);
entry("srem32", AluBinary, ebpf::BPF_PQR | ebpf::BPF_SREM);

// LoadReg, StoreImm, and StoreReg.
for &(suffix, size) in &mem_sizes {
entry(
&format!("ldx{suffix}"),
LoadReg,
ebpf::BPF_MEM | ebpf::BPF_LDX | size,
);
entry(
&format!("st{suffix}"),
StoreImm,
ebpf::BPF_MEM | ebpf::BPF_ST | size,
);
entry(
&format!("stx{suffix}"),
StoreReg,
ebpf::BPF_MEM | ebpf::BPF_STX | size,
);
// Memory
if sbpf_version.move_memory_instruction_classes() {
for &(prefix, class, _, opcode) in &mem_classes {
for &(suffix, _, size) in &mem_sizes {
entry(&format!("{prefix}{suffix}"), class, opcode | size);
}
}
} else {
for &(prefix, class, opcode, _) in &mem_classes {
for &(suffix, size, _) in &mem_sizes {
entry(&format!("{prefix}{suffix}"), class, opcode | size);
}
}
}

// JumpConditional.
Expand Down Expand Up @@ -300,7 +316,7 @@ pub fn assemble<C: ContextObject>(
let sbpf_version = loader.get_config().enabled_sbpf_versions.end().clone();

let statements = parse(src)?;
let instruction_map = make_instruction_map();
let instruction_map = make_instruction_map(&sbpf_version);
let mut insn_ptr = 0;
let mut function_registry = FunctionRegistry::default();
let mut labels = HashMap::new();
Expand Down
12 changes: 12 additions & 0 deletions src/disassembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,10 @@ pub fn disassemble_instruction<C: ContextObject>(
ebpf::SUB32_REG => { name = "sub32"; desc = alu_reg_str(name, insn); },
ebpf::MUL32_IMM if !sbpf_version.enable_pqr() => { name = "mul32"; desc = alu_imm_str(name, insn); },
ebpf::MUL32_REG if !sbpf_version.enable_pqr() => { name = "mul32"; desc = alu_reg_str(name, insn); },
ebpf::LD_1B_REG if sbpf_version.move_memory_instruction_classes() => { name = "ldxb"; desc = ld_reg_str(name, insn); },
ebpf::DIV32_IMM if !sbpf_version.enable_pqr() => { name = "div32"; desc = alu_imm_str(name, insn); },
ebpf::DIV32_REG if !sbpf_version.enable_pqr() => { name = "div32"; desc = alu_reg_str(name, insn); },
ebpf::LD_2B_REG if sbpf_version.move_memory_instruction_classes() => { name = "ldxh"; desc = ld_reg_str(name, insn); },
ebpf::OR32_IMM => { name = "or32"; desc = alu_imm_str(name, insn); },
ebpf::OR32_REG => { name = "or32"; desc = alu_reg_str(name, insn); },
ebpf::AND32_IMM => { name = "and32"; desc = alu_imm_str(name, insn); },
Expand All @@ -159,8 +161,10 @@ pub fn disassemble_instruction<C: ContextObject>(
ebpf::RSH32_IMM => { name = "rsh32"; desc = alu_imm_str(name, insn); },
ebpf::RSH32_REG => { name = "rsh32"; desc = alu_reg_str(name, insn); },
ebpf::NEG32 if sbpf_version.enable_neg() => { name = "neg32"; desc = format!("{} r{}", name, insn.dst); },
ebpf::LD_4B_REG if sbpf_version.move_memory_instruction_classes() => { name = "ldxw"; desc = ld_reg_str(name, insn); },
ebpf::MOD32_IMM if !sbpf_version.enable_pqr() => { name = "mod32"; desc = alu_imm_str(name, insn); },
ebpf::MOD32_REG if !sbpf_version.enable_pqr() => { name = "mod32"; desc = alu_reg_str(name, insn); },
ebpf::LD_8B_REG if sbpf_version.move_memory_instruction_classes() => { name = "ldxdw"; desc = ld_reg_str(name, insn); },
ebpf::XOR32_IMM => { name = "xor32"; desc = alu_imm_str(name, insn); },
ebpf::XOR32_REG => { name = "xor32"; desc = alu_reg_str(name, insn); },
ebpf::MOV32_IMM => { name = "mov32"; desc = alu_imm_str(name, insn); },
Expand All @@ -176,9 +180,13 @@ pub fn disassemble_instruction<C: ContextObject>(
ebpf::SUB64_IMM => { name = "sub64"; desc = alu_imm_str(name, insn); },
ebpf::SUB64_REG => { name = "sub64"; desc = alu_reg_str(name, insn); },
ebpf::MUL64_IMM if !sbpf_version.enable_pqr() => { name = "mul64"; desc = alu_imm_str(name, insn); },
ebpf::ST_1B_IMM if sbpf_version.move_memory_instruction_classes() => { name = "stb"; desc = ld_st_imm_str(name, insn); },
ebpf::MUL64_REG if !sbpf_version.enable_pqr() => { name = "mul64"; desc = alu_reg_str(name, insn); },
ebpf::ST_1B_REG if sbpf_version.move_memory_instruction_classes() => { name = "stxb"; desc = st_reg_str(name, insn); },
ebpf::DIV64_IMM if !sbpf_version.enable_pqr() => { name = "div64"; desc = alu_imm_str(name, insn); },
ebpf::ST_2B_IMM if sbpf_version.move_memory_instruction_classes() => { name = "sth"; desc = ld_st_imm_str(name, insn); },
ebpf::DIV64_REG if !sbpf_version.enable_pqr() => { name = "div64"; desc = alu_reg_str(name, insn); },
ebpf::ST_2B_REG if sbpf_version.move_memory_instruction_classes() => { name = "stxh"; desc = st_reg_str(name, insn); },
ebpf::OR64_IMM => { name = "or64"; desc = alu_imm_str(name, insn); },
ebpf::OR64_REG => { name = "or64"; desc = alu_reg_str(name, insn); },
ebpf::AND64_IMM => { name = "and64"; desc = alu_imm_str(name, insn); },
Expand All @@ -187,9 +195,13 @@ pub fn disassemble_instruction<C: ContextObject>(
ebpf::LSH64_REG => { name = "lsh64"; desc = alu_reg_str(name, insn); },
ebpf::RSH64_IMM => { name = "rsh64"; desc = alu_imm_str(name, insn); },
ebpf::RSH64_REG => { name = "rsh64"; desc = alu_reg_str(name, insn); },
ebpf::ST_4B_IMM if sbpf_version.move_memory_instruction_classes() => { name = "stw"; desc = ld_st_imm_str(name, insn); },
ebpf::NEG64 if sbpf_version.enable_neg() => { name = "neg64"; desc = format!("{} r{}", name, insn.dst); },
ebpf::ST_4B_REG if sbpf_version.move_memory_instruction_classes() => { name = "stxw"; desc = st_reg_str(name, insn); },
ebpf::MOD64_IMM if !sbpf_version.enable_pqr() => { name = "mod64"; desc = alu_imm_str(name, insn); },
ebpf::ST_8B_IMM if sbpf_version.move_memory_instruction_classes() => { name = "stdw"; desc = ld_st_imm_str(name, insn); },
ebpf::MOD64_REG if !sbpf_version.enable_pqr() => { name = "mod64"; desc = alu_reg_str(name, insn); },
ebpf::ST_8B_REG if sbpf_version.move_memory_instruction_classes() => { name = "stxdw"; desc = st_reg_str(name, insn); },
ebpf::XOR64_IMM => { name = "xor64"; desc = alu_imm_str(name, insn); },
ebpf::XOR64_REG => { name = "xor64"; desc = alu_reg_str(name, insn); },
ebpf::MOV64_IMM => { name = "mov64"; desc = alu_imm_str(name, insn); },
Expand Down
14 changes: 7 additions & 7 deletions test_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,21 @@ pub const TCP_SACK_ASM: &str = "
exit";

pub const TCP_SACK_BIN: [u8; 352] = [
0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x2c, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x2c, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, //
0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x55, 0x03, 0x25, 0x00, 0x08, 0x00, 0x00, 0x00, //
0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x2c, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x55, 0x02, 0x23, 0x00, 0x06, 0x00, 0x00, 0x00, //
0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x2c, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, //
0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, //
0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, //
0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x69, 0x14, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x3c, 0x14, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x07, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, //
0x77, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, //
0x57, 0x04, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, //
Expand All @@ -115,15 +115,15 @@ pub const TCP_SACK_BIN: [u8; 352] = [
0xc7, 0x05, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, //
0xbf, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x0f, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x71, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x15, 0x05, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, //
0x15, 0x05, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, //
0xbf, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x15, 0x05, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, //
0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x07, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, //
0xbf, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x71, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x2c, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x0f, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x67, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, //
0xc7, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, //
Expand Down
90 changes: 18 additions & 72 deletions tests/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,33 +72,6 @@ fn test_neg64() {
assert_eq!(asm("neg64 r1"), Ok(vec![insn(0, ebpf::NEG64, 1, 0, 0, 0)]));
}

// Example for InstructionType::LoadReg.
#[test]
fn test_ldxw() {
assert_eq!(
asm("ldxw r1, [r2+5]"),
Ok(vec![insn(0, ebpf::LD_W_REG, 1, 2, 5, 0)])
);
}

// Example for InstructionType::StoreImm.
#[test]
fn test_stw() {
assert_eq!(
asm("stw [r2+5], 7"),
Ok(vec![insn(0, ebpf::ST_W_IMM, 2, 0, 5, 7)])
);
}

// Example for InstructionType::StoreReg.
#[test]
fn test_stxw() {
assert_eq!(
asm("stxw [r2+5], r8"),
Ok(vec![insn(0, ebpf::ST_W_REG, 2, 8, 5, 0)])
);
}

// Example for InstructionType::JumpUnconditional.
#[test]
fn test_ja() {
Expand Down Expand Up @@ -161,33 +134,6 @@ fn test_lddw() {
);
}

// Example for InstructionType::LoadReg.
#[test]
fn test_ldxdw() {
assert_eq!(
asm("ldxdw r1, [r2+3]"),
Ok(vec![insn(0, ebpf::LD_DW_REG, 1, 2, 3, 0)])
);
}

// Example for InstructionType::StoreImm.
#[test]
fn test_sth() {
assert_eq!(
asm("sth [r1+2], 3"),
Ok(vec![insn(0, ebpf::ST_H_IMM, 1, 0, 2, 3)])
);
}

// Example for InstructionType::StoreReg.
#[test]
fn test_stxh() {
assert_eq!(
asm("stxh [r1+2], r3"),
Ok(vec![insn(0, ebpf::ST_H_REG, 1, 3, 2, 0)])
);
}

// Test all supported AluBinary mnemonics.
#[test]
fn test_alu_binary() {
Expand Down Expand Up @@ -385,15 +331,15 @@ fn test_alu_unary() {
#[test]
fn test_load_reg() {
assert_eq!(
asm("ldxw r1, [r2+3]
asm("ldxb r1, [r2+3]
ldxh r1, [r2+3]
ldxb r1, [r2+3]
ldxw r1, [r2+3]
ldxdw r1, [r2+3]"),
Ok(vec![
insn(0, ebpf::LD_W_REG, 1, 2, 3, 0),
insn(1, ebpf::LD_H_REG, 1, 2, 3, 0),
insn(2, ebpf::LD_B_REG, 1, 2, 3, 0),
insn(3, ebpf::LD_DW_REG, 1, 2, 3, 0)
insn(0, ebpf::LD_1B_REG, 1, 2, 3, 0),
insn(1, ebpf::LD_2B_REG, 1, 2, 3, 0),
insn(2, ebpf::LD_4B_REG, 1, 2, 3, 0),
insn(3, ebpf::LD_8B_REG, 1, 2, 3, 0)
])
);
}
Expand All @@ -402,15 +348,15 @@ fn test_load_reg() {
#[test]
fn test_store_imm() {
assert_eq!(
asm("stw [r1+2], 3
asm("stb [r1+2], 3
sth [r1+2], 3
stb [r1+2], 3
stw [r1+2], 3
stdw [r1+2], 3"),
Ok(vec![
insn(0, ebpf::ST_W_IMM, 1, 0, 2, 3),
insn(1, ebpf::ST_H_IMM, 1, 0, 2, 3),
insn(2, ebpf::ST_B_IMM, 1, 0, 2, 3),
insn(3, ebpf::ST_DW_IMM, 1, 0, 2, 3)
insn(0, ebpf::ST_1B_IMM, 1, 0, 2, 3),
insn(1, ebpf::ST_2B_IMM, 1, 0, 2, 3),
insn(2, ebpf::ST_4B_IMM, 1, 0, 2, 3),
insn(3, ebpf::ST_8B_IMM, 1, 0, 2, 3)
])
);
}
Expand All @@ -419,15 +365,15 @@ fn test_store_imm() {
#[test]
fn test_store_reg() {
assert_eq!(
asm("stxw [r1+2], r3
asm("stxb [r1+2], r3
stxh [r1+2], r3
stxb [r1+2], r3
stxw [r1+2], r3
stxdw [r1+2], r3"),
Ok(vec![
insn(0, ebpf::ST_W_REG, 1, 3, 2, 0),
insn(1, ebpf::ST_H_REG, 1, 3, 2, 0),
insn(2, ebpf::ST_B_REG, 1, 3, 2, 0),
insn(3, ebpf::ST_DW_REG, 1, 3, 2, 0)
insn(0, ebpf::ST_1B_REG, 1, 3, 2, 0),
insn(1, ebpf::ST_2B_REG, 1, 3, 2, 0),
insn(2, ebpf::ST_4B_REG, 1, 3, 2, 0),
insn(3, ebpf::ST_8B_REG, 1, 3, 2, 0)
])
);
}
Expand Down

0 comments on commit 1a1c148

Please sign in to comment.