Explorar o código

assembler: support ldabs and ldind instructions

Rich Lane %!s(int64=8) %!d(string=hai) anos
pai
achega
3a169a0965
Modificáronse 2 ficheiros con 53 adicións e 4 borrados
  1. 13 3
      src/assembler.rs
  2. 40 1
      tests/assembler.rs

+ 13 - 3
src/assembler.rs

@@ -11,8 +11,8 @@ use asm_parser::{Instruction, Operand, parse};
 use ebpf;
 use ebpf::Insn;
 use std::collections::HashMap;
-use self::InstructionType::{AluBinary, AluUnary, LoadImm, LoadReg, StoreImm, StoreReg,
-                            JumpUnconditional, JumpConditional, Call, Endian, NoOperand};
+use self::InstructionType::{AluBinary, AluUnary, LoadAbs, LoadInd, LoadImm, LoadReg, StoreImm,
+                            StoreReg, JumpUnconditional, JumpConditional, Call, Endian, NoOperand};
 use asm_parser::Operand::{Integer, Memory, Register, Nil};
 
 #[derive(Clone, Copy, Debug, PartialEq)]
@@ -20,6 +20,8 @@ enum InstructionType {
     AluBinary,
     AluUnary,
     LoadImm,
+    LoadAbs,
+    LoadInd,
     LoadReg,
     StoreImm,
     StoreReg,
@@ -80,8 +82,14 @@ fn make_instruction_map() -> HashMap<String, (InstructionType, u8)> {
             entry(&format!("{}64", name), AluBinary, ebpf::BPF_ALU64 | opc);
         }
 
-        // Load, StoreImm, and StoreReg.
+        // LoadAbs, LoadInd, LoadReg, StoreImm, and StoreReg.
         for &(suffix, size) in &mem_sizes {
+            entry(&format!("ldabs{}", suffix),
+                  LoadAbs,
+                  ebpf::BPF_ABS | ebpf::BPF_LD | size);
+            entry(&format!("ldind{}", suffix),
+                  LoadInd,
+                  ebpf::BPF_IND | ebpf::BPF_LD | size);
             entry(&format!("ldx{}", suffix),
                   LoadReg,
                   ebpf::BPF_MEM | ebpf::BPF_LDX | size);
@@ -147,6 +155,8 @@ fn encode(inst_type: InstructionType, opc: u8, operands: &[Operand]) -> Result<I
         (AluBinary, Register(dst), Register(src), Nil) => insn(opc | ebpf::BPF_X, dst, src, 0, 0),
         (AluBinary, Register(dst), Integer(imm), Nil) => insn(opc | ebpf::BPF_K, dst, 0, 0, imm),
         (AluUnary, Register(dst), Nil, Nil) => insn(opc, dst, 0, 0, 0),
+        (LoadAbs, Integer(imm), Nil, Nil) => insn(opc, 0, 0, 0, imm),
+        (LoadInd, Register(src), Integer(imm), Nil) => insn(opc, 0, src, 0, imm),
         (LoadReg, Register(dst), Memory(src, off), Nil) |
         (StoreReg, Memory(dst, off), Register(src), Nil) => insn(opc, dst, src, off, 0),
         (StoreImm, Memory(dst, off), Integer(imm), Nil) => insn(opc, dst, 0, off, imm),

+ 40 - 1
tests/assembler.rs

@@ -109,6 +109,19 @@ fn test_lddw() {
                        insn(0, 0, 0, 0, 0xff11ee22u32 as i32)]));
 }
 
+// Example for InstructionType::LoadAbs.
+#[test]
+fn test_ldabsw() {
+    assert_eq!(asm("ldabsw 1"), Ok(vec![insn(ebpf::LD_ABS_W, 0, 0, 0, 1)]));
+}
+
+// Example for InstructionType::LoadInd.
+#[test]
+fn test_ldindw() {
+    assert_eq!(asm("ldindw r1, 2"),
+               Ok(vec![insn(ebpf::LD_IND_W, 0, 1, 0, 2)]));
+}
+
 // Example for InstructionType::LoadReg.
 #[test]
 fn test_ldxdw() {
@@ -295,9 +308,35 @@ fn test_alu_unary() {
                        insn(ebpf::NEG32, 1, 0, 0, 0)]));
 }
 
+// Test all supported LoadAbs mnemonics.
+#[test]
+fn test_load_abs() {
+    assert_eq!(asm("ldabsw 1
+                    ldabsh 1
+                    ldabsb 1
+                    ldabsdw 1"),
+               Ok(vec![insn(ebpf::LD_ABS_W, 0, 0, 0, 1),
+                       insn(ebpf::LD_ABS_H, 0, 0, 0, 1),
+                       insn(ebpf::LD_ABS_B, 0, 0, 0, 1),
+                       insn(ebpf::LD_ABS_DW, 0, 0, 0, 1)]));
+}
+
+// Test all supported LoadInd mnemonics.
+#[test]
+fn test_load_ind() {
+    assert_eq!(asm("ldindw r1, 2
+                    ldindh r1, 2
+                    ldindb r1, 2
+                    ldinddw r1, 2"),
+               Ok(vec![insn(ebpf::LD_IND_W, 0, 1, 0, 2),
+                       insn(ebpf::LD_IND_H, 0, 1, 0, 2),
+                       insn(ebpf::LD_IND_B, 0, 1, 0, 2),
+                       insn(ebpf::LD_IND_DW, 0, 1, 0, 2)]));
+}
+
 // Test all supported LoadReg mnemonics.
 #[test]
-fn test_load() {
+fn test_load_reg() {
     assert_eq!(asm("ldxw r1, [r2+3]
                     ldxh r1, [r2+3]
                     ldxb r1, [r2+3]