3 Commits

Author SHA1 Message Date
902a52a07d remove debug print statements 2025-11-20 14:39:13 +05:30
306570953b format chore 2025-11-20 14:18:45 +05:30
740eed45e1 add placeholder debug info to shut llvmlite up about NoneType 2025-11-20 14:17:57 +05:30
6 changed files with 58 additions and 47 deletions

View File

@ -44,9 +44,9 @@ def unwrap_pointer_type(type_obj: Any) -> Any:
def process_vmlinux_class(
node,
llvm_module,
handler: DependencyHandler,
node,
llvm_module,
handler: DependencyHandler,
):
symbols_in_module, imported_module = get_module_symbols("vmlinux")
if node.name in symbols_in_module:
@ -57,10 +57,10 @@ def process_vmlinux_class(
def process_vmlinux_post_ast(
elem_type_class,
llvm_handler,
handler: DependencyHandler,
processing_stack=None,
elem_type_class,
llvm_handler,
handler: DependencyHandler,
processing_stack=None,
):
# Initialize processing stack on first call
if processing_stack is None:
@ -140,7 +140,7 @@ def process_vmlinux_post_ast(
# Process pointer to ctype
if isinstance(elem_type, type) and issubclass(
elem_type, ctypes._Pointer
elem_type, ctypes._Pointer
):
# Get the pointed-to type
pointed_type = elem_type._type_
@ -153,7 +153,7 @@ def process_vmlinux_post_ast(
# Process function pointers (CFUNCTYPE)
elif hasattr(elem_type, "_restype_") and hasattr(
elem_type, "_argtypes_"
elem_type, "_argtypes_"
):
# This is a CFUNCTYPE or similar
logger.info(

View File

@ -66,7 +66,6 @@ def detect_import_statement(
)
logger.info(f"Total vmlinux imports detected: {len(vmlinux_imports)}")
# print(f"\n**************\n{vmlinux_imports}\n**************\n")
return vmlinux_imports

View File

@ -21,7 +21,7 @@ def debug_info_generation(
generated_debug_info: List of tuples (struct, debug_info) to track generated debug info
Returns:
The generated global variable debug info
The generated global variable debug info, or None for unsupported types
"""
# Set up debug info generator
generator = DebugInfoGenerator(llvm_module)
@ -31,29 +31,44 @@ def debug_info_generation(
if existing_struct.name == struct.name:
return debug_info
# Check if this is a union (not supported yet)
if not struct.name.startswith("struct_"):
logger.warning(f"Skipping debug info generation for union: {struct.name}")
# Create a minimal forward declaration for unions
union_type = generator.create_struct_type(
[], struct.__sizeof__() * 8, is_distinct=True
)
return union_type
# Process all fields and create members for the struct
members = []
for field_name, field in struct.fields.items():
# Get appropriate debug type for this field
field_type = _get_field_debug_type(
field_name, field, generator, struct, generated_debug_info
)
# Create struct member with proper offset
member = generator.create_struct_member_vmlinux(
field_name, field_type, field.offset * 8
)
members.append(member)
try:
# Get appropriate debug type for this field
field_type = _get_field_debug_type(
field_name, field, generator, struct, generated_debug_info
)
# Ensure field_type is a tuple
if not isinstance(field_type, tuple) or len(field_type) != 2:
logger.error(f"Invalid field_type for {field_name}: {field_type}")
continue
# Create struct member with proper offset
member = generator.create_struct_member_vmlinux(
field_name, field_type, field.offset * 8
)
members.append(member)
except Exception as e:
logger.error(f"Failed to process field {field_name} in {struct.name}: {e}")
continue
struct_name = struct.name.removeprefix("struct_")
# Create struct type with all members
struct_type = generator.create_struct_type_with_name(
struct_name, members, struct.__sizeof__() * 8, is_distinct=True
)
if struct.name.startswith("struct_"):
struct_name = struct.name.removeprefix("struct_")
# Create struct type with all members
struct_type = generator.create_struct_type_with_name(
struct_name, members, struct.__sizeof__() * 8, is_distinct=True
)
else:
logger.warning("Blindly handling Unions present in vmlinux dependencies")
struct_type = None
# raise ValueError("Unions are not supported in the current version")
return struct_type
@ -63,7 +78,7 @@ def _get_field_debug_type(
generator: DebugInfoGenerator,
parent_struct: DependencyNode,
generated_debug_info: List[Tuple[DependencyNode, Any]],
) -> tuple[Any, int] | None:
) -> tuple[Any, int]:
"""
Determine the appropriate debug type for a field based on its Python/ctypes type.
@ -75,14 +90,16 @@ def _get_field_debug_type(
generated_debug_info: List of already generated debug info
Returns:
The debug info type for this field
A tuple of (debug_type, size_in_bits)
"""
# Handle complex types (arrays, pointers)
# Handle complex types (arrays, pointers, function pointers)
if field.ctype_complex_type is not None:
# TODO: Check if this is a CFUNCTYPE (function pointer), but sadly it just checks callable for now
# Handle function pointer types (CFUNCTYPE)
if callable(field.ctype_complex_type):
# Handle function pointer types, create a void pointer as a placeholder
return generator.create_pointer_type(None), 64
# Function pointers are represented as void pointers
logger.info(f"Field {field_name} is a function pointer, using void pointer")
void_ptr = generator.create_pointer_type(None, 64)
return void_ptr, 64
elif issubclass(field.ctype_complex_type, ctypes.Array):
# Handle array types
element_type, base_type_size = _get_basic_debug_type(
@ -105,11 +122,13 @@ def _get_field_debug_type(
for existing_struct, debug_info in generated_debug_info:
if existing_struct.name == struct_name:
# Use existing debug info
return debug_info, existing_struct.__sizeof__()
return debug_info, existing_struct.__sizeof__() * 8
# If not found, create a forward declaration
# This will be completed when the actual struct is processed
logger.warning("Forward declaration in struct created")
logger.warning(
f"Forward declaration created for {struct_name} in {parent_struct.name}"
)
forward_type = generator.create_struct_type([], 0, is_distinct=True)
return forward_type, 0

View File

@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
class IRGenerator:
# This field keeps track of the non_struct names to avoid duplicate name errors.
type_number = 0
unprocessed_store = []
unprocessed_store: list[str] = []
# get the assignments dict and add this stuff to it.
def __init__(self, llvm_module, handler: DependencyHandler, assignments):
@ -72,7 +72,6 @@ class IRGenerator:
dep_node_from_dependency, processing_stack
)
else:
print(struct)
raise RuntimeError(
f"Warning: Dependency {dependency} not found in handler"
)
@ -87,7 +86,6 @@ class IRGenerator:
members_dict = {}
for field_name, field in struct.fields.items():
# Get the generated field name from our dictionary, or use field_name if not found
print(f"DEBUG: {struct.name}, {field_name}")
if (
struct.name in self.generated_field_names
and field_name in self.generated_field_names[struct.name]
@ -140,7 +138,6 @@ class IRGenerator:
field_co_re_name, returned = self._struct_name_generator(
struct, field, field_index
)
print(field_co_re_name)
field_index += 1
globvar = ir.GlobalVariable(
self.llvm_module, ir.IntType(64), name=field_co_re_name
@ -182,7 +179,6 @@ class IRGenerator:
array_size = field.type_size
containing_type = field.containing_type
if containing_type.__module__ == "vmlinux":
print(struct)
# Unwrap all pointer layers to get the base struct type
base_containing_type = containing_type
while hasattr(base_containing_type, "_type_"):
@ -202,7 +198,6 @@ class IRGenerator:
# Look up the size using the base struct name
containing_type_size = self.handler[base_struct_name].current_offset
print(f"GAY: {array_size}, {struct.name}, {field_name}")
if array_size == 0:
field_co_re_name, returned = self._struct_name_generator(
struct, field, field_index, True, 0, containing_type_size

View File

@ -98,11 +98,9 @@ class VmlinuxHandler:
python_type.__name__, field_name
)
builder.function.args[0].type = ir.PointerType(ir.IntType(8))
print(builder.function.args[0])
field_ptr = self.load_ctx_field(
builder, builder.function.args[0], globvar_ir
)
print(field_ptr)
# Return pointer to field and field type
return field_ptr, field_data
else:

View File

@ -1,4 +1,4 @@
from vmlinux import struct_pt_regs, struct_request
from vmlinux import struct_pt_regs
from pythonbpf import bpf, section, bpfglobal, compile_to_ir
import logging
from ctypes import c_int64