@@ -61,7 +61,7 @@ let create_hardcoded_tc_action_enum () = {
6161}
6262
6363(* * Get program template based on eBPF program type *)
64- let rec get_program_template prog_type btf_path =
64+ let get_program_template prog_type btf_path =
6565 let (context_type, return_type, common_types) = match prog_type with
6666 | "xdp" -> (" xdp_md" , " xdp_action" , [
6767 " xdp_md" ; " xdp_action"
@@ -89,7 +89,16 @@ let rec get_program_template prog_type btf_path =
8989
9090 (* Extract types from BTF - BTF file is required *)
9191 let extracted_types = match btf_path with
92- | Some path when Sys. file_exists path -> extract_types_from_btf path common_types
92+ | Some path when Sys. file_exists path ->
93+ let binary_types = Btf_binary_parser. parse_btf_file path common_types in
94+ (* Convert binary parser types to btf_type_info *)
95+ List. map (fun bt -> {
96+ name = bt.Btf_binary_parser. name;
97+ kind = bt.Btf_binary_parser. kind;
98+ size = bt.Btf_binary_parser. size;
99+ members = bt.Btf_binary_parser. members;
100+ kernel_defined = is_well_known_kernel_type bt.Btf_binary_parser. name;
101+ }) binary_types
93102 | Some path -> failwith (sprintf " BTF file not found: %s" path)
94103 | None -> failwith " BTF file path is required. Use --btf-vmlinux-path option."
95104 in
@@ -119,32 +128,57 @@ let rec get_program_template prog_type btf_path =
119128 function_signatures = function_signatures;
120129 }
121130
122- (* * Extract specific types from BTF file using binary parser *)
123- and extract_types_from_btf btf_path type_names =
124- try
125- printf " Extracting types from BTF file: %s\n " btf_path;
126- let binary_types = Btf_binary_parser. parse_btf_file btf_path type_names in
127-
128- (* Convert binary parser types to btf_type_info *)
129- let converted_types = List. map (fun bt ->
130- {
131- name = bt.Btf_binary_parser. name;
132- kind = bt.Btf_binary_parser. kind;
133- size = bt.Btf_binary_parser. size;
134- members = bt.Btf_binary_parser. members;
135- kernel_defined = is_well_known_kernel_type bt.Btf_binary_parser. name;
136- }
137- ) binary_types in
138-
139- if List. length converted_types > 0 then (
140- printf " Successfully extracted %d types from BTF\n " (List. length converted_types);
141- converted_types
142- ) else (
143- failwith " No types extracted from BTF - requested types not found"
144- )
145- with
146- | exn ->
147- failwith (sprintf " BTF extraction failed: %s" (Printexc. to_string exn ))
131+ (* * Get tracepoint program template for a specific category/event *)
132+ let get_tracepoint_program_template category_event btf_path =
133+ (* Parse category and event from the category_event string *)
134+ let (category, event) =
135+ if String. contains category_event '/' then
136+ let parts = String. split_on_char '/' category_event in
137+ match parts with
138+ | [cat; evt] -> (cat, evt)
139+ | _ -> failwith (sprintf " Invalid tracepoint format '%s'. Use 'category/event'" category_event)
140+ else
141+ failwith (sprintf " Invalid tracepoint format '%s'. Use 'category/event'" category_event)
142+ in
143+
144+ (* Determine typedef_name and raw_name based on the user's logic *)
145+ let (typedef_name, raw_name) =
146+ if category = " syscalls" && String. starts_with event ~prefix: " sys_enter_" then
147+ (" btf_trace_sys_enter" , " trace_event_raw_sys_enter" )
148+ else if category = " syscalls" && String. starts_with event ~prefix: " sys_exit_" then
149+ (" btf_trace_sys_exit" , " trace_event_raw_sys_exit" )
150+ else
151+ (sprintf " btf_trace_%s" event, sprintf " trace_event_raw_%s" event)
152+ in
153+
154+ (* Extract the tracepoint structure from BTF *)
155+ let common_types = [raw_name; typedef_name] in
156+ let extracted_types = match btf_path with
157+ | Some path when Sys. file_exists path ->
158+ let binary_types = Btf_binary_parser. parse_btf_file path common_types in
159+ (* Convert binary parser types to btf_type_info *)
160+ List. map (fun bt -> {
161+ name = bt.Btf_binary_parser. name;
162+ kind = bt.Btf_binary_parser. kind;
163+ size = bt.Btf_binary_parser. size;
164+ members = bt.Btf_binary_parser. members;
165+ kernel_defined = is_well_known_kernel_type bt.Btf_binary_parser. name;
166+ }) binary_types
167+ | Some path -> failwith (sprintf " BTF file not found: %s" path)
168+ | None -> failwith " BTF file path is required for tracepoint extraction. Use --btf-vmlinux-path option."
169+ in
170+
171+ (* Create the context type from the extracted struct *)
172+ let context_type = sprintf " *%s" raw_name in
173+
174+ {
175+ program_type = " tracepoint" ;
176+ context_type = context_type;
177+ return_type = " i32" ;
178+ includes = [" linux/bpf.h" ; " bpf/bpf_helpers.h" ; " bpf/bpf_tracing.h" ; " linux/trace_events.h" ];
179+ types = extracted_types;
180+ function_signatures = [(sprintf " %s/%s" category event, sprintf " fn(%s) -> i32" context_type)];
181+ }
148182
149183(* * Get kprobe program template for a specific target function *)
150184let get_kprobe_program_template target_function btf_path =
@@ -312,8 +346,8 @@ let generate_kernelscript_source template project_name =
312346 | [] -> " 0"
313347 in
314348
315- (* Generate function signature comments and actual function definition for kprobe programs *)
316- let (function_signatures_comment, target_function_name, function_definition) =
349+ (* Generate function signature comments and actual function definition for specific program types *)
350+ let (function_signatures_comment, target_function_name, function_definition, custom_attribute ) =
317351 if template.program_type = " kprobe" && template.function_signatures <> [] then
318352 let signature_lines = List. map (fun (func_name , signature ) ->
319353 sprintf " // Target function: %s -> %s" func_name signature
@@ -325,27 +359,58 @@ let generate_kernelscript_source template project_name =
325359 | [] -> (" target_function" , " fn() -> i32" )
326360 in
327361 let func_def = generate_kprobe_function_from_signature first_func first_sig in
328- (comment, first_func, func_def)
362+ (comment, first_func, func_def, Some (sprintf " @kprobe(\" %s\" )" first_func))
363+ else if template.program_type = " tracepoint" && template.function_signatures <> [] then
364+ let signature_lines = List. map (fun (event_name , signature ) ->
365+ sprintf " // Tracepoint event: %s -> %s" event_name signature
366+ ) template.function_signatures in
367+ let comment = sprintf " \n // Tracepoint event signature:\n %s\n "
368+ (String. concat " \n " signature_lines) in
369+ let first_event, _first_sig = match template.function_signatures with
370+ | (name , sig_str ) :: _ -> (name, sig_str)
371+ | [] -> (" category/event" , " fn(void*) -> i32" )
372+ in
373+ let func_def = sprintf " fn %s_handler(ctx: %s) -> %s"
374+ (String. map (function '/' -> '_' | c -> c) first_event) template.context_type template.return_type in
375+ (comment, first_event, func_def, Some (sprintf " @tracepoint(\" %s\" )" first_event))
329376 else
330- (" " , " target_function" , sprintf " fn %s_handler(ctx: %s) -> %s" project_name template.context_type template.return_type)
377+ (" " , " target_function" , sprintf " fn %s_handler(ctx: %s) -> %s" project_name template.context_type template.return_type, None )
331378 in
332379
333- (* Customize attach call for kprobe *)
334- let attach_target = if template.program_type = " kprobe" then target_function_name else " eth0" in
335- let attach_comment = if template.program_type = " kprobe" then
336- " // Attach kprobe to target kernel function"
337- else
338- " // TODO: Update interface name and attachment parameters"
380+ (* Use custom attribute if available, otherwise use generic program type attribute *)
381+ let attribute_line = match custom_attribute with
382+ | Some attr -> attr
383+ | None -> " @" ^ template.program_type
339384 in
340385
341- let function_name = if template.program_type = " kprobe" then target_function_name else sprintf " %s_handler" project_name in
386+ (* Customize attach call for kprobe/tracepoint *)
387+ let attach_target =
388+ if template.program_type = " kprobe" then target_function_name
389+ else if template.program_type = " tracepoint" then target_function_name
390+ else " eth0"
391+ in
392+ let attach_comment =
393+ if template.program_type = " kprobe" then
394+ " // Attach kprobe to target kernel function"
395+ else if template.program_type = " tracepoint" then
396+ " // Attach tracepoint to target kernel event"
397+ else
398+ " // TODO: Update interface name and attachment parameters"
399+ in
400+
401+ let function_name =
402+ if template.program_type = " kprobe" then target_function_name
403+ else if template.program_type = " tracepoint" then
404+ String. map (function '/' -> '_' | c -> c) target_function_name ^ " _handler"
405+ else sprintf " %s_handler" project_name
406+ in
342407
343408 sprintf {|% s
344409// Generated by KernelScript compiler with direct BTF parsing
345410% s
346411% s
347412
348- @ % s
413+ % s
349414% s {
350415 // TODO : Implement your % s logic here
351416
@@ -367,4 +432,4 @@ fn main() -> i32 {
367432
368433 return 0
369434}
370- | } context_comment function_signatures_comment type_definitions template.program_type function_definition template.program_type sample_return function_name attach_comment attach_target template.program_type template.program_type
435+ | } context_comment function_signatures_comment type_definitions attribute_line function_definition template.program_type sample_return function_name attach_comment attach_target template.program_type template.program_type
0 commit comments