From 8e05a34bd4ffaa5e82a03e39a1d32af33af6aca3 Mon Sep 17 00:00:00 2001
From: Martin Teichmann <martin.teichmann@xfel.eu>
Date: Fri, 26 Feb 2021 08:08:21 +0000
Subject: [PATCH] add ktime to ebpf

---
 ebpfcat/ebpf.py      | 16 ++++++++++++++--
 ebpfcat/ebpf_test.py | 11 ++++++++++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/ebpfcat/ebpf.py b/ebpfcat/ebpf.py
index 8894106..4960a2e 100644
--- a/ebpfcat/ebpf.py
+++ b/ebpfcat/ebpf.py
@@ -638,8 +638,6 @@ class Memory(Expression):
 
     @contextmanager
     def calculate(self, dst, long, signed, force=False):
-        if not long and self.bits == Opcode.DW:
-            raise AssembleError("cannot compile")
         if isinstance(self.address, Sum):
             with self.ebpf.get_free_register(dst) as dst:
                 self.ebpf.append(Opcode.LD + self.bits, dst,
@@ -768,6 +766,20 @@ class PseudoFd(Expression):
             yield dst, long, signed
 
 
+class ktime(Expression):
+    def __init__(self, ebpf):
+        self.ebpf = ebpf
+
+    @contextmanager
+    def calculate(self, dst, long, signed, force):
+        with self.ebpf.get_free_register(dst) as dst:
+            with self.ebpf.save_registers([i for i in range(6) if i != dst]):
+                self.ebpf.call(FuncId.ktime_get_ns)
+                if dst != 0:
+                    self.ebpf.r[dst] = self.ebpf.r0
+                yield dst, True, False
+
+
 class RegisterDesc:
     def __init__(self, no, array):
         self.no = no
diff --git a/ebpfcat/ebpf_test.py b/ebpfcat/ebpf_test.py
index 1f37e26..cba4236 100644
--- a/ebpfcat/ebpf_test.py
+++ b/ebpfcat/ebpf_test.py
@@ -4,7 +4,7 @@ from . import ebpf
 from .arraymap import ArrayMap
 from .ebpf import (
     AssembleError, EBPF, FuncId, Opcode, OpcodeFlags, Opcode as O, LocalVar,
-    SubProgram)
+    SubProgram, ktime)
 from .hashmap import HashMap
 from .xdp import XDP
 from .bpf import ProgType, prog_test_run
@@ -539,6 +539,15 @@ class Tests(TestCase):
             Instruction(opcode=O.MOV+O.LONG+O.REG, dst=3, src=2, off=0, imm=0)
             ])
 
+    def test_ktime(self):
+        e = EBPF()
+        e.r3 = ktime(e)
+        self.assertEqual(e.opcodes, [
+            Instruction(opcode=O.REG+O.MOV+O.LONG, dst=6, src=1, off=0, imm=0),
+            Instruction(opcode=O.CALL, dst=0, src=0, off=0, imm=5),
+            Instruction(opcode=O.REG+O.MOV+O.LONG, dst=3, src=0, off=0, imm=0),
+            Instruction(opcode=O.REG+O.MOV+O.LONG, dst=1, src=6, off=0, imm=0)])
+
     def test_xdp(self):
         e = XDP(license="GPL")
         with e.packetSize > 100 as p:
-- 
GitLab