Skip to content

Commit 526f113

Browse files
r41k0uclaude
andcommitted
Core: Give every symbol kind a common Symbol base class
LocalSymbol, BpfGlobalSymbol and MapSymbol each named the storage behind a name differently (var, var, sym) and shared no type. They now all derive from symbols.Symbol, which carries what every symbol has -- the storage pointer (alloca, GlobalVariable, or None for the context parameter) and its IR type -- and each subclass adds only what its kind needs: LocalSymbol its metadata and declared_global flag, BpfGlobalSymbol its ctypes name, MapSymbol its map type and params. MapSymbol.sym becomes var to match. local_symbol.py is folded into the new symbols.py. LocalSymbol keeps its three-field __iter__ for the call sites that tuple-unpack a symbol. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BSDVsZH5NtoASyxB8FCtGU
1 parent 2b77c40 commit 526f113

9 files changed

Lines changed: 71 additions & 52 deletions

File tree

pythonbpf/allocation_pass.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
import ctypes
44
from llvmlite import ir
5-
from .local_symbol import LocalSymbol
5+
from .symbols import LocalSymbol
66
from pythonbpf.helper import HelperHandlerRegistry
77
from pythonbpf.vmlinux_parser.dependency_node import Field
88
from .expr import VmlinuxHandlerRegistry

pythonbpf/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
if TYPE_CHECKING:
66
from pythonbpf.structs.struct_type import StructType
77
from pythonbpf.maps.maps_utils import MapSymbol
8-
from pythonbpf.globals_pass import BpfGlobalSymbol
8+
from pythonbpf.symbols import BpfGlobalSymbol
99

1010
logger = logging.getLogger(__name__)
1111

pythonbpf/globals_pass.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from llvmlite import ir
22
import ast
33

4-
from dataclasses import dataclass
54
from logging import Logger
65
import logging
76
from .type_deducer import ctypes_to_ir
7+
from .symbols import BpfGlobalSymbol
88
from .debuginfo import DebugInfoGenerator
99
from .expr import VmlinuxHandlerRegistry
1010
from .debuginfo import dwarf_constants as dc
@@ -26,20 +26,6 @@
2626
_C_NAME_BY_WIDTH = {8: "char", 16: "short", 32: "int", 64: "long long"}
2727

2828

29-
@dataclass
30-
class BpfGlobalSymbol:
31-
"""A mutable BPF global variable declared with @bpfglobal.
32-
33-
Lands in .bss (zero initializer) or .data (non-zero) and is read with a
34-
plain load / written with a plain store; libbpf exposes the sections to
35-
userspace as global-data maps.
36-
"""
37-
38-
var: ir.GlobalVariable
39-
ir_type: ir.Type
40-
ctype_name: str
41-
42-
4329
def populate_global_symbol_table(tree, compilation_context):
4430
"""
4531
compilation_context: CompilationContext

pythonbpf/helper/bpf_helper_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,6 @@ def invoke_helper(method_name, map_ptr=None):
11111111
if not map_sym_tab or map_name not in map_sym_tab:
11121112
raise ValueError(f"Map '{map_name}' not found in symbol table")
11131113

1114-
return invoke_helper(method_name, map_sym_tab[map_name].sym)
1114+
return invoke_helper(method_name, map_sym_tab[map_name].var)
11151115

11161116
return None

pythonbpf/local_symbol.py

Lines changed: 0 additions & 24 deletions
This file was deleted.

pythonbpf/maps/maps_pass.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ def create_bpf_map(compilation_context, map_name, map_params):
5050
map_global.align = 8
5151

5252
logger.info(f"Created BPF map: {map_name} with params {map_params}")
53-
return MapSymbol(type=map_params["type"], sym=map_global, params=map_params)
53+
return MapSymbol(
54+
var=map_global,
55+
ir_type=map_global.value_type,
56+
type=map_params["type"],
57+
params=map_params,
58+
)
5459

5560

5661
def _parse_map_params(rval, expected_args=None):
@@ -112,7 +117,7 @@ def process_ringbuf_map(map_name, rval, compilation_context):
112117
map_global = create_bpf_map(compilation_context, map_name, map_params)
113118
create_ringbuf_debug_info(
114119
compilation_context,
115-
map_global.sym,
120+
map_global.var,
116121
map_name,
117122
map_params,
118123
)
@@ -131,7 +136,7 @@ def process_hash_map(map_name, rval, compilation_context):
131136
# Generate debug info for BTF
132137
create_map_debug_info(
133138
compilation_context,
134-
map_global.sym,
139+
map_global.var,
135140
map_name,
136141
map_params,
137142
)
@@ -150,7 +155,7 @@ def process_perf_event_map(map_name, rval, compilation_context):
150155
# Generate debug info for BTF
151156
create_map_debug_info(
152157
compilation_context,
153-
map_global.sym,
158+
map_global.var,
154159
map_name,
155160
map_params,
156161
)

pythonbpf/maps/maps_utils.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
from collections.abc import Callable
22
from dataclasses import dataclass
3-
from llvmlite import ir
43
from typing import Any
54
from .map_types import BPFMapType
5+
from ..symbols import Symbol
66

77

88
@dataclass
9-
class MapSymbol:
10-
"""Class representing a symbol on the map"""
9+
class MapSymbol(Symbol):
10+
"""A BPF map: var is the map's GlobalVariable in the .maps section."""
1111

12-
type: BPFMapType
13-
sym: ir.GlobalVariable
12+
type: BPFMapType = BPFMapType.UNSPEC
1413
params: dict[str, Any] | None = None
1514

1615

pythonbpf/symbols.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""Symbols: what a name in a BPF program resolves to.
2+
3+
Every symbol table in the compiler maps a name to one of these. The base class
4+
carries what all of them share -- the storage behind the name and its IR type;
5+
subclasses add what each kind of name needs on top.
6+
"""
7+
8+
from dataclasses import dataclass
9+
from typing import Any
10+
11+
import llvmlite.ir as ir
12+
13+
14+
@dataclass
15+
class Symbol:
16+
"""The storage a name resolves to, and the type of what is stored there.
17+
18+
`var` is a pointer to that storage: an alloca for a local, a GlobalVariable
19+
for a BPF global or a map, or None for the context parameter (which arrives
20+
as func.args[0] rather than living in a slot).
21+
"""
22+
23+
var: ir.Value | None
24+
ir_type: ir.Type | None
25+
26+
27+
@dataclass
28+
class LocalSymbol(Symbol):
29+
"""One name visible in a BPF function's scope.
30+
31+
`declared_global` marks a name bound by a `global` statement: its var is
32+
the @bpfglobal's GlobalVariable rather than an alloca.
33+
"""
34+
35+
metadata: Any = None
36+
declared_global: bool = False
37+
38+
def __iter__(self):
39+
# Three fields on purpose: several call sites tuple-unpack a symbol.
40+
yield self.var
41+
yield self.ir_type
42+
yield self.metadata
43+
44+
45+
@dataclass
46+
class BpfGlobalSymbol(Symbol):
47+
"""A mutable BPF global variable declared with @bpfglobal.
48+
49+
Lands in .bss (zero initializer) or .data (non-zero); libbpf exposes the
50+
section to userspace as a global-data map.
51+
"""
52+
53+
ctype_name: str = ""

pythonbpf/vmlinux_parser/vmlinux_exports_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import ctypes
44
from llvmlite import ir
55

6-
from pythonbpf.local_symbol import LocalSymbol
6+
from pythonbpf.symbols import LocalSymbol
77
from pythonbpf.vmlinux_parser.assignment_info import AssignmentType
88

99
logger = logging.getLogger(__name__)

0 commit comments

Comments
 (0)