@@ -123,77 +123,171 @@ static __always_inline __u64* take_param(void* map) {
123123 return value ;
124124}
125125
126- /* Helper to submit an event to the ring buffer */
127- static __always_inline int submit_event (__u64 addr , __u64 size , __u8 event_type ) {
128- __u64 tid = bpf_get_current_pid_tgid ();
129- __u32 pid = tid >> 32 ;
130-
131- if (!is_tracked (pid ) || !is_enabled ()) {
132- return 0 ;
126+ /* Macro to handle common event submission boilerplate
127+ * Usage: SUBMIT_EVENT(event_type, { e->data.foo = bar; })
128+ */
129+ #define SUBMIT_EVENT (evt_type , fill_data ) \
130+ { \
131+ __u64 tid = bpf_get_current_pid_tgid(); \
132+ __u32 pid = tid >> 32; \
133+ \
134+ if (!is_tracked(pid) || !is_enabled()) { \
135+ return 0; \
136+ } \
137+ \
138+ struct event* e = bpf_ringbuf_reserve(&events, sizeof(*e), 0); \
139+ if (!e) { \
140+ return 0; \
141+ } \
142+ \
143+ e->header.timestamp = bpf_ktime_get_ns(); \
144+ e->header.pid = pid; \
145+ e->header.tid = tid & 0xFFFFFFFF; \
146+ e->header.event_type = evt_type; \
147+ \
148+ fill_data; \
149+ \
150+ bpf_ringbuf_submit(e, 0); \
151+ return 0; \
133152 }
134153
135- struct event * e = bpf_ringbuf_reserve (& events , sizeof (* e ), 0 );
136- if (!e ) {
137- return 0 ;
138- }
154+ /* Helper to submit an allocation event (malloc, calloc, aligned_alloc) */
155+ static __always_inline int submit_alloc_event (__u64 size , __u64 addr ) {
156+ SUBMIT_EVENT (EVENT_TYPE_MALLOC , {
157+ e -> data .alloc .addr = addr ;
158+ e -> data .alloc .size = size ;
159+ });
160+ }
139161
140- e -> timestamp = bpf_ktime_get_ns ();
141- e -> pid = pid ;
142- e -> tid = tid & 0xFFFFFFFF ;
143- e -> event_type = event_type ;
144- e -> addr = addr ;
145- e -> size = size ;
146- bpf_ringbuf_submit (e , 0 );
162+ /* Helper to submit a free event */
163+ static __always_inline int submit_free_event (__u64 addr ) {
164+ SUBMIT_EVENT (EVENT_TYPE_FREE , {
165+ e -> data .free .addr = addr ;
166+ });
167+ }
147168
148- return 0 ;
169+ /* Helper to submit a realloc event with both old and new addresses */
170+ static __always_inline int submit_realloc_event (__u64 old_addr , __u64 new_addr , __u64 size ) {
171+ SUBMIT_EVENT (EVENT_TYPE_REALLOC , {
172+ e -> data .realloc .old_addr = old_addr ;
173+ e -> data .realloc .new_addr = new_addr ;
174+ e -> data .realloc .size = size ;
175+ });
149176}
150177
151- /* Macro to generate uprobe/uretprobe pairs for allocation functions */
152- #define UPROBE_WITH_ARGS (name , size_expr , addr_expr , event_type ) \
153- BPF_HASH_MAP(name##_size, __u64, __u64, 10000); \
178+ /* Helper to submit a memory mapping event (mmap, munmap, brk) */
179+ static __always_inline int submit_mmap_event (__u64 addr , __u64 size , __u8 event_type ) {
180+ SUBMIT_EVENT (event_type , {
181+ e -> data .mmap .addr = addr ;
182+ e -> data .mmap .size = size ;
183+ });
184+ }
185+
186+ /* Macro to generate uprobe/uretprobe pairs for allocation functions with 1 argument */
187+ #define UPROBE_ARG_RET (name , arg_expr , submit_block ) \
188+ BPF_HASH_MAP(name##_arg, __u64, __u64, 10000); \
154189 SEC("uprobe") \
155- int uprobe_##name(struct pt_regs* ctx) { return store_param(&name##_size, size_expr ); } \
190+ int uprobe_##name(struct pt_regs* ctx) { return store_param(&name##_arg, arg_expr ); } \
156191 SEC("uretprobe") \
157192 int uretprobe_##name(struct pt_regs* ctx) { \
158- __u64* size_ptr = take_param(&name##_size); \
159- if (!size_ptr ) { \
193+ __u64* arg_ptr = take_param(&name##_arg); \
194+ if (!arg_ptr ) { \
160195 return 0; \
161196 } \
162- __u64 addr = addr_expr; \
163- if (addr == 0) { \
197+ __u64 ret_val = PT_REGS_RC(ctx); \
198+ if (ret_val == 0) { \
164199 return 0; \
165200 } \
166- return submit_event(addr, *size_ptr, event_type); \
201+ __u64 arg0 = *arg_ptr; \
202+ submit_block; \
203+ }
204+
205+ /* Macro for simple return value only functions like free */
206+ #define UPROBE_RET (name , arg_expr , submit_block ) \
207+ SEC("uprobe") \
208+ int uprobe_##name(struct pt_regs* ctx) { \
209+ __u64 arg0 = arg_expr; \
210+ if (arg0 == 0) { \
211+ return 0; \
212+ } \
213+ submit_block; \
167214 }
168215
169- /* Macro for simple address-only functions like free */
170- #define UPROBE_ADDR_ONLY (name , addr_expr , event_type ) \
171- SEC("uprobe") \
172- int uprobe_##name(struct pt_regs* ctx) { \
173- __u64 addr = addr_expr; \
174- if (addr == 0) { \
175- return 0; \
176- } \
177- return submit_event(addr, 0, event_type); \
216+ /* Macro to generate uprobe/uretprobe pairs for functions with 2 arguments */
217+ #define UPROBE_ARGS_RET (name , arg0_expr , arg1_expr , submit_block ) \
218+ struct name##_args_t { \
219+ __u64 arg0; \
220+ __u64 arg1; \
221+ }; \
222+ BPF_HASH_MAP(name##_args, __u64, struct name##_args_t, 10000); \
223+ SEC("uprobe") \
224+ int uprobe_##name(struct pt_regs* ctx) { \
225+ __u64 tid = bpf_get_current_pid_tgid(); \
226+ __u32 pid = tid >> 32; \
227+ \
228+ if (!is_tracked(pid)) { \
229+ return 0; \
230+ } \
231+ \
232+ struct name##_args_t args = { \
233+ .arg0 = arg0_expr, \
234+ .arg1 = arg1_expr \
235+ }; \
236+ \
237+ bpf_map_update_elem(&name##_args, &tid, &args, BPF_ANY); \
238+ return 0; \
239+ } \
240+ SEC("uretprobe") \
241+ int uretprobe_##name(struct pt_regs* ctx) { \
242+ __u64 tid = bpf_get_current_pid_tgid(); \
243+ struct name##_args_t* args = bpf_map_lookup_elem(&name##_args, &tid); \
244+ \
245+ if (!args) { \
246+ return 0; \
247+ } \
248+ \
249+ struct name##_args_t a = *args; \
250+ bpf_map_delete_elem(&name##_args, &tid); \
251+ \
252+ __u64 ret_val = PT_REGS_RC(ctx); \
253+ if (ret_val == 0) { \
254+ return 0; \
255+ } \
256+ \
257+ __u64 arg0 = a.arg0; \
258+ __u64 arg1 = a.arg1; \
259+ submit_block; \
178260 }
179261
180262/* malloc: allocates with size parameter */
181- UPROBE_WITH_ARGS (malloc , PT_REGS_PARM1 (ctx ), PT_REGS_RC (ctx ), EVENT_TYPE_MALLOC )
263+ UPROBE_ARG_RET (malloc , PT_REGS_PARM1 (ctx ), {
264+ return submit_alloc_event (arg0 , ret_val );
265+ })
182266
183267/* free: deallocates by address */
184- UPROBE_ADDR_ONLY (free , PT_REGS_PARM1 (ctx ), EVENT_TYPE_FREE )
268+ UPROBE_RET (free , PT_REGS_PARM1 (ctx ), {
269+ return submit_free_event (arg0 );
270+ })
185271
186272/* calloc: allocates with nmemb * size */
187- UPROBE_WITH_ARGS (calloc , PT_REGS_PARM1 (ctx ) * PT_REGS_PARM2 (ctx ), PT_REGS_RC (ctx ), EVENT_TYPE_CALLOC )
273+ UPROBE_ARG_RET (calloc , PT_REGS_PARM1 (ctx ) * PT_REGS_PARM2 (ctx ), {
274+ return submit_alloc_event (arg0 , ret_val );
275+ })
188276
189- /* realloc: reallocates with new size */
190- UPROBE_WITH_ARGS (realloc , PT_REGS_PARM2 (ctx ), PT_REGS_RC (ctx ), EVENT_TYPE_REALLOC )
277+ /* realloc: reallocates with old_addr and new size */
278+ UPROBE_ARGS_RET (realloc , PT_REGS_PARM2 (ctx ), PT_REGS_PARM1 (ctx ), {
279+ return submit_realloc_event (arg1 , ret_val , arg0 );
280+ })
191281
192282/* aligned_alloc: allocates with alignment and size */
193- UPROBE_WITH_ARGS (aligned_alloc , PT_REGS_PARM2 (ctx ), PT_REGS_RC (ctx ), EVENT_TYPE_ALIGNED_ALLOC )
283+ UPROBE_ARG_RET (aligned_alloc , PT_REGS_PARM2 (ctx ), {
284+ return submit_alloc_event (arg0 , ret_val );
285+ })
194286
195287/* memalign: allocates with alignment and size (legacy interface) */
196- UPROBE_WITH_ARGS (memalign , PT_REGS_PARM2 (ctx ), PT_REGS_RC (ctx ), EVENT_TYPE_ALIGNED_ALLOC )
288+ UPROBE_ARG_RET (memalign , PT_REGS_PARM2 (ctx ), {
289+ return submit_alloc_event (arg0 , ret_val );
290+ })
197291
198292/* Map to store mmap parameters between entry and return */
199293struct mmap_args {
@@ -234,7 +328,7 @@ int tracepoint_sys_exit_mmap(struct trace_event_raw_sys_exit* ctx) {
234328 return 0 ;
235329 }
236330
237- return submit_event ((__u64 )ret , args -> len , EVENT_TYPE_MMAP );
331+ return submit_mmap_event ((__u64 )ret , args -> len , EVENT_TYPE_MMAP );
238332}
239333
240334/* munmap tracking */
@@ -247,7 +341,7 @@ int tracepoint_sys_enter_munmap(struct trace_event_raw_sys_enter* ctx) {
247341 return 0 ;
248342 }
249343
250- return submit_event (addr , len , EVENT_TYPE_MUNMAP );
344+ return submit_mmap_event (addr , len , EVENT_TYPE_MUNMAP );
251345}
252346
253347/* brk tracking - adjusts the program break (heap boundary) */
@@ -281,5 +375,5 @@ int tracepoint_sys_exit_brk(struct trace_event_raw_sys_exit* ctx) {
281375 return 0 ;
282376 }
283377
284- return submit_event (new_brk , 0 , EVENT_TYPE_BRK );
378+ return submit_mmap_event (new_brk , 0 , EVENT_TYPE_BRK );
285379}
0 commit comments