@@ -1152,6 +1152,137 @@ let check_object_allocation_usage ir_multi_prog =
11521152let check_object_allocation_usage_in_program ir_prog =
11531153 check_object_allocation_usage_in_function ir_prog.entry_function
11541154
1155+ (* * Check if dynptr functionality is used in IR instructions *)
1156+ let rec check_dynptr_usage_in_instrs instrs =
1157+ List. exists (fun instr ->
1158+ match instr.instr_desc with
1159+ | IRRingbufOp (_ , _ ) -> true (* Ring buffer operations always use dynptr *)
1160+ | IRStructFieldAssignment (obj_val , _ , _ ) ->
1161+ (* Struct field assignments on packet data or map values use dynptr *)
1162+ (match detect_memory_region_enhanced obj_val with
1163+ | PacketData | MapValue -> true
1164+ | _ -> false )
1165+ | IRAssign (_ , expr ) ->
1166+ (* Check if assignment expressions use enhanced memory access patterns *)
1167+ check_dynptr_usage_in_expr expr
1168+ | IRCall (_ , args , _ ) ->
1169+ (* Check function call arguments for enhanced memory patterns *)
1170+ List. exists check_dynptr_usage_in_value args
1171+ | IRIf (condition , then_body , else_body ) ->
1172+ (check_dynptr_usage_in_value condition) ||
1173+ (check_dynptr_usage_in_instrs then_body) ||
1174+ (match else_body with
1175+ | Some else_instrs -> check_dynptr_usage_in_instrs else_instrs
1176+ | None -> false )
1177+ | IRIfElseChain (conditions_and_bodies , final_else ) ->
1178+ (List. exists (fun (condition , then_body ) ->
1179+ (check_dynptr_usage_in_value condition) ||
1180+ (check_dynptr_usage_in_instrs then_body)
1181+ ) conditions_and_bodies) ||
1182+ (match final_else with
1183+ | Some else_instrs -> check_dynptr_usage_in_instrs else_instrs
1184+ | None -> false )
1185+ | IRBpfLoop (_ , _ , _ , _ , body_instrs ) ->
1186+ check_dynptr_usage_in_instrs body_instrs
1187+ | _ -> false
1188+ ) instrs
1189+
1190+ and check_dynptr_usage_in_expr expr =
1191+ match expr.expr_desc with
1192+ | IRValue value -> check_dynptr_usage_in_value value
1193+ | IRBinOp (left , _ , right ) ->
1194+ (check_dynptr_usage_in_value left) || (check_dynptr_usage_in_value right)
1195+ | IRUnOp (IRDeref, value ) ->
1196+ (* Dereference operations on packet data or map values use dynptr *)
1197+ (match detect_memory_region_enhanced value with
1198+ | PacketData | MapValue -> true
1199+ | _ -> false )
1200+ | IRUnOp (_ , value ) -> check_dynptr_usage_in_value value
1201+ | IRFieldAccess (obj_value , _ ) ->
1202+ (* Field access on packet data or map values uses dynptr *)
1203+ (match detect_memory_region_enhanced obj_value with
1204+ | PacketData | MapValue -> true
1205+ | _ -> false )
1206+ | IRCast (value , _ ) -> check_dynptr_usage_in_value value
1207+ | _ -> false
1208+
1209+ and check_dynptr_usage_in_value value =
1210+ match value.value_desc with
1211+ | IRMapAccess (_ , _ , _ ) -> true (* Map access may use enhanced patterns *)
1212+ | IRContextField (_ , _ ) -> true (* Context field access may use enhanced patterns *)
1213+ | _ -> false
1214+
1215+ (* * Check if dynptr functionality is used in a function *)
1216+ let check_dynptr_usage_in_function ir_func =
1217+ List. exists (fun basic_block ->
1218+ check_dynptr_usage_in_instrs basic_block.instructions
1219+ ) ir_func.basic_blocks
1220+
1221+ (* * Check if dynptr functionality is used in a multi-program *)
1222+ let check_dynptr_usage ir_multi_prog =
1223+ (* Conservative approach: include dynptr for XDP/TC programs or any enhanced memory access *)
1224+ (List. exists (fun ir_prog ->
1225+ match ir_prog.program_type with
1226+ | Xdp | Tc -> true (* XDP/TC commonly use packet data access *)
1227+ | _ -> check_dynptr_usage_in_function ir_prog.entry_function
1228+ ) ir_multi_prog.programs) ||
1229+ (* Check kernel functions *)
1230+ (List. exists check_dynptr_usage_in_function ir_multi_prog.kernel_functions)
1231+
1232+ (* * Check if a single IR program uses dynptr functionality *)
1233+ let check_dynptr_usage_in_program ir_prog =
1234+ match ir_prog.program_type with
1235+ | Xdp | Tc -> true (* XDP/TC commonly use packet data access *)
1236+ | _ -> check_dynptr_usage_in_function ir_prog.entry_function
1237+
1238+ (* * Generate dynptr safety macros and helper functions *)
1239+ let generate_dynptr_macros ctx =
1240+ emit_line ctx " /* eBPF Dynptr API integration for enhanced pointer safety */" ;
1241+ emit_line ctx " /* Using system-provided bpf_dynptr_* helper functions from bpf_helpers.h */" ;
1242+ emit_blank_line ctx;
1243+
1244+ (* Generate enhanced dynptr safety macros *)
1245+ emit_line ctx " /* Enhanced dynptr safety macros */" ;
1246+ emit_line ctx " #define DYNPTR_SAFE_ACCESS(dynptr, offset, size, type) \\ " ;
1247+ emit_line ctx " ({ \\ " ;
1248+ emit_line ctx " type *__ptr = (type*)bpf_dynptr_data(dynptr, offset, sizeof(type)); \\ " ;
1249+ emit_line ctx " __ptr ? *__ptr : (type){0}; \\ " ;
1250+ emit_line ctx " })" ;
1251+ emit_blank_line ctx;
1252+
1253+ emit_line ctx " #define DYNPTR_SAFE_WRITE(dynptr, offset, value, type) \\ " ;
1254+ emit_line ctx " ({ \\ " ;
1255+ emit_line ctx " type __tmp = (value); \\ " ;
1256+ emit_line ctx " bpf_dynptr_write(dynptr, offset, &__tmp, sizeof(type), 0); \\ " ;
1257+ emit_line ctx " })" ;
1258+ emit_blank_line ctx;
1259+
1260+ emit_line ctx " #define DYNPTR_SAFE_READ(dst, dynptr, offset, type) \\ " ;
1261+ emit_line ctx " bpf_dynptr_read(dst, sizeof(type), dynptr, offset, 0)" ;
1262+ emit_blank_line ctx;
1263+
1264+ (* Fallback macros for regular pointers *)
1265+ emit_line ctx " /* Fallback macros for regular pointer operations */" ;
1266+ emit_line ctx " #define SAFE_DEREF(ptr) \\ " ;
1267+ emit_line ctx " ({ \\ " ;
1268+ emit_line ctx " typeof(*ptr) __val = {0}; \\ " ;
1269+ emit_line ctx " if (ptr) { \\ " ;
1270+ emit_line ctx " __builtin_memcpy(&__val, ptr, sizeof(__val)); \\ " ;
1271+ emit_line ctx " } \\ " ;
1272+ emit_line ctx " __val; \\ " ;
1273+ emit_line ctx " })" ;
1274+ emit_blank_line ctx;
1275+
1276+ emit_line ctx " #define SAFE_PTR_ACCESS(ptr, field) \\ " ;
1277+ emit_line ctx " ({ \\ " ;
1278+ emit_line ctx " typeof((ptr)->field) __val = {0}; \\ " ;
1279+ emit_line ctx " if (ptr) { \\ " ;
1280+ emit_line ctx " __val = (ptr)->field; \\ " ;
1281+ emit_line ctx " } \\ " ;
1282+ emit_line ctx " __val; \\ " ;
1283+ emit_line ctx " })" ;
1284+ emit_blank_line ctx
1285+
11551286(* * Generate standard eBPF includes *)
11561287
11571288let generate_includes ctx ?(program_types =[] ) ?(ir_multi_prog =None ) ?(ir_program =None ) () =
@@ -3523,6 +3654,10 @@ let generate_c_program ?_config_declarations ir_prog =
35233654 let program_types = [ir_prog.program_type] in
35243655 generate_includes ctx ~program_types ~ir_program: (Some ir_prog) () ;
35253656
3657+ (* Generate dynptr safety macros only if needed for single program *)
3658+ let uses_dynptr = check_dynptr_usage_in_program ir_prog in
3659+ if uses_dynptr then generate_dynptr_macros ctx;
3660+
35263661 (* Generate string type definitions *)
35273662 let temp_multi_prog = {
35283663 source_name = ir_prog.name;
@@ -3715,52 +3850,9 @@ let compile_multi_to_c_with_tail_calls
37153850 let program_types = List. map (fun ir_prog -> ir_prog.program_type) ir_multi_prog.programs in
37163851 generate_includes ctx ~program_types ~ir_multi_prog: (Some ir_multi_prog) () ;
37173852
3718- (* Generate dynptr safety macros and helper functions *)
3719- emit_line ctx " /* eBPF Dynptr API integration for enhanced pointer safety */" ;
3720- emit_line ctx " /* Using system-provided bpf_dynptr_* helper functions from bpf_helpers.h */" ;
3721- emit_blank_line ctx;
3722-
3723- (* Generate enhanced dynptr safety macros *)
3724- emit_line ctx " /* Enhanced dynptr safety macros */" ;
3725- emit_line ctx " #define DYNPTR_SAFE_ACCESS(dynptr, offset, size, type) \\ " ;
3726- emit_line ctx " ({ \\ " ;
3727- emit_line ctx " type *__ptr = (type*)bpf_dynptr_data(dynptr, offset, sizeof(type)); \\ " ;
3728- emit_line ctx " __ptr ? *__ptr : (type){0}; \\ " ;
3729- emit_line ctx " })" ;
3730- emit_blank_line ctx;
3731-
3732- emit_line ctx " #define DYNPTR_SAFE_WRITE(dynptr, offset, value, type) \\ " ;
3733- emit_line ctx " ({ \\ " ;
3734- emit_line ctx " type __tmp = (value); \\ " ;
3735- emit_line ctx " bpf_dynptr_write(dynptr, offset, &__tmp, sizeof(type), 0); \\ " ;
3736- emit_line ctx " })" ;
3737- emit_blank_line ctx;
3738-
3739- emit_line ctx " #define DYNPTR_SAFE_READ(dst, dynptr, offset, type) \\ " ;
3740- emit_line ctx " bpf_dynptr_read(dst, sizeof(type), dynptr, offset, 0)" ;
3741- emit_blank_line ctx;
3742-
3743- (* Fallback macros for regular pointers *)
3744- emit_line ctx " /* Fallback macros for regular pointer operations */" ;
3745- emit_line ctx " #define SAFE_DEREF(ptr) \\ " ;
3746- emit_line ctx " ({ \\ " ;
3747- emit_line ctx " typeof(*ptr) __val = {0}; \\ " ;
3748- emit_line ctx " if (ptr) { \\ " ;
3749- emit_line ctx " __builtin_memcpy(&__val, ptr, sizeof(__val)); \\ " ;
3750- emit_line ctx " } \\ " ;
3751- emit_line ctx " __val; \\ " ;
3752- emit_line ctx " })" ;
3753- emit_blank_line ctx;
3754-
3755- emit_line ctx " #define SAFE_PTR_ACCESS(ptr, field) \\ " ;
3756- emit_line ctx " ({ \\ " ;
3757- emit_line ctx " typeof((ptr)->field) __val = {0}; \\ " ;
3758- emit_line ctx " if (ptr) { \\ " ;
3759- emit_line ctx " __val = (ptr)->field; \\ " ;
3760- emit_line ctx " } \\ " ;
3761- emit_line ctx " __val; \\ " ;
3762- emit_line ctx " })" ;
3763- emit_blank_line ctx;
3853+ (* Generate dynptr safety macros and helper functions only if needed *)
3854+ let uses_dynptr = check_dynptr_usage ir_multi_prog in
3855+ if uses_dynptr then generate_dynptr_macros ctx;
37643856
37653857 (* Store variable type aliases for later lookup *)
37663858 ctx.variable_type_aliases < - variable_type_aliases;
0 commit comments