From 9b7aa6d8beef8134c70385e6bd92cc12cf61794c Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Sat, 18 Oct 2025 03:27:26 +0530 Subject: [PATCH] add dependency debug info list --- .../vmlinux_parser/ir_gen/debug_info_gen.py | 10 ++-- .../vmlinux_parser/ir_gen/ir_generation.py | 12 +++-- tests/passing_tests/vmlinux/xdp_pass.py | 46 +++++++++++++++++++ 3 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 tests/passing_tests/vmlinux/xdp_pass.py diff --git a/pythonbpf/vmlinux_parser/ir_gen/debug_info_gen.py b/pythonbpf/vmlinux_parser/ir_gen/debug_info_gen.py index 0b38cd6..07daea4 100644 --- a/pythonbpf/vmlinux_parser/ir_gen/debug_info_gen.py +++ b/pythonbpf/vmlinux_parser/ir_gen/debug_info_gen.py @@ -1,10 +1,14 @@ from pythonbpf.debuginfo import DebugInfoGenerator +from ..dependency_node import DependencyNode -def debug_info_generation(struct, llvm_module): +def debug_info_generation( + struct: DependencyNode, llvm_module, generated_debug_info: list +): generator = DebugInfoGenerator(llvm_module) - # this is sample debug info generation - # i64type = generator.get_uint64_type() + print("DEBUG1", generated_debug_info) + for field in struct.fields: + print("DEBUG", field) struct_type = generator.create_struct_type([], 64 * 4, is_distinct=True) diff --git a/pythonbpf/vmlinux_parser/ir_gen/ir_generation.py b/pythonbpf/vmlinux_parser/ir_gen/ir_generation.py index 1cf3794..5d1df92 100644 --- a/pythonbpf/vmlinux_parser/ir_gen/ir_generation.py +++ b/pythonbpf/vmlinux_parser/ir_gen/ir_generation.py @@ -14,6 +14,7 @@ class IRGenerator: self.llvm_module = llvm_module self.handler: DependencyHandler = handler self.generated: list[str] = [] + self.generated_debug_info: list = [] if not handler.is_ready: raise ImportError( "Semantic analysis of vmlinux imports failed. Cannot generate IR" @@ -67,18 +68,22 @@ class IRGenerator: ) # Actual processor logic here after dependencies are resolved - self.gen_ir(struct) + self.generated_debug_info.append( + (struct, self.gen_ir(struct, self.generated_debug_info)) + ) self.generated.append(struct.name) finally: # Remove from processing stack after we're done processing_stack.discard(struct.name) - def gen_ir(self, struct): + def gen_ir(self, struct, generated_debug_info): # TODO: we add the btf_ama attribute by monkey patching in the end of compilation, but once llvmlite # accepts our issue, we will resort to normal accessed attribute based attribute addition # currently we generate all possible field accesses for CO-RE and put into the assignment table - debug_info = debug_info_generation(struct, self.llvm_module) + debug_info = debug_info_generation( + struct, self.llvm_module, generated_debug_info + ) field_index = 0 for field_name, field in struct.fields.items(): # does not take arrays and similar types into consideration yet. @@ -126,6 +131,7 @@ class IRGenerator: ) globvar.linkage = "external" globvar.set_metadata("llvm.preserve.access.index", debug_info) + return debug_info def _struct_name_generator( self, diff --git a/tests/passing_tests/vmlinux/xdp_pass.py b/tests/passing_tests/vmlinux/xdp_pass.py new file mode 100644 index 0000000..1e73614 --- /dev/null +++ b/tests/passing_tests/vmlinux/xdp_pass.py @@ -0,0 +1,46 @@ +from pythonbpf import bpf, map, section, bpfglobal, compile_to_ir +from pythonbpf.maps import HashMap +from pythonbpf.helper import XDP_PASS +from vmlinux import TASK_COMM_LEN # noqa: F401 +from vmlinux import struct_xdp_md +from vmlinux import struct_trace_event_raw_sys_enter # noqa: F401 +from ctypes import c_int64 + +# Instructions to how to run this program +# 1. Install PythonBPF: pip install pythonbpf +# 2. Run the program: python examples/xdp_pass.py +# 3. Run the program with sudo: sudo tools/check.sh run examples/xdp_pass.o +# 4. Attach object file to any network device with something like ./check.sh xdp examples/xdp_pass.o tailscale0 +# 5. send traffic through the device and observe effects + + +@bpf +@map +def count() -> HashMap: + return HashMap(key=c_int64, value=c_int64, max_entries=1) + + +@bpf +@section("xdp") +def hello_world(ctx: struct_xdp_md) -> c_int64: + key = 0 + one = 1 + prev = count().lookup(key) + if prev: + prevval = prev + 1 + print(f"count: {prevval}") + count().update(key, prevval) + return XDP_PASS + else: + count().update(key, one) + + return XDP_PASS + + +@bpf +@bpfglobal +def LICENSE() -> str: + return "GPL" + + +compile_to_ir("xdp_pass.py", "xdp_pass.ll")