diff --git a/ebpfcat/ebpf.py b/ebpfcat/ebpf.py index 15dea9d123104647d4b5d6a4687a73e70cfce468..b487b9bc21eecd168b0a3323dfcfb5999b6ad989 100644 --- a/ebpfcat/ebpf.py +++ b/ebpfcat/ebpf.py @@ -460,6 +460,9 @@ class Expression: def __neg__(self): return Negate(self.ebpf, self) + def __abs__(self): + return Absolute(self.ebpf, self) + def __bool__(self): raise AssembleError("Expression only has a value at execution time") @@ -615,6 +618,23 @@ class Negate(Expression): return self.arg.contains(no) +class Absolute(Expression): + def __init__(self, ebpf, arg): + self.ebpf = ebpf + self.arg = arg + + @contextmanager + def calculate(self, dst, long, signed, force=False): + with self.arg.calculate(dst, long, True, force) as \ + (dst, long, signed): + with self.ebpf.r[dst] < 0: + self.ebpf.r[dst] = -self.ebpf.r[dst] + yield dst, long, True + + def contains(self, no): + return self.arg.contains(no) + + class Sum(Binary): """represent the sum of one register and a constant value diff --git a/ebpfcat/ebpf_test.py b/ebpfcat/ebpf_test.py index 4646af4f3d55b5b54eb98c17a560dbfa3ab2881c..c8ee9f80637d519ee57b812e962a1241e8250f2b 100644 --- a/ebpfcat/ebpf_test.py +++ b/ebpfcat/ebpf_test.py @@ -583,6 +583,14 @@ class Tests(TestCase): Instruction(opcode=O.LONG+O.REG+O.MOV, dst=7, src=1, off=0, imm=0), Instruction(opcode=O.LONG+O.NEG, dst=7, src=0, off=0, imm=0)]) + def test_absolute(self): + e = EBPF() + e.r7 = abs(e.r1) + self.assertEqual(e.opcodes, [ + Instruction(opcode=O.LONG+O.REG+O.MOV, dst=7, src=1, off=0, imm=0), + Instruction(opcode=O.JGE, dst=7, src=0, off=1, imm=0), + Instruction(opcode=O.LONG+O.NEG, dst=7, src=0, off=0, imm=0)]) + def test_jump_data(self): e = EBPF() t1 = e.jumpIf(e.r1 > 0)