mirror of
https://github.com/varun-r-mallya/Python-BPF.git
synced 2026-04-22 21:51:26 +00:00
Compare commits
3 Commits
c04e32bd24
...
bdcfe47601
| Author | SHA1 | Date | |
|---|---|---|---|
| bdcfe47601 | |||
| 3396d84e26 | |||
| c22911daaf |
@ -157,17 +157,16 @@ def bpf_printk_emitter(
|
||||
if isinstance(call.args[0], ast.JoinedStr):
|
||||
args = handle_fstring_print(
|
||||
call.args[0],
|
||||
compilation_context.module,
|
||||
compilation_context,
|
||||
builder,
|
||||
func,
|
||||
local_sym_tab,
|
||||
compilation_context.structs_sym_tab,
|
||||
)
|
||||
elif isinstance(call.args[0], ast.Constant) and isinstance(call.args[0].value, str):
|
||||
# TODO: We are only supporting single arguments for now.
|
||||
# In case of multiple args, the first one will be taken.
|
||||
args = simple_string_print(
|
||||
call.args[0].value, compilation_context.module, builder, func
|
||||
call.args[0].value, compilation_context, builder, func
|
||||
)
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
@ -397,7 +396,7 @@ def bpf_perf_event_output_handler(
|
||||
ctx_ptr = func.args[0] # First argument to the function is ctx
|
||||
|
||||
data_ptr, size_val = get_data_ptr_and_size(
|
||||
data_arg, local_sym_tab, compilation_context.structs_sym_tab
|
||||
data_arg, local_sym_tab, compilation_context
|
||||
)
|
||||
|
||||
# BPF_F_CURRENT_CPU is -1 in 32 bit
|
||||
@ -446,7 +445,7 @@ def bpf_ringbuf_output_emitter(
|
||||
)
|
||||
data_arg = call.args[0]
|
||||
data_ptr, size_val = get_data_ptr_and_size(
|
||||
data_arg, local_sym_tab, compilation_context.structs_sym_tab
|
||||
data_arg, local_sym_tab, compilation_context
|
||||
)
|
||||
flags_val = ir.Constant(ir.IntType(64), 0)
|
||||
|
||||
|
||||
@ -10,40 +10,6 @@ from pythonbpf.expr import (
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# NOTE: ScratchPoolManager is now in context.py
|
||||
|
||||
|
||||
def get_ptr_from_arg(arg, compilation_context, builder, local_sym_tab):
|
||||
"""Helper to get a pointer value from an argument."""
|
||||
# This is a bit duplicative of logic in eval_expr but simplified for helpers
|
||||
# We might need to handle more cases here or defer to eval_expr
|
||||
|
||||
# Simple check for name
|
||||
if isinstance(arg, ast.Name):
|
||||
if arg.id in local_sym_tab:
|
||||
sym = local_sym_tab[arg.id]
|
||||
if isinstance(sym.ir_type, ir.PointerType):
|
||||
return builder.load(sym.var)
|
||||
# If it's an array/struct we might need GEP depending on how it was allocated
|
||||
# For now assume load returns the pointer/value
|
||||
return builder.load(sym.var)
|
||||
|
||||
# Use eval_expr for general case
|
||||
val = eval_expr(
|
||||
None,
|
||||
compilation_context.module,
|
||||
builder,
|
||||
arg,
|
||||
local_sym_tab,
|
||||
compilation_context.map_sym_tab,
|
||||
compilation_context.structs_sym_tab,
|
||||
)
|
||||
if val and isinstance(val[0].type, ir.PointerType):
|
||||
return val[0]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Argument Preparation
|
||||
# ============================================================================
|
||||
@ -85,10 +51,7 @@ def get_or_create_ptr_from_arg(
|
||||
sz = None
|
||||
if isinstance(arg, ast.Name):
|
||||
# Stack space is already allocated
|
||||
if arg.id in local_sym_tab:
|
||||
ptr = local_sym_tab[arg.id].var
|
||||
else:
|
||||
raise ValueError(f"Variable '{arg.id}' not found")
|
||||
ptr = get_var_ptr_from_name(arg.id, local_sym_tab)
|
||||
elif isinstance(arg, ast.Constant) and isinstance(arg.value, int):
|
||||
int_width = 64 # Default to i64
|
||||
if expected_type and isinstance(expected_type, ir.IntType):
|
||||
@ -345,6 +308,22 @@ def _is_char_array(ir_type):
|
||||
)
|
||||
|
||||
|
||||
def get_ptr_from_arg(arg, func, compilation_context, builder, local_sym_tab):
|
||||
"""Evaluate argument and return pointer value"""
|
||||
|
||||
result = eval_expr(func, compilation_context, builder, arg, local_sym_tab)
|
||||
|
||||
if not result:
|
||||
raise ValueError("Failed to evaluate argument")
|
||||
|
||||
val, val_type = result
|
||||
|
||||
if not isinstance(val_type, ir.PointerType):
|
||||
raise ValueError(f"Expected pointer type, got {val_type}")
|
||||
|
||||
return val, val_type
|
||||
|
||||
|
||||
def get_int_value_from_arg(arg, func, compilation_context, builder, local_sym_tab):
|
||||
"""Evaluate argument and return integer value"""
|
||||
|
||||
|
||||
@ -9,8 +9,9 @@ from pythonbpf.helper.helper_utils import get_char_array_ptr_and_size
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def simple_string_print(string_value, module, builder, func):
|
||||
def simple_string_print(string_value, compilation_context, builder, func):
|
||||
"""Prepare arguments for bpf_printk from a simple string value"""
|
||||
module = compilation_context.module
|
||||
fmt_str = string_value + "\n\0"
|
||||
fmt_ptr = _create_format_string_global(fmt_str, func, module, builder)
|
||||
|
||||
@ -20,11 +21,10 @@ def simple_string_print(string_value, module, builder, func):
|
||||
|
||||
def handle_fstring_print(
|
||||
joined_str,
|
||||
module,
|
||||
compilation_context,
|
||||
builder,
|
||||
func,
|
||||
local_sym_tab=None,
|
||||
struct_sym_tab=None,
|
||||
):
|
||||
"""Handle f-string formatting for bpf_printk emitter."""
|
||||
fmt_parts = []
|
||||
@ -41,13 +41,13 @@ def handle_fstring_print(
|
||||
fmt_parts,
|
||||
exprs,
|
||||
local_sym_tab,
|
||||
struct_sym_tab,
|
||||
compilation_context.struct_sym_tab,
|
||||
)
|
||||
else:
|
||||
raise NotImplementedError(f"Unsupported f-string value type: {type(value)}")
|
||||
|
||||
fmt_str = "".join(fmt_parts)
|
||||
args = simple_string_print(fmt_str, module, builder, func)
|
||||
args = simple_string_print(fmt_str, compilation_context, builder, func)
|
||||
|
||||
# NOTE: Process expressions (limited to 3 due to BPF constraints)
|
||||
if len(exprs) > 3:
|
||||
@ -57,10 +57,10 @@ def handle_fstring_print(
|
||||
arg_value = _prepare_expr_args(
|
||||
expr,
|
||||
func,
|
||||
module,
|
||||
compilation_context.module,
|
||||
builder,
|
||||
local_sym_tab,
|
||||
struct_sym_tab,
|
||||
compilation_context.struct_sym_tab,
|
||||
)
|
||||
args.append(arg_value)
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ def structs_proc(tree, compilation_context, chunks):
|
||||
for cls_node in chunks:
|
||||
if is_bpf_struct(cls_node):
|
||||
logger.info(f"Found BPF struct: {cls_node.name}")
|
||||
struct_info = process_bpf_struct(cls_node, compilation_context)
|
||||
struct_info = process_bpf_struct(cls_node)
|
||||
structs_sym_tab[cls_node.name] = struct_info
|
||||
|
||||
return structs_sym_tab
|
||||
@ -35,7 +35,7 @@ def is_bpf_struct(cls_node):
|
||||
)
|
||||
|
||||
|
||||
def process_bpf_struct(cls_node, compilation_context):
|
||||
def process_bpf_struct(cls_node):
|
||||
"""Process a single BPF struct definition"""
|
||||
|
||||
fields = parse_struct_fields(cls_node)
|
||||
|
||||
Reference in New Issue
Block a user