11import ast
22from llvmlite import ir
3- from .type_deducer import ctypes_to_ir
4- from . import dwarf_constants as dc
3+ from pythonbpf import dwarf_constants as dc
4+ from enum import Enum
5+ from .maps_utils import MapProcessorRegistry
6+ import logging
57
6- map_sym_tab = {}
8+ logger = logging . getLogger ( __name__ )
79
810
911def maps_proc (tree , module , chunks ):
12+ """ Process all functions decorated with @map to find BPF maps """
13+ map_sym_tab = {}
1014 for func_node in chunks :
11- # Check if this function is a map
12- is_map = False
13- for decorator in func_node .decorator_list :
14- if isinstance (decorator , ast .Name ) and decorator .id == "map" :
15- is_map = True
16- break
17- if is_map :
15+ if is_map (func_node ):
1816 print (f"Found BPF map: { func_node .name } " )
19- process_bpf_map (func_node , module )
20- continue
17+ map_sym_tab [func_node .name ] = process_bpf_map (func_node , module )
2118 return map_sym_tab
2219
2320
24- BPF_MAP_MAPPINGS = {
25- "HASH" : 1 , # BPF_MAP_TYPE_HASH
26- "PERF_EVENT_ARRAY" : 4 , # BPF_MAP_TYPE_PERF_EVENT_ARRAY
27- }
21+ def is_map (func_node ):
22+ return any (
23+ isinstance (decorator , ast .Name ) and decorator .id == "map"
24+ for decorator in func_node .decorator_list
25+ )
2826
2927
30- def create_bpf_map (module , map_name , map_params ):
31- """Create a BPF map in the module with the given parameters and debug info"""
28+ class BPFMapType (Enum ):
29+ HASH = 1
30+ PERF_EVENT_ARRAY = 4
3231
33- map_type_str = map_params .get ("type" , "HASH" )
34- map_type = BPF_MAP_MAPPINGS .get (map_type_str )
32+
33+ def create_bpf_map (module , map_name , map_params ):
34+ """Create a BPF map in the module with given parameters and debug info"""
3535
3636 # Create the anonymous struct type for BPF map
3737 map_struct_type = ir .LiteralStructType (
@@ -42,15 +42,14 @@ def create_bpf_map(module, map_name, map_params):
4242 map_global .linkage = 'dso_local'
4343 map_global .global_constant = False
4444 map_global .initializer = ir .Constant (
45- map_struct_type , None ) # type: ignore
45+ map_struct_type , None )
4646 map_global .section = ".maps"
47- map_global .align = 8 # type: ignore
47+ map_global .align = 8
4848
4949 # Generate debug info for BTF
5050 create_map_debug_info (module , map_global , map_name , map_params )
5151
52- print (f"Created BPF map: { map_name } " )
53- map_sym_tab [map_name ] = map_global
52+ logger .info (f"Created BPF map: { map_name } with params { map_params } " )
5453 return map_global
5554
5655
@@ -75,7 +74,7 @@ def create_map_debug_info(module, map_global, map_name, map_params):
7574
7675 # Create array type for map type field (array of 1 unsigned int)
7776 array_subrange = module .add_debug_info (
78- "DISubrange" , {"count" : BPF_MAP_MAPPINGS [ map_params .get ("type" , " HASH" )] })
77+ "DISubrange" , {"count" : map_params .get ("type" , BPFMapType . HASH ). value })
7978 array_type = module .add_debug_info ("DICompositeType" , {
8079 "tag" : dc .DW_TAG_array_type ,
8180 "baseType" : uint_type ,
@@ -183,9 +182,11 @@ def create_map_debug_info(module, map_global, map_name, map_params):
183182 return global_var_expr
184183
185184
185+ @MapProcessorRegistry .register ("HashMap" )
186186def process_hash_map (map_name , rval , module ):
187- print (f"Creating HashMap map: { map_name } " )
188- map_params : dict [str , object ] = {"type" : "HASH" }
187+ """Process a BPF_HASH map declaration"""
188+ logger .info (f"Processing HashMap: { map_name } " )
189+ map_params = {"type" : BPFMapType .HASH }
189190
190191 # Assuming order: key_type, value_type, max_entries
191192 if len (rval .args ) >= 1 and isinstance (rval .args [0 ], ast .Name ):
@@ -202,18 +203,21 @@ def process_hash_map(map_name, rval, module):
202203 map_params ["key" ] = keyword .value .id
203204 elif keyword .arg == "value" and isinstance (keyword .value , ast .Name ):
204205 map_params ["value" ] = keyword .value .id
205- elif keyword .arg == "max_entries" and isinstance (keyword .value , ast .Constant ):
206+ elif (keyword .arg == "max_entries" and
207+ isinstance (keyword .value , ast .Constant )):
206208 const_val = keyword .value .value
207209 if isinstance (const_val , (int , str )):
208210 map_params ["max_entries" ] = const_val
209211
210- print (f"Map parameters: { map_params } " )
212+ logger . info (f"Map parameters: { map_params } " )
211213 return create_bpf_map (module , map_name , map_params )
212214
213215
216+ @MapProcessorRegistry .register ("PerfEventArray" )
214217def process_perf_event_map (map_name , rval , module ):
215- print (f"Creating PerfEventArray map: { map_name } " )
216- map_params = {"type" : "PERF_EVENT_ARRAY" }
218+ """Process a BPF_PERF_EVENT_ARRAY map declaration"""
219+ logger .info (f"Processing PerfEventArray: { map_name } " )
220+ map_params = {"type" : BPFMapType .PERF_EVENT_ARRAY }
217221
218222 if len (rval .args ) >= 1 and isinstance (rval .args [0 ], ast .Name ):
219223 map_params ["key_size" ] = rval .args [0 ].id
@@ -223,21 +227,18 @@ def process_perf_event_map(map_name, rval, module):
223227 for keyword in rval .keywords :
224228 if keyword .arg == "key_size" and isinstance (keyword .value , ast .Name ):
225229 map_params ["key_size" ] = keyword .value .id
226- elif keyword .arg == "value_size" and isinstance (keyword .value , ast .Name ):
230+ elif (keyword .arg == "value_size" and
231+ isinstance (keyword .value , ast .Name )):
227232 map_params ["value_size" ] = keyword .value .id
228233
229- print (f"Map parameters: { map_params } " )
234+ logger . info (f"Map parameters: { map_params } " )
230235 return create_bpf_map (module , map_name , map_params )
231236
232237
233238def process_bpf_map (func_node , module ):
234239 """Process a BPF map (a function decorated with @map)"""
235240 map_name = func_node .name
236- print (f"Processing BPF map: { map_name } " )
237-
238- BPF_MAP_TYPES = {"HashMap" : process_hash_map , # BPF_MAP_TYPE_HASH
239- "PerfEventArray" : process_perf_event_map , # BPF_MAP_TYPE_PERF_EVENT_ARRAY
240- }
241+ logger .info (f"Processing BPF map: { map_name } " )
241242
242243 # For now, assume single return statement
243244 return_stmt = None
@@ -250,13 +251,13 @@ def process_bpf_map(func_node, module):
250251
251252 rval = return_stmt .value
252253
253- # Handle only HashMap maps
254254 if isinstance (rval , ast .Call ) and isinstance (rval .func , ast .Name ):
255- if rval .func .id in BPF_MAP_TYPES :
256- handler = BPF_MAP_TYPES [ rval . func . id ]
257- handler (map_name , rval , module )
255+ handler = MapProcessorRegistry . get_processor ( rval .func .id )
256+ if handler :
257+ return handler (map_name , rval , module )
258258 else :
259- print (f"Unknown map type { rval .func .id } , defaulting to HashMap" )
260- process_hash_map (map_name , rval , module )
259+ logger .warning (f"Unknown map type "
260+ f"{ rval .func .id } , defaulting to HashMap" )
261+ return process_hash_map (map_name , rval , module )
261262 else :
262263 raise ValueError ("Function under @map must return a map" )
0 commit comments