From e1f9ac6ba07aa7e6f5dd2b4bd146386db52c69cf Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Tue, 14 Oct 2025 02:35:49 +0530 Subject: [PATCH 1/2] add dependency tree functionality --- pythonbpf/vmlinux_parser/class_handler.py | 3 ++- pythonbpf/vmlinux_parser/dependency_node.py | 9 +++++++++ pythonbpf/vmlinux_parser/ir_generation.py | 3 +++ tests/c-form/ex7.bpf.c | 16 +--------------- tests/failing_tests/xdp_pass.py | 4 ++-- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/pythonbpf/vmlinux_parser/class_handler.py b/pythonbpf/vmlinux_parser/class_handler.py index 3cb3a97d..1ffe2b3f 100644 --- a/pythonbpf/vmlinux_parser/class_handler.py +++ b/pythonbpf/vmlinux_parser/class_handler.py @@ -112,7 +112,7 @@ def process_vmlinux_post_ast( type_length = elem_type._length_ if containing_type.__module__ == "vmlinux": - pass + new_dep_node.add_dependent(elem_type._type_.__name__ if hasattr(elem_type._type_, "__name__") else str(elem_type._type_)) elif containing_type.__module__ == ctypes.__name__: if isinstance(elem_type, type): if issubclass(elem_type, ctypes.Array): @@ -149,6 +149,7 @@ def process_vmlinux_post_ast( "Module not supported in recursive resolution" ) else: + new_dep_node.add_dependent(elem_type.__name__ if hasattr(elem_type, "__name__") else str(elem_type)) process_vmlinux_post_ast( elem_type, llvm_handler, handler, processing_stack ) diff --git a/pythonbpf/vmlinux_parser/dependency_node.py b/pythonbpf/vmlinux_parser/dependency_node.py index a17ffaf7..7f32323a 100644 --- a/pythonbpf/vmlinux_parser/dependency_node.py +++ b/pythonbpf/vmlinux_parser/dependency_node.py @@ -106,6 +106,7 @@ class DependencyNode: """ name: str + depends_on: Optional[list[str]] = None fields: Dict[str, Field] = field(default_factory=dict) _ready_cache: Optional[bool] = field(default=None, repr=False) @@ -121,6 +122,8 @@ def add_field( ready: bool = False, ) -> None: """Add a field to the node with an optional initial value and readiness state.""" + if self.depends_on is None: + self.depends_on = [] self.fields[name] = Field( name=name, type=field_type, @@ -235,3 +238,9 @@ def get_ready_fields(self) -> Dict[str, Field]: def get_not_ready_fields(self) -> Dict[str, Field]: """Get all fields that are marked as not ready.""" return {name: elem for name, elem in self.fields.items() if not elem.ready} + + def add_dependent(self, dep_type): + if dep_type in self.depends_on: + return + else: + self.depends_on.append(dep_type) diff --git a/pythonbpf/vmlinux_parser/ir_generation.py b/pythonbpf/vmlinux_parser/ir_generation.py index 62b13bc0..c66ba112 100644 --- a/pythonbpf/vmlinux_parser/ir_generation.py +++ b/pythonbpf/vmlinux_parser/ir_generation.py @@ -12,3 +12,6 @@ def __init__(self, module, handler: DependencyHandler): raise ImportError( "Semantic analysis of vmlinux imports failed. Cannot generate IR" ) + for struct in handler: + print(struct) + print() diff --git a/tests/c-form/ex7.bpf.c b/tests/c-form/ex7.bpf.c index a462444f..80a60d1a 100644 --- a/tests/c-form/ex7.bpf.c +++ b/tests/c-form/ex7.bpf.c @@ -1,23 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 -#include +#include "vmlinux.h" #include #include -struct trace_entry { - short unsigned int type; - unsigned char flags; - unsigned char preempt_count; - int pid; -}; - -struct trace_event_raw_sys_enter { - struct trace_entry ent; - long int id; - long unsigned int args[6]; - char __data[0]; -}; - struct event { __u32 pid; __u32 uid; diff --git a/tests/failing_tests/xdp_pass.py b/tests/failing_tests/xdp_pass.py index a7b45506..473375b1 100644 --- a/tests/failing_tests/xdp_pass.py +++ b/tests/failing_tests/xdp_pass.py @@ -2,8 +2,8 @@ from pythonbpf.maps import HashMap from pythonbpf.helper import XDP_PASS from vmlinux import struct_xdp_md -from vmlinux import struct_xdp_buff # noqa: F401 -from vmlinux import struct_ring_buffer_per_cpu # noqa: F401 +from vmlinux import struct_trace_event_raw_sys_enter # noqa: F401 +from vmlinux import struct_ring_buffer_per_cpu # noqa: F401 from ctypes import c_int64 From a03d3e5d4c5d37ef2d8312dde9c61bd4315521f7 Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Tue, 14 Oct 2025 02:36:04 +0530 Subject: [PATCH 2/2] format chore --- pythonbpf/vmlinux_parser/class_handler.py | 12 ++++++++++-- tests/failing_tests/xdp_pass.py | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pythonbpf/vmlinux_parser/class_handler.py b/pythonbpf/vmlinux_parser/class_handler.py index 1ffe2b3f..cf82e50d 100644 --- a/pythonbpf/vmlinux_parser/class_handler.py +++ b/pythonbpf/vmlinux_parser/class_handler.py @@ -112,7 +112,11 @@ def process_vmlinux_post_ast( type_length = elem_type._length_ if containing_type.__module__ == "vmlinux": - new_dep_node.add_dependent(elem_type._type_.__name__ if hasattr(elem_type._type_, "__name__") else str(elem_type._type_)) + new_dep_node.add_dependent( + elem_type._type_.__name__ + if hasattr(elem_type._type_, "__name__") + else str(elem_type._type_) + ) elif containing_type.__module__ == ctypes.__name__: if isinstance(elem_type, type): if issubclass(elem_type, ctypes.Array): @@ -149,7 +153,11 @@ def process_vmlinux_post_ast( "Module not supported in recursive resolution" ) else: - new_dep_node.add_dependent(elem_type.__name__ if hasattr(elem_type, "__name__") else str(elem_type)) + new_dep_node.add_dependent( + elem_type.__name__ + if hasattr(elem_type, "__name__") + else str(elem_type) + ) process_vmlinux_post_ast( elem_type, llvm_handler, handler, processing_stack ) diff --git a/tests/failing_tests/xdp_pass.py b/tests/failing_tests/xdp_pass.py index 473375b1..6d6be86a 100644 --- a/tests/failing_tests/xdp_pass.py +++ b/tests/failing_tests/xdp_pass.py @@ -2,8 +2,8 @@ from pythonbpf.maps import HashMap from pythonbpf.helper import XDP_PASS from vmlinux import struct_xdp_md -from vmlinux import struct_trace_event_raw_sys_enter # noqa: F401 -from vmlinux import struct_ring_buffer_per_cpu # noqa: F401 +from vmlinux import struct_trace_event_raw_sys_enter # noqa: F401 +from vmlinux import struct_ring_buffer_per_cpu # noqa: F401 from ctypes import c_int64