Skip to content

Commit f0570cb

Browse files
committed
Add object allocation checks in eBPF code generation.
1 parent bd61c79 commit f0570cb

File tree

1 file changed

+86
-31
lines changed

1 file changed

+86
-31
lines changed

src/ebpf_c_codegen.ml

Lines changed: 86 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,9 +1106,55 @@ let generate_declarations_in_source_order ctx _ir_multi_program type_aliases =
11061106
(* Function has side effects on ctx, no return value needed *)
11071107
()
11081108

1109+
(** Check if IR multi-program contains object allocation instructions *)
1110+
let rec check_object_allocation_usage_in_instrs instrs =
1111+
List.exists (fun instr ->
1112+
match instr.instr_desc with
1113+
| IRObjectNew (_, _) | IRObjectDelete _ -> true
1114+
| IRIf (_, then_body, else_body) ->
1115+
(check_object_allocation_usage_in_instrs then_body) ||
1116+
(match else_body with
1117+
| Some else_instrs -> check_object_allocation_usage_in_instrs else_instrs
1118+
| None -> false)
1119+
| IRIfElseChain (conditions_and_bodies, final_else) ->
1120+
(List.exists (fun (_, then_body) ->
1121+
check_object_allocation_usage_in_instrs then_body
1122+
) conditions_and_bodies) ||
1123+
(match final_else with
1124+
| Some else_instrs -> check_object_allocation_usage_in_instrs else_instrs
1125+
| None -> false)
1126+
| IRBpfLoop (_, _, _, _, body_instrs) ->
1127+
check_object_allocation_usage_in_instrs body_instrs
1128+
| IRTry (try_instrs, catch_clauses) ->
1129+
(check_object_allocation_usage_in_instrs try_instrs) ||
1130+
(List.exists (fun clause ->
1131+
check_object_allocation_usage_in_instrs clause.catch_body
1132+
) catch_clauses)
1133+
| IRDefer defer_instrs ->
1134+
check_object_allocation_usage_in_instrs defer_instrs
1135+
| _ -> false
1136+
) instrs
1137+
1138+
let check_object_allocation_usage_in_function ir_func =
1139+
List.exists (fun block ->
1140+
check_object_allocation_usage_in_instrs block.instructions
1141+
) ir_func.basic_blocks
1142+
1143+
let check_object_allocation_usage ir_multi_prog =
1144+
(* Check all programs *)
1145+
(List.exists (fun ir_prog ->
1146+
check_object_allocation_usage_in_function ir_prog.entry_function
1147+
) ir_multi_prog.programs) ||
1148+
(* Check kernel functions *)
1149+
(List.exists check_object_allocation_usage_in_function ir_multi_prog.kernel_functions)
1150+
1151+
(** Check if a single IR program contains object allocation instructions *)
1152+
let check_object_allocation_usage_in_program ir_prog =
1153+
check_object_allocation_usage_in_function ir_prog.entry_function
1154+
11091155
(** Generate standard eBPF includes *)
11101156

1111-
let generate_includes ctx ?(program_types=[]) () =
1157+
let generate_includes ctx ?(program_types=[]) ?(ir_multi_prog=None) ?(ir_program=None) () =
11121158
(* Use vmlinux.h which contains all kernel types from BTF *)
11131159
let vmlinux_includes = [
11141160
"#include \"vmlinux.h\"";
@@ -1156,34 +1202,43 @@ let generate_includes ctx ?(program_types=[]) () =
11561202
List.iter (emit_line ctx) all_includes;
11571203
emit_blank_line ctx;
11581204

1159-
(* Use proper kernel implementation: extern declarations and macros *)
1160-
emit_line ctx "extern void *bpf_obj_new_impl(__u64 local_type_id__k, void *meta__ign) __ksym;";
1161-
emit_line ctx "extern void bpf_obj_drop_impl(void *p__alloc, void *meta__ign) __ksym;";
1162-
emit_blank_line ctx;
1163-
1164-
(* Use exact kernel implementation for proper typeof handling *)
1165-
emit_line ctx "#define ___concat(a, b) a ## b";
1166-
emit_line ctx "#ifdef __clang__";
1167-
emit_line ctx "#define ___bpf_typeof(type) ((typeof(type) *) 0)";
1168-
emit_line ctx "#else";
1169-
emit_line ctx "#define ___bpf_typeof1(type, NR) ({ \\";
1170-
emit_line ctx " extern typeof(type) *___concat(bpf_type_tmp_, NR); \\";
1171-
emit_line ctx " ___concat(bpf_type_tmp_, NR); \\";
1172-
emit_line ctx "})";
1173-
emit_line ctx "#define ___bpf_typeof(type) ___bpf_typeof1(type, __COUNTER__)";
1174-
emit_line ctx "#endif";
1175-
emit_blank_line ctx;
1176-
1177-
(* Add BPF_TYPE_ID_LOCAL constant *)
1178-
emit_line ctx "#ifndef BPF_TYPE_ID_LOCAL";
1179-
emit_line ctx "#define BPF_TYPE_ID_LOCAL 1";
1180-
emit_line ctx "#endif";
1181-
emit_blank_line ctx;
1205+
(* Only include object allocation code if the program actually uses new() or delete() *)
1206+
let uses_object_allocation = match ir_multi_prog, ir_program with
1207+
| Some multi_prog, _ -> check_object_allocation_usage multi_prog
1208+
| None, Some single_prog -> check_object_allocation_usage_in_program single_prog
1209+
| None, None -> false (* Conservative: don't include if we can't analyze *)
1210+
in
11821211

1183-
emit_line ctx "#define bpf_core_type_id_kernel(type) __builtin_btf_type_id(*(type*)0, 0)";
1184-
emit_line ctx "#define bpf_obj_new(type) ((type *)bpf_obj_new_impl(bpf_core_type_id_kernel(type), NULL))";
1185-
emit_line ctx "#define bpf_obj_drop(ptr) bpf_obj_drop_impl(ptr, NULL)";
1186-
emit_blank_line ctx
1212+
if uses_object_allocation then (
1213+
(* Use proper kernel implementation: extern declarations and macros *)
1214+
emit_line ctx "extern void *bpf_obj_new_impl(__u64 local_type_id__k, void *meta__ign) __ksym;";
1215+
emit_line ctx "extern void bpf_obj_drop_impl(void *p__alloc, void *meta__ign) __ksym;";
1216+
emit_blank_line ctx;
1217+
1218+
(* Use exact kernel implementation for proper typeof handling *)
1219+
emit_line ctx "#define ___concat(a, b) a ## b";
1220+
emit_line ctx "#ifdef __clang__";
1221+
emit_line ctx "#define ___bpf_typeof(type) ((typeof(type) *) 0)";
1222+
emit_line ctx "#else";
1223+
emit_line ctx "#define ___bpf_typeof1(type, NR) ({ \\";
1224+
emit_line ctx " extern typeof(type) *___concat(bpf_type_tmp_, NR); \\";
1225+
emit_line ctx " ___concat(bpf_type_tmp_, NR); \\";
1226+
emit_line ctx "})";
1227+
emit_line ctx "#define ___bpf_typeof(type) ___bpf_typeof1(type, __COUNTER__)";
1228+
emit_line ctx "#endif";
1229+
emit_blank_line ctx;
1230+
1231+
(* Add BPF_TYPE_ID_LOCAL constant *)
1232+
emit_line ctx "#ifndef BPF_TYPE_ID_LOCAL";
1233+
emit_line ctx "#define BPF_TYPE_ID_LOCAL 1";
1234+
emit_line ctx "#endif";
1235+
emit_blank_line ctx;
1236+
1237+
emit_line ctx "#define bpf_core_type_id_kernel(type) __builtin_btf_type_id(*(type*)0, 0)";
1238+
emit_line ctx "#define bpf_obj_new(type) ((type *)bpf_obj_new_impl(bpf_core_type_id_kernel(type), NULL))";
1239+
emit_line ctx "#define bpf_obj_drop(ptr) bpf_obj_drop_impl(ptr, NULL)";
1240+
emit_blank_line ctx
1241+
)
11871242
)
11881243

11891244
(** Generate map definitions *)
@@ -3466,7 +3521,7 @@ let generate_c_program ?_config_declarations ir_prog =
34663521

34673522
(* Add standard includes *)
34683523
let program_types = [ir_prog.program_type] in
3469-
generate_includes ctx ~program_types ();
3524+
generate_includes ctx ~program_types ~ir_program:(Some ir_prog) ();
34703525

34713526
(* Generate string type definitions *)
34723527
let temp_multi_prog = {
@@ -3539,7 +3594,7 @@ let generate_c_multi_program ?_config_declarations ?(type_aliases=[]) ?(variable
35393594

35403595
(* Add standard includes *)
35413596
let program_types = List.map (fun prog -> prog.program_type) ir_multi_prog.programs in
3542-
generate_includes ctx ~program_types ();
3597+
generate_includes ctx ~program_types ~ir_multi_prog:(Some ir_multi_prog) ();
35433598

35443599
(* Generate string type definitions *)
35453600
generate_string_typedefs ctx ir_multi_prog;
@@ -3658,7 +3713,7 @@ let compile_multi_to_c_with_tail_calls
36583713

36593714
(* Generate headers and includes *)
36603715
let program_types = List.map (fun ir_prog -> ir_prog.program_type) ir_multi_prog.programs in
3661-
generate_includes ctx ~program_types ();
3716+
generate_includes ctx ~program_types ~ir_multi_prog:(Some ir_multi_prog) ();
36623717

36633718
(* Generate dynptr safety macros and helper functions *)
36643719
emit_line ctx "/* eBPF Dynptr API integration for enhanced pointer safety */";

0 commit comments

Comments
 (0)