@@ -19,7 +19,6 @@ def bpf_map_lookup_elem_emitter(call, map_ptr, module, builder, local_sym_tab=No
1919 """
2020 Emit LLVM IR for bpf_map_lookup_elem helper function call.
2121 """
22-
2322 if call .args and len (call .args ) != 1 :
2423 raise ValueError ("Map lookup expects exactly one argument, got "
2524 f"{ len (call .args )} " )
@@ -94,11 +93,105 @@ def bpf_printk_emitter(call, module, builder, func):
9493 builder .call (fn_ptr , [fmt_ptr , ir .Constant (
9594 ir .IntType (32 ), len (fmt_str ))], tail = True )
9695
96+ def bpf_map_update_elem_emitter (call , map_ptr , module , builder , local_sym_tab = None ):
97+ """
98+ Emit LLVM IR for bpf_map_update_elem helper function call.
99+ Expected call signature: map.update(key, value, flags=0)
100+ """
101+ if not call .args or len (call .args ) < 2 or len (call .args ) > 3 :
102+ raise ValueError ("Map update expects 2 or 3 arguments (key, value, flags), got "
103+ f"{ len (call .args )} " )
104+
105+ key_arg = call .args [0 ]
106+ value_arg = call .args [1 ]
107+ flags_arg = call .args [2 ] if len (call .args ) > 2 else None
108+
109+ # Handle key
110+ if isinstance (key_arg , ast .Name ):
111+ key_name = key_arg .id
112+ if local_sym_tab and key_name in local_sym_tab :
113+ key_ptr = local_sym_tab [key_name ]
114+ else :
115+ raise ValueError (
116+ f"Key variable { key_name } not found in local symbol table." )
117+ elif isinstance (key_arg , ast .Constant ) and isinstance (key_arg .value , int ):
118+ # Handle constant integer keys
119+ key_val = key_arg .value
120+ key_type = ir .IntType (64 )
121+ key_ptr = builder .alloca (key_type )
122+ key_ptr .align = key_type .width // 8
123+ builder .store (ir .Constant (key_type , key_val ), key_ptr )
124+ else :
125+ raise NotImplementedError (
126+ "Only simple variable names and integer constants are supported as keys in map update." )
127+
128+ # Handle value
129+ if isinstance (value_arg , ast .Name ):
130+ value_name = value_arg .id
131+ if local_sym_tab and value_name in local_sym_tab :
132+ value_ptr = local_sym_tab [value_name ]
133+ else :
134+ raise ValueError (
135+ f"Value variable { value_name } not found in local symbol table." )
136+ elif isinstance (value_arg , ast .Constant ) and isinstance (value_arg .value , int ):
137+ # Handle constant integers
138+ value_val = value_arg .value
139+ value_type = ir .IntType (64 )
140+ value_ptr = builder .alloca (value_type )
141+ value_ptr .align = value_type .width // 8
142+ builder .store (ir .Constant (value_type , value_val ), value_ptr )
143+ else :
144+ raise NotImplementedError (
145+ "Only simple variable names and integer constants are supported as values in map update." )
146+
147+ # Handle flags argument (defaults to 0)
148+ if flags_arg is not None :
149+ if isinstance (flags_arg , ast .Constant ) and isinstance (flags_arg .value , int ):
150+ flags_val = flags_arg .value
151+ elif isinstance (flags_arg , ast .Name ):
152+ flags_name = flags_arg .id
153+ if local_sym_tab and flags_name in local_sym_tab :
154+ # Assume it's a stored integer value, load it
155+ flags_ptr = local_sym_tab [flags_name ]
156+ flags_val = builder .load (flags_ptr )
157+ else :
158+ raise ValueError (
159+ f"Flags variable { flags_name } not found in local symbol table." )
160+ else :
161+ raise NotImplementedError (
162+ "Only integer constants and simple variable names are supported as flags in map update." )
163+ else :
164+ flags_val = 0
165+
166+ if key_ptr is None or value_ptr is None :
167+ raise ValueError ("Key pointer or value pointer is None." )
168+
169+ map_void_ptr = builder .bitcast (map_ptr , ir .PointerType ())
170+ fn_type = ir .FunctionType (
171+ ir .IntType (64 ),
172+ [ir .PointerType (), ir .PointerType (), ir .PointerType (), ir .IntType (64 )],
173+ var_arg = False
174+ )
175+ fn_ptr_type = ir .PointerType (fn_type )
176+
177+ # helper id
178+ fn_addr = ir .Constant (ir .IntType (64 ), 2 )
179+ fn_ptr = builder .inttoptr (fn_addr , fn_ptr_type )
180+
181+ if isinstance (flags_val , int ):
182+ flags_const = ir .Constant (ir .IntType (64 ), flags_val )
183+ else :
184+ flags_const = flags_val
185+
186+ result = builder .call (fn_ptr , [map_void_ptr , key_ptr , value_ptr , flags_const ], tail = False )
187+
188+ return result
97189
98190helper_func_list = {
99191 "lookup" : bpf_map_lookup_elem_emitter ,
100192 "print" : bpf_printk_emitter ,
101193 "ktime" : bpf_ktime_get_ns_emitter ,
194+ "update" : bpf_map_update_elem_emitter ,
102195}
103196
104197
0 commit comments