Skip to content

Commit e95ee71

Browse files
r41k0uclaude
andcommitted
Core: Resolve @bpfglobal reads in expressions and f-strings
Name resolution tried local_sym_tab, then vmlinux enums, then failed. Globals now resolve between the two, in _handle_name_expr, get_operand_value, and the printk f-string formatter, each emitting the plain 'load i64, ptr @counter' form the C reference produces. A global therefore works in conditions, binops, print arguments and as a helper scalar argument with no further changes -- those paths all funnel through eval_expr/get_operand_value. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L1PX8EuP9C3o3veWGA84RF
1 parent 3d8a211 commit e95ee71

2 files changed

Lines changed: 25 additions & 7 deletions

File tree

pythonbpf/expr/expr_pass.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,20 @@
2222
# ============================================================================
2323

2424

25-
def _handle_name_expr(expr: ast.Name, local_sym_tab: Dict, builder: ir.IRBuilder):
25+
def _handle_name_expr(
26+
expr: ast.Name, compilation_context, local_sym_tab: Dict, builder: ir.IRBuilder
27+
):
2628
"""Handle ast.Name expressions."""
2729
if expr.id in local_sym_tab:
2830
var = local_sym_tab[expr.id].var
2931
val = builder.load(var)
3032
return val, local_sym_tab[expr.id].ir_type
33+
elif expr.id in compilation_context.bpf_globals:
34+
# A @bpfglobal: read straight off the global symbol, exactly the
35+
# `load i64, ptr @counter` form clang emits (tests/c-form/global_vars).
36+
sym = compilation_context.bpf_globals[expr.id]
37+
val = builder.load(sym.var)
38+
return val, sym.ir_type
3139
else:
3240
# Check if it's a vmlinux enum/constant
3341
vmlinux_result = VmlinuxHandlerRegistry.handle_name(expr.id)
@@ -175,6 +183,9 @@ def get_operand_value(func, compilation_context, operand, builder, local_sym_tab
175183
else:
176184
val = deref_to_depth(func, builder, var, depth)
177185
return val
186+
elif operand.id in compilation_context.bpf_globals:
187+
# A @bpfglobal: plain load off the global symbol.
188+
return builder.load(compilation_context.bpf_globals[operand.id].var)
178189
else:
179190
# Check if it's a vmlinux enum/constant
180191
vmlinux_result = VmlinuxHandlerRegistry.handle_name(operand.id)
@@ -662,7 +673,7 @@ def eval_expr(
662673

663674
logger.info(f"Evaluating expression: {ast.dump(expr)}")
664675
if isinstance(expr, ast.Name):
665-
return _handle_name_expr(expr, local_sym_tab, builder)
676+
return _handle_name_expr(expr, compilation_context, local_sym_tab, builder)
666677
elif isinstance(expr, ast.Constant):
667678
return _handle_constant_expr(compilation_context, builder, expr)
668679
elif isinstance(expr, ast.Call):

pythonbpf/helper/printk_formatter.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def handle_fstring_print(
4141
fmt_parts,
4242
exprs,
4343
local_sym_tab,
44-
compilation_context.structs_sym_tab,
44+
compilation_context,
4545
)
4646
else:
4747
raise NotImplementedError(f"Unsupported f-string value type: {type(value)}")
@@ -80,31 +80,38 @@ def _process_constant_in_fstring(cst, fmt_parts, exprs):
8080
)
8181

8282

83-
def _process_fval(fval, fmt_parts, exprs, local_sym_tab, struct_sym_tab):
83+
def _process_fval(fval, fmt_parts, exprs, local_sym_tab, compilation_context):
8484
"""Process formatted values in f-string."""
8585
logger.debug(f"Processing formatted value: {ast.dump(fval)}")
8686

8787
if isinstance(fval.value, ast.Name):
88-
_process_name_in_fval(fval.value, fmt_parts, exprs, local_sym_tab)
88+
_process_name_in_fval(
89+
fval.value, fmt_parts, exprs, local_sym_tab, compilation_context
90+
)
8991
elif isinstance(fval.value, ast.Attribute):
9092
_process_attr_in_fval(
9193
fval.value,
9294
fmt_parts,
9395
exprs,
9496
local_sym_tab,
95-
struct_sym_tab,
97+
compilation_context.structs_sym_tab,
9698
)
9799
else:
98100
raise NotImplementedError(
99101
f"Unsupported formatted value in f-string: {type(fval.value)}"
100102
)
101103

102104

103-
def _process_name_in_fval(name_node, fmt_parts, exprs, local_sym_tab):
105+
def _process_name_in_fval(
106+
name_node, fmt_parts, exprs, local_sym_tab, compilation_context
107+
):
104108
"""Process name nodes in formatted values."""
105109
if local_sym_tab and name_node.id in local_sym_tab:
106110
_, var_type, tmp = local_sym_tab[name_node.id]
107111
_populate_fval(var_type, name_node, fmt_parts, exprs)
112+
elif name_node.id in compilation_context.bpf_globals:
113+
var_type = compilation_context.bpf_globals[name_node.id].ir_type
114+
_populate_fval(var_type, name_node, fmt_parts, exprs)
108115
else:
109116
# Try to resolve through vmlinux registry if not in local symbol table
110117
result = VmlinuxHandlerRegistry.handle_name(name_node.id)

0 commit comments

Comments
 (0)