mirror of
https://github.com/varun-r-mallya/Python-BPF.git
synced 2026-02-12 16:10:59 +00:00
Compare commits
3 Commits
f7dee329cb
...
c8801f4c3e
| Author | SHA1 | Date | |
|---|---|---|---|
| c8801f4c3e | |||
| 49740598ea | |||
| 73bbf00e7c |
@ -195,24 +195,9 @@ def process_vmlinux_post_ast(
|
|||||||
if hasattr(base_type, "__name__")
|
if hasattr(base_type, "__name__")
|
||||||
else str(base_type)
|
else str(base_type)
|
||||||
)
|
)
|
||||||
|
# ONLY add vmlinux types as dependencies
|
||||||
new_dep_node.add_dependent(base_type_name)
|
new_dep_node.add_dependent(base_type_name)
|
||||||
elif base_type_module == ctypes.__name__ or base_type_module is None:
|
|
||||||
# Handle ctypes or types with no module (like some internal ctypes types)
|
|
||||||
if isinstance(elem_type, type):
|
|
||||||
if issubclass(elem_type, ctypes.Array):
|
|
||||||
ctype_complex_type = ctypes.Array
|
|
||||||
elif issubclass(elem_type, ctypes._Pointer):
|
|
||||||
ctype_complex_type = ctypes._Pointer
|
|
||||||
else:
|
|
||||||
raise ImportError(
|
|
||||||
"Non Array and Pointer type ctype imports not supported in current version"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
raise TypeError("Unsupported ctypes subclass")
|
|
||||||
else:
|
|
||||||
raise ImportError(
|
|
||||||
f"Unsupported module of {base_type}: {base_type_module}"
|
|
||||||
)
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"{containing_type} containing type of parent {elem_name} with {elem_type} and ctype {ctype_complex_type} and length {type_length}"
|
f"{containing_type} containing type of parent {elem_name} with {elem_type} and ctype {ctype_complex_type} and length {type_length}"
|
||||||
)
|
)
|
||||||
@ -226,10 +211,14 @@ def process_vmlinux_post_ast(
|
|||||||
new_dep_node.set_field_type(elem_name, elem_type)
|
new_dep_node.set_field_type(elem_name, elem_type)
|
||||||
|
|
||||||
# Check the containing_type module to decide whether to recurse
|
# Check the containing_type module to decide whether to recurse
|
||||||
containing_type_module = getattr(containing_type, "__module__", None)
|
containing_type_module = getattr(
|
||||||
|
containing_type, "__module__", None
|
||||||
|
)
|
||||||
if containing_type_module == "vmlinux":
|
if containing_type_module == "vmlinux":
|
||||||
# Also unwrap containing_type to get base type name
|
# Also unwrap containing_type to get base type name
|
||||||
base_containing_type = unwrap_pointer_type(containing_type)
|
base_containing_type = unwrap_pointer_type(
|
||||||
|
containing_type
|
||||||
|
)
|
||||||
containing_type_name = (
|
containing_type_name = (
|
||||||
base_containing_type.__name__
|
base_containing_type.__name__
|
||||||
if hasattr(base_containing_type, "__name__")
|
if hasattr(base_containing_type, "__name__")
|
||||||
@ -259,13 +248,53 @@ def process_vmlinux_post_ast(
|
|||||||
processing_stack,
|
processing_stack,
|
||||||
)
|
)
|
||||||
new_dep_node.set_field_ready(elem_name, True)
|
new_dep_node.set_field_ready(elem_name, True)
|
||||||
elif containing_type_module == ctypes.__name__ or containing_type_module is None:
|
elif (
|
||||||
logger.debug(f"Processing ctype internal{containing_type}")
|
containing_type_module == ctypes.__name__
|
||||||
|
or containing_type_module is None
|
||||||
|
):
|
||||||
|
logger.debug(
|
||||||
|
f"Processing ctype internal{containing_type}"
|
||||||
|
)
|
||||||
new_dep_node.set_field_ready(elem_name, True)
|
new_dep_node.set_field_ready(elem_name, True)
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f"Module not supported in recursive resolution: {containing_type_module}"
|
f"Module not supported in recursive resolution: {containing_type_module}"
|
||||||
)
|
)
|
||||||
|
elif (
|
||||||
|
base_type_module == ctypes.__name__
|
||||||
|
or base_type_module is None
|
||||||
|
):
|
||||||
|
# Handle ctypes or types with no module (like some internal ctypes types)
|
||||||
|
# DO NOT add ctypes as dependencies - just set field metadata and mark ready
|
||||||
|
logger.debug(
|
||||||
|
f"Base type {base_type} is ctypes - NOT adding as dependency, just processing field"
|
||||||
|
)
|
||||||
|
if isinstance(elem_type, type):
|
||||||
|
if issubclass(elem_type, ctypes.Array):
|
||||||
|
ctype_complex_type = ctypes.Array
|
||||||
|
elif issubclass(elem_type, ctypes._Pointer):
|
||||||
|
ctype_complex_type = ctypes._Pointer
|
||||||
|
else:
|
||||||
|
raise ImportError(
|
||||||
|
"Non Array and Pointer type ctype imports not supported in current version"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise TypeError("Unsupported ctypes subclass")
|
||||||
|
|
||||||
|
# Set field metadata but DO NOT add dependency or recurse
|
||||||
|
new_dep_node.set_field_containing_type(
|
||||||
|
elem_name, containing_type
|
||||||
|
)
|
||||||
|
new_dep_node.set_field_type_size(elem_name, type_length)
|
||||||
|
new_dep_node.set_field_ctype_complex_type(
|
||||||
|
elem_name, ctype_complex_type
|
||||||
|
)
|
||||||
|
new_dep_node.set_field_type(elem_name, elem_type)
|
||||||
|
new_dep_node.set_field_ready(elem_name, True)
|
||||||
|
else:
|
||||||
|
raise ImportError(
|
||||||
|
f"Unsupported module of {base_type}: {base_type_module}"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
new_dep_node.add_dependent(
|
new_dep_node.add_dependent(
|
||||||
elem_type.__name__
|
elem_type.__name__
|
||||||
|
|||||||
@ -14,6 +14,7 @@ class IRGenerator:
|
|||||||
# This field keeps track of the non_struct names to avoid duplicate name errors.
|
# This field keeps track of the non_struct names to avoid duplicate name errors.
|
||||||
type_number = 0
|
type_number = 0
|
||||||
unprocessed_store = []
|
unprocessed_store = []
|
||||||
|
|
||||||
# get the assignments dict and add this stuff to it.
|
# get the assignments dict and add this stuff to it.
|
||||||
def __init__(self, llvm_module, handler: DependencyHandler, assignments):
|
def __init__(self, llvm_module, handler: DependencyHandler, assignments):
|
||||||
self.llvm_module = llvm_module
|
self.llvm_module = llvm_module
|
||||||
@ -193,7 +194,11 @@ class IRGenerator:
|
|||||||
base_containing_type = next_type
|
base_containing_type = next_type
|
||||||
|
|
||||||
# Get the base struct name
|
# Get the base struct name
|
||||||
base_struct_name = base_containing_type.__name__ if hasattr(base_containing_type, "__name__") else str(base_containing_type)
|
base_struct_name = (
|
||||||
|
base_containing_type.__name__
|
||||||
|
if hasattr(base_containing_type, "__name__")
|
||||||
|
else str(base_containing_type)
|
||||||
|
)
|
||||||
|
|
||||||
# Look up the size using the base struct name
|
# Look up the size using the base struct name
|
||||||
containing_type_size = self.handler[base_struct_name].current_offset
|
containing_type_size = self.handler[base_struct_name].current_offset
|
||||||
@ -212,14 +217,23 @@ class IRGenerator:
|
|||||||
else:
|
else:
|
||||||
for i in range(0, array_size):
|
for i in range(0, array_size):
|
||||||
field_co_re_name, returned = self._struct_name_generator(
|
field_co_re_name, returned = self._struct_name_generator(
|
||||||
struct, field, field_index, True, i, containing_type_size
|
struct,
|
||||||
|
field,
|
||||||
|
field_index,
|
||||||
|
True,
|
||||||
|
i,
|
||||||
|
containing_type_size,
|
||||||
)
|
)
|
||||||
globvar = ir.GlobalVariable(
|
globvar = ir.GlobalVariable(
|
||||||
self.llvm_module, ir.IntType(64), name=field_co_re_name
|
self.llvm_module, ir.IntType(64), name=field_co_re_name
|
||||||
)
|
)
|
||||||
globvar.linkage = "external"
|
globvar.linkage = "external"
|
||||||
globvar.set_metadata("llvm.preserve.access.index", debug_info)
|
globvar.set_metadata(
|
||||||
self.generated_field_names[struct.name][field_name] = globvar
|
"llvm.preserve.access.index", debug_info
|
||||||
|
)
|
||||||
|
self.generated_field_names[struct.name][field_name] = (
|
||||||
|
globvar
|
||||||
|
)
|
||||||
field_index += 1
|
field_index += 1
|
||||||
else:
|
else:
|
||||||
field_co_re_name, returned = self._struct_name_generator(
|
field_co_re_name, returned = self._struct_name_generator(
|
||||||
|
|||||||
22
tests/failing_tests/vmlinux/assignment_handling.py
Normal file
22
tests/failing_tests/vmlinux/assignment_handling.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from vmlinux import XDP_PASS
|
||||||
|
from pythonbpf import bpf, section, bpfglobal, compile_to_ir
|
||||||
|
import logging
|
||||||
|
from ctypes import c_int64, c_void_p
|
||||||
|
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@section("kprobe/blk_mq_start_request")
|
||||||
|
def example(ctx: c_void_p) -> c_int64:
|
||||||
|
d = XDP_PASS # This gives an error, but
|
||||||
|
e = XDP_PASS + 0 # this does not
|
||||||
|
print(f"test1 {e} test2 {d}")
|
||||||
|
return c_int64(0)
|
||||||
|
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@bpfglobal
|
||||||
|
def LICENSE() -> str:
|
||||||
|
return "GPL"
|
||||||
|
|
||||||
|
|
||||||
|
compile_to_ir("assignment_handling.py", "assignment_handling.ll", loglevel=logging.INFO)
|
||||||
@ -1,15 +1,16 @@
|
|||||||
from vmlinux import struct_request, struct_pt_regs, XDP_PASS
|
from vmlinux import struct_request, struct_pt_regs
|
||||||
from pythonbpf import bpf, section, bpfglobal, compile_to_ir
|
from pythonbpf import bpf, section, bpfglobal, compile_to_ir
|
||||||
import logging
|
import logging
|
||||||
|
from ctypes import c_int64
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
@section("kprobe/blk_mq_start_request")
|
@section("kprobe/blk_mq_start_request")
|
||||||
def example(ctx: struct_pt_regs):
|
def example(ctx: struct_pt_regs) -> c_int64:
|
||||||
req = struct_request(ctx.di)
|
req = struct_request(ctx.di)
|
||||||
c = req.__data_len
|
c = req.__data_len
|
||||||
d = XDP_PASS
|
print(f"data length {c}")
|
||||||
print(f"data length {c} and test {d}")
|
return c_int64(0)
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
from vmlinux import struct_kobj_type
|
from vmlinux import struct_pt_regs, struct_request
|
||||||
from pythonbpf import bpf, section, bpfglobal, compile_to_ir
|
from pythonbpf import bpf, section, bpfglobal, compile_to_ir
|
||||||
import logging
|
import logging
|
||||||
from ctypes import c_void_p
|
from ctypes import c_int64
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
@section("kprobe/blk_mq_start_request")
|
@section("kprobe/blk_mq_start_request")
|
||||||
def example(ctx: c_void_p):
|
def example(ctx: struct_pt_regs) -> c_int64:
|
||||||
print(f"data lengt")
|
req = ctx.di
|
||||||
|
print(f"data length {req}")
|
||||||
|
return c_int64(0)
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
@ -16,4 +18,4 @@ def LICENSE() -> str:
|
|||||||
return "GPL"
|
return "GPL"
|
||||||
|
|
||||||
|
|
||||||
compile_to_ir("requests.py", "requests.ll", loglevel=logging.INFO)
|
compile_to_ir("requests2.py", "requests2.ll", loglevel=logging.INFO)
|
||||||
|
|||||||
Reference in New Issue
Block a user