xref: /aosp_15_r20/external/bcc/libbpf-tools/memleak.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*387f9dfdSAndroid Build Coastguard Worker // Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
3*387f9dfdSAndroid Build Coastguard Worker #include <vmlinux.h>
4*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_helpers.h>
5*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_tracing.h>
6*387f9dfdSAndroid Build Coastguard Worker 
7*387f9dfdSAndroid Build Coastguard Worker #include "maps.bpf.h"
8*387f9dfdSAndroid Build Coastguard Worker #include "memleak.h"
9*387f9dfdSAndroid Build Coastguard Worker #include "core_fixes.bpf.h"
10*387f9dfdSAndroid Build Coastguard Worker 
11*387f9dfdSAndroid Build Coastguard Worker const volatile size_t min_size = 0;
12*387f9dfdSAndroid Build Coastguard Worker const volatile size_t max_size = -1;
13*387f9dfdSAndroid Build Coastguard Worker const volatile size_t page_size = 4096;
14*387f9dfdSAndroid Build Coastguard Worker const volatile __u64 sample_rate = 1;
15*387f9dfdSAndroid Build Coastguard Worker const volatile bool trace_all = false;
16*387f9dfdSAndroid Build Coastguard Worker const volatile __u64 stack_flags = 0;
17*387f9dfdSAndroid Build Coastguard Worker const volatile bool wa_missing_free = false;
18*387f9dfdSAndroid Build Coastguard Worker 
19*387f9dfdSAndroid Build Coastguard Worker struct {
20*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
21*387f9dfdSAndroid Build Coastguard Worker 	__type(key, u32);
22*387f9dfdSAndroid Build Coastguard Worker 	__type(value, u64);
23*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, 10240);
24*387f9dfdSAndroid Build Coastguard Worker } sizes SEC(".maps");
25*387f9dfdSAndroid Build Coastguard Worker 
26*387f9dfdSAndroid Build Coastguard Worker struct {
27*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
28*387f9dfdSAndroid Build Coastguard Worker 	__type(key, u64); /* address */
29*387f9dfdSAndroid Build Coastguard Worker 	__type(value, struct alloc_info);
30*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, ALLOCS_MAX_ENTRIES);
31*387f9dfdSAndroid Build Coastguard Worker } allocs SEC(".maps");
32*387f9dfdSAndroid Build Coastguard Worker 
33*387f9dfdSAndroid Build Coastguard Worker struct {
34*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
35*387f9dfdSAndroid Build Coastguard Worker 	__type(key, u64); /* stack id */
36*387f9dfdSAndroid Build Coastguard Worker 	__type(value, union combined_alloc_info);
37*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, COMBINED_ALLOCS_MAX_ENTRIES);
38*387f9dfdSAndroid Build Coastguard Worker } combined_allocs SEC(".maps");
39*387f9dfdSAndroid Build Coastguard Worker 
40*387f9dfdSAndroid Build Coastguard Worker struct {
41*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
42*387f9dfdSAndroid Build Coastguard Worker 	__type(key, u64);
43*387f9dfdSAndroid Build Coastguard Worker 	__type(value, u64);
44*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, 10240);
45*387f9dfdSAndroid Build Coastguard Worker } memptrs SEC(".maps");
46*387f9dfdSAndroid Build Coastguard Worker 
47*387f9dfdSAndroid Build Coastguard Worker struct {
48*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_STACK_TRACE);
49*387f9dfdSAndroid Build Coastguard Worker 	__type(key, u32);
50*387f9dfdSAndroid Build Coastguard Worker } stack_traces SEC(".maps");
51*387f9dfdSAndroid Build Coastguard Worker 
52*387f9dfdSAndroid Build Coastguard Worker static union combined_alloc_info initial_cinfo;
53*387f9dfdSAndroid Build Coastguard Worker 
update_statistics_add(u64 stack_id,u64 sz)54*387f9dfdSAndroid Build Coastguard Worker static void update_statistics_add(u64 stack_id, u64 sz)
55*387f9dfdSAndroid Build Coastguard Worker {
56*387f9dfdSAndroid Build Coastguard Worker 	union combined_alloc_info *existing_cinfo;
57*387f9dfdSAndroid Build Coastguard Worker 
58*387f9dfdSAndroid Build Coastguard Worker 	existing_cinfo = bpf_map_lookup_or_try_init(&combined_allocs, &stack_id, &initial_cinfo);
59*387f9dfdSAndroid Build Coastguard Worker 	if (!existing_cinfo)
60*387f9dfdSAndroid Build Coastguard Worker 		return;
61*387f9dfdSAndroid Build Coastguard Worker 
62*387f9dfdSAndroid Build Coastguard Worker 	const union combined_alloc_info incremental_cinfo = {
63*387f9dfdSAndroid Build Coastguard Worker 		.total_size = sz,
64*387f9dfdSAndroid Build Coastguard Worker 		.number_of_allocs = 1
65*387f9dfdSAndroid Build Coastguard Worker 	};
66*387f9dfdSAndroid Build Coastguard Worker 
67*387f9dfdSAndroid Build Coastguard Worker 	__sync_fetch_and_add(&existing_cinfo->bits, incremental_cinfo.bits);
68*387f9dfdSAndroid Build Coastguard Worker }
69*387f9dfdSAndroid Build Coastguard Worker 
update_statistics_del(u64 stack_id,u64 sz)70*387f9dfdSAndroid Build Coastguard Worker static void update_statistics_del(u64 stack_id, u64 sz)
71*387f9dfdSAndroid Build Coastguard Worker {
72*387f9dfdSAndroid Build Coastguard Worker 	union combined_alloc_info *existing_cinfo;
73*387f9dfdSAndroid Build Coastguard Worker 
74*387f9dfdSAndroid Build Coastguard Worker 	existing_cinfo = bpf_map_lookup_elem(&combined_allocs, &stack_id);
75*387f9dfdSAndroid Build Coastguard Worker 	if (!existing_cinfo) {
76*387f9dfdSAndroid Build Coastguard Worker 		bpf_printk("failed to lookup combined allocs\n");
77*387f9dfdSAndroid Build Coastguard Worker 
78*387f9dfdSAndroid Build Coastguard Worker 		return;
79*387f9dfdSAndroid Build Coastguard Worker 	}
80*387f9dfdSAndroid Build Coastguard Worker 
81*387f9dfdSAndroid Build Coastguard Worker 	const union combined_alloc_info decremental_cinfo = {
82*387f9dfdSAndroid Build Coastguard Worker 		.total_size = sz,
83*387f9dfdSAndroid Build Coastguard Worker 		.number_of_allocs = 1
84*387f9dfdSAndroid Build Coastguard Worker 	};
85*387f9dfdSAndroid Build Coastguard Worker 
86*387f9dfdSAndroid Build Coastguard Worker 	__sync_fetch_and_sub(&existing_cinfo->bits, decremental_cinfo.bits);
87*387f9dfdSAndroid Build Coastguard Worker }
88*387f9dfdSAndroid Build Coastguard Worker 
gen_alloc_enter(size_t size)89*387f9dfdSAndroid Build Coastguard Worker static int gen_alloc_enter(size_t size)
90*387f9dfdSAndroid Build Coastguard Worker {
91*387f9dfdSAndroid Build Coastguard Worker 	if (size < min_size || size > max_size)
92*387f9dfdSAndroid Build Coastguard Worker 		return 0;
93*387f9dfdSAndroid Build Coastguard Worker 
94*387f9dfdSAndroid Build Coastguard Worker 	if (sample_rate > 1) {
95*387f9dfdSAndroid Build Coastguard Worker 		if (bpf_ktime_get_ns() % sample_rate != 0)
96*387f9dfdSAndroid Build Coastguard Worker 			return 0;
97*387f9dfdSAndroid Build Coastguard Worker 	}
98*387f9dfdSAndroid Build Coastguard Worker 
99*387f9dfdSAndroid Build Coastguard Worker 	const u32 tid = bpf_get_current_pid_tgid();
100*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_update_elem(&sizes, &tid, &size, BPF_ANY);
101*387f9dfdSAndroid Build Coastguard Worker 
102*387f9dfdSAndroid Build Coastguard Worker 	if (trace_all)
103*387f9dfdSAndroid Build Coastguard Worker 		bpf_printk("alloc entered, size = %lu\n", size);
104*387f9dfdSAndroid Build Coastguard Worker 
105*387f9dfdSAndroid Build Coastguard Worker 	return 0;
106*387f9dfdSAndroid Build Coastguard Worker }
107*387f9dfdSAndroid Build Coastguard Worker 
gen_alloc_exit2(void * ctx,u64 address)108*387f9dfdSAndroid Build Coastguard Worker static int gen_alloc_exit2(void *ctx, u64 address)
109*387f9dfdSAndroid Build Coastguard Worker {
110*387f9dfdSAndroid Build Coastguard Worker 	const u32 tid = bpf_get_current_pid_tgid();
111*387f9dfdSAndroid Build Coastguard Worker 	struct alloc_info info;
112*387f9dfdSAndroid Build Coastguard Worker 
113*387f9dfdSAndroid Build Coastguard Worker 	const u64* size = bpf_map_lookup_elem(&sizes, &tid);
114*387f9dfdSAndroid Build Coastguard Worker 	if (!size)
115*387f9dfdSAndroid Build Coastguard Worker 		return 0; // missed alloc entry
116*387f9dfdSAndroid Build Coastguard Worker 
117*387f9dfdSAndroid Build Coastguard Worker 	__builtin_memset(&info, 0, sizeof(info));
118*387f9dfdSAndroid Build Coastguard Worker 
119*387f9dfdSAndroid Build Coastguard Worker 	info.size = *size;
120*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&sizes, &tid);
121*387f9dfdSAndroid Build Coastguard Worker 
122*387f9dfdSAndroid Build Coastguard Worker 	if (address != 0) {
123*387f9dfdSAndroid Build Coastguard Worker 		info.timestamp_ns = bpf_ktime_get_ns();
124*387f9dfdSAndroid Build Coastguard Worker 
125*387f9dfdSAndroid Build Coastguard Worker 		info.stack_id = bpf_get_stackid(ctx, &stack_traces, stack_flags);
126*387f9dfdSAndroid Build Coastguard Worker 
127*387f9dfdSAndroid Build Coastguard Worker 		bpf_map_update_elem(&allocs, &address, &info, BPF_ANY);
128*387f9dfdSAndroid Build Coastguard Worker 
129*387f9dfdSAndroid Build Coastguard Worker 		update_statistics_add(info.stack_id, info.size);
130*387f9dfdSAndroid Build Coastguard Worker 	}
131*387f9dfdSAndroid Build Coastguard Worker 
132*387f9dfdSAndroid Build Coastguard Worker 	if (trace_all) {
133*387f9dfdSAndroid Build Coastguard Worker 		bpf_printk("alloc exited, size = %lu, result = %lx\n",
134*387f9dfdSAndroid Build Coastguard Worker 				info.size, address);
135*387f9dfdSAndroid Build Coastguard Worker 	}
136*387f9dfdSAndroid Build Coastguard Worker 
137*387f9dfdSAndroid Build Coastguard Worker 	return 0;
138*387f9dfdSAndroid Build Coastguard Worker }
139*387f9dfdSAndroid Build Coastguard Worker 
gen_alloc_exit(struct pt_regs * ctx)140*387f9dfdSAndroid Build Coastguard Worker static int gen_alloc_exit(struct pt_regs *ctx)
141*387f9dfdSAndroid Build Coastguard Worker {
142*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit2(ctx, PT_REGS_RC(ctx));
143*387f9dfdSAndroid Build Coastguard Worker }
144*387f9dfdSAndroid Build Coastguard Worker 
gen_free_enter(const void * address)145*387f9dfdSAndroid Build Coastguard Worker static int gen_free_enter(const void *address)
146*387f9dfdSAndroid Build Coastguard Worker {
147*387f9dfdSAndroid Build Coastguard Worker 	const u64 addr = (u64)address;
148*387f9dfdSAndroid Build Coastguard Worker 
149*387f9dfdSAndroid Build Coastguard Worker 	const struct alloc_info *info = bpf_map_lookup_elem(&allocs, &addr);
150*387f9dfdSAndroid Build Coastguard Worker 	if (!info)
151*387f9dfdSAndroid Build Coastguard Worker 		return 0;
152*387f9dfdSAndroid Build Coastguard Worker 
153*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&allocs, &addr);
154*387f9dfdSAndroid Build Coastguard Worker 	update_statistics_del(info->stack_id, info->size);
155*387f9dfdSAndroid Build Coastguard Worker 
156*387f9dfdSAndroid Build Coastguard Worker 	if (trace_all) {
157*387f9dfdSAndroid Build Coastguard Worker 		bpf_printk("free entered, address = %lx, size = %lu\n",
158*387f9dfdSAndroid Build Coastguard Worker 				address, info->size);
159*387f9dfdSAndroid Build Coastguard Worker 	}
160*387f9dfdSAndroid Build Coastguard Worker 
161*387f9dfdSAndroid Build Coastguard Worker 	return 0;
162*387f9dfdSAndroid Build Coastguard Worker }
163*387f9dfdSAndroid Build Coastguard Worker 
164*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(malloc_enter,size_t size)165*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(malloc_enter, size_t size)
166*387f9dfdSAndroid Build Coastguard Worker {
167*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(size);
168*387f9dfdSAndroid Build Coastguard Worker }
169*387f9dfdSAndroid Build Coastguard Worker 
170*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(malloc_exit)171*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(malloc_exit)
172*387f9dfdSAndroid Build Coastguard Worker {
173*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit(ctx);
174*387f9dfdSAndroid Build Coastguard Worker }
175*387f9dfdSAndroid Build Coastguard Worker 
176*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(free_enter,void * address)177*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(free_enter, void *address)
178*387f9dfdSAndroid Build Coastguard Worker {
179*387f9dfdSAndroid Build Coastguard Worker 	return gen_free_enter(address);
180*387f9dfdSAndroid Build Coastguard Worker }
181*387f9dfdSAndroid Build Coastguard Worker 
182*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(calloc_enter,size_t nmemb,size_t size)183*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(calloc_enter, size_t nmemb, size_t size)
184*387f9dfdSAndroid Build Coastguard Worker {
185*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(nmemb * size);
186*387f9dfdSAndroid Build Coastguard Worker }
187*387f9dfdSAndroid Build Coastguard Worker 
188*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(calloc_exit)189*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(calloc_exit)
190*387f9dfdSAndroid Build Coastguard Worker {
191*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit(ctx);
192*387f9dfdSAndroid Build Coastguard Worker }
193*387f9dfdSAndroid Build Coastguard Worker 
194*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(realloc_enter,void * ptr,size_t size)195*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(realloc_enter, void *ptr, size_t size)
196*387f9dfdSAndroid Build Coastguard Worker {
197*387f9dfdSAndroid Build Coastguard Worker 	gen_free_enter(ptr);
198*387f9dfdSAndroid Build Coastguard Worker 
199*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(size);
200*387f9dfdSAndroid Build Coastguard Worker }
201*387f9dfdSAndroid Build Coastguard Worker 
202*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(realloc_exit)203*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(realloc_exit)
204*387f9dfdSAndroid Build Coastguard Worker {
205*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit(ctx);
206*387f9dfdSAndroid Build Coastguard Worker }
207*387f9dfdSAndroid Build Coastguard Worker 
208*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(mmap_enter,void * address,size_t size)209*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(mmap_enter, void *address, size_t size)
210*387f9dfdSAndroid Build Coastguard Worker {
211*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(size);
212*387f9dfdSAndroid Build Coastguard Worker }
213*387f9dfdSAndroid Build Coastguard Worker 
214*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(mmap_exit)215*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(mmap_exit)
216*387f9dfdSAndroid Build Coastguard Worker {
217*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit(ctx);
218*387f9dfdSAndroid Build Coastguard Worker }
219*387f9dfdSAndroid Build Coastguard Worker 
220*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(munmap_enter,void * address)221*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(munmap_enter, void *address)
222*387f9dfdSAndroid Build Coastguard Worker {
223*387f9dfdSAndroid Build Coastguard Worker 	return gen_free_enter(address);
224*387f9dfdSAndroid Build Coastguard Worker }
225*387f9dfdSAndroid Build Coastguard Worker 
226*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(posix_memalign_enter,void ** memptr,size_t alignment,size_t size)227*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(posix_memalign_enter, void **memptr, size_t alignment, size_t size)
228*387f9dfdSAndroid Build Coastguard Worker {
229*387f9dfdSAndroid Build Coastguard Worker 	const u64 memptr64 = (u64)(size_t)memptr;
230*387f9dfdSAndroid Build Coastguard Worker 	const u32 tid = bpf_get_current_pid_tgid();
231*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_update_elem(&memptrs, &tid, &memptr64, BPF_ANY);
232*387f9dfdSAndroid Build Coastguard Worker 
233*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(size);
234*387f9dfdSAndroid Build Coastguard Worker }
235*387f9dfdSAndroid Build Coastguard Worker 
236*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(posix_memalign_exit)237*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(posix_memalign_exit)
238*387f9dfdSAndroid Build Coastguard Worker {
239*387f9dfdSAndroid Build Coastguard Worker 	u64 *memptr64;
240*387f9dfdSAndroid Build Coastguard Worker 	void *addr;
241*387f9dfdSAndroid Build Coastguard Worker 	const u32 tid = bpf_get_current_pid_tgid();
242*387f9dfdSAndroid Build Coastguard Worker 
243*387f9dfdSAndroid Build Coastguard Worker 	memptr64 = bpf_map_lookup_elem(&memptrs, &tid);
244*387f9dfdSAndroid Build Coastguard Worker 	if (!memptr64)
245*387f9dfdSAndroid Build Coastguard Worker 		return 0;
246*387f9dfdSAndroid Build Coastguard Worker 
247*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&memptrs, &tid);
248*387f9dfdSAndroid Build Coastguard Worker 
249*387f9dfdSAndroid Build Coastguard Worker 	if (bpf_probe_read_user(&addr, sizeof(void*), (void*)(size_t)*memptr64))
250*387f9dfdSAndroid Build Coastguard Worker 		return 0;
251*387f9dfdSAndroid Build Coastguard Worker 
252*387f9dfdSAndroid Build Coastguard Worker 	const u64 addr64 = (u64)(size_t)addr;
253*387f9dfdSAndroid Build Coastguard Worker 
254*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit2(ctx, addr64);
255*387f9dfdSAndroid Build Coastguard Worker }
256*387f9dfdSAndroid Build Coastguard Worker 
257*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(aligned_alloc_enter,size_t alignment,size_t size)258*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(aligned_alloc_enter, size_t alignment, size_t size)
259*387f9dfdSAndroid Build Coastguard Worker {
260*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(size);
261*387f9dfdSAndroid Build Coastguard Worker }
262*387f9dfdSAndroid Build Coastguard Worker 
263*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(aligned_alloc_exit)264*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(aligned_alloc_exit)
265*387f9dfdSAndroid Build Coastguard Worker {
266*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit(ctx);
267*387f9dfdSAndroid Build Coastguard Worker }
268*387f9dfdSAndroid Build Coastguard Worker 
269*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(valloc_enter,size_t size)270*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(valloc_enter, size_t size)
271*387f9dfdSAndroid Build Coastguard Worker {
272*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(size);
273*387f9dfdSAndroid Build Coastguard Worker }
274*387f9dfdSAndroid Build Coastguard Worker 
275*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(valloc_exit)276*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(valloc_exit)
277*387f9dfdSAndroid Build Coastguard Worker {
278*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit(ctx);
279*387f9dfdSAndroid Build Coastguard Worker }
280*387f9dfdSAndroid Build Coastguard Worker 
281*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(memalign_enter,size_t alignment,size_t size)282*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(memalign_enter, size_t alignment, size_t size)
283*387f9dfdSAndroid Build Coastguard Worker {
284*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(size);
285*387f9dfdSAndroid Build Coastguard Worker }
286*387f9dfdSAndroid Build Coastguard Worker 
287*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(memalign_exit)288*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(memalign_exit)
289*387f9dfdSAndroid Build Coastguard Worker {
290*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit(ctx);
291*387f9dfdSAndroid Build Coastguard Worker }
292*387f9dfdSAndroid Build Coastguard Worker 
293*387f9dfdSAndroid Build Coastguard Worker SEC("uprobe")
BPF_KPROBE(pvalloc_enter,size_t size)294*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(pvalloc_enter, size_t size)
295*387f9dfdSAndroid Build Coastguard Worker {
296*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_enter(size);
297*387f9dfdSAndroid Build Coastguard Worker }
298*387f9dfdSAndroid Build Coastguard Worker 
299*387f9dfdSAndroid Build Coastguard Worker SEC("uretprobe")
BPF_KRETPROBE(pvalloc_exit)300*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(pvalloc_exit)
301*387f9dfdSAndroid Build Coastguard Worker {
302*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit(ctx);
303*387f9dfdSAndroid Build Coastguard Worker }
304*387f9dfdSAndroid Build Coastguard Worker 
305*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/kmem/kmalloc")
memleak__kmalloc(void * ctx)306*387f9dfdSAndroid Build Coastguard Worker int memleak__kmalloc(void *ctx)
307*387f9dfdSAndroid Build Coastguard Worker {
308*387f9dfdSAndroid Build Coastguard Worker 	const void *ptr;
309*387f9dfdSAndroid Build Coastguard Worker 	size_t bytes_alloc;
310*387f9dfdSAndroid Build Coastguard Worker 
311*387f9dfdSAndroid Build Coastguard Worker 	if (has_kmem_alloc()) {
312*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmem_alloc___x *args = ctx;
313*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
314*387f9dfdSAndroid Build Coastguard Worker 		bytes_alloc = BPF_CORE_READ(args, bytes_alloc);
315*387f9dfdSAndroid Build Coastguard Worker 	} else {
316*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmalloc___x *args = ctx;
317*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
318*387f9dfdSAndroid Build Coastguard Worker 		bytes_alloc = BPF_CORE_READ(args, bytes_alloc);
319*387f9dfdSAndroid Build Coastguard Worker 	}
320*387f9dfdSAndroid Build Coastguard Worker 
321*387f9dfdSAndroid Build Coastguard Worker 	if (wa_missing_free)
322*387f9dfdSAndroid Build Coastguard Worker 		gen_free_enter(ptr);
323*387f9dfdSAndroid Build Coastguard Worker 
324*387f9dfdSAndroid Build Coastguard Worker 	gen_alloc_enter(bytes_alloc);
325*387f9dfdSAndroid Build Coastguard Worker 
326*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit2(ctx, (u64)ptr);
327*387f9dfdSAndroid Build Coastguard Worker }
328*387f9dfdSAndroid Build Coastguard Worker 
329*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/kmem/kmalloc_node")
memleak__kmalloc_node(void * ctx)330*387f9dfdSAndroid Build Coastguard Worker int memleak__kmalloc_node(void *ctx)
331*387f9dfdSAndroid Build Coastguard Worker {
332*387f9dfdSAndroid Build Coastguard Worker 	const void *ptr;
333*387f9dfdSAndroid Build Coastguard Worker 	size_t bytes_alloc;
334*387f9dfdSAndroid Build Coastguard Worker 
335*387f9dfdSAndroid Build Coastguard Worker 	if (has_kmem_alloc_node()) {
336*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmem_alloc_node___x *args = ctx;
337*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
338*387f9dfdSAndroid Build Coastguard Worker 		bytes_alloc = BPF_CORE_READ(args, bytes_alloc);
339*387f9dfdSAndroid Build Coastguard Worker 
340*387f9dfdSAndroid Build Coastguard Worker 		if (wa_missing_free)
341*387f9dfdSAndroid Build Coastguard Worker 			gen_free_enter(ptr);
342*387f9dfdSAndroid Build Coastguard Worker 
343*387f9dfdSAndroid Build Coastguard Worker 		gen_alloc_enter( bytes_alloc);
344*387f9dfdSAndroid Build Coastguard Worker 
345*387f9dfdSAndroid Build Coastguard Worker 		return gen_alloc_exit2(ctx, (u64)ptr);
346*387f9dfdSAndroid Build Coastguard Worker 	} else {
347*387f9dfdSAndroid Build Coastguard Worker 		/* tracepoint is disabled if not exist, avoid compile warning */
348*387f9dfdSAndroid Build Coastguard Worker 		return 0;
349*387f9dfdSAndroid Build Coastguard Worker 	}
350*387f9dfdSAndroid Build Coastguard Worker }
351*387f9dfdSAndroid Build Coastguard Worker 
352*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/kmem/kfree")
memleak__kfree(void * ctx)353*387f9dfdSAndroid Build Coastguard Worker int memleak__kfree(void *ctx)
354*387f9dfdSAndroid Build Coastguard Worker {
355*387f9dfdSAndroid Build Coastguard Worker 	const void *ptr;
356*387f9dfdSAndroid Build Coastguard Worker 
357*387f9dfdSAndroid Build Coastguard Worker 	if (has_kfree()) {
358*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kfree___x *args = ctx;
359*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
360*387f9dfdSAndroid Build Coastguard Worker 	} else {
361*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmem_free___x *args = ctx;
362*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
363*387f9dfdSAndroid Build Coastguard Worker 	}
364*387f9dfdSAndroid Build Coastguard Worker 
365*387f9dfdSAndroid Build Coastguard Worker 	return gen_free_enter(ptr);
366*387f9dfdSAndroid Build Coastguard Worker }
367*387f9dfdSAndroid Build Coastguard Worker 
368*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/kmem/kmem_cache_alloc")
memleak__kmem_cache_alloc(void * ctx)369*387f9dfdSAndroid Build Coastguard Worker int memleak__kmem_cache_alloc(void *ctx)
370*387f9dfdSAndroid Build Coastguard Worker {
371*387f9dfdSAndroid Build Coastguard Worker 	const void *ptr;
372*387f9dfdSAndroid Build Coastguard Worker 	size_t bytes_alloc;
373*387f9dfdSAndroid Build Coastguard Worker 
374*387f9dfdSAndroid Build Coastguard Worker 	if (has_kmem_alloc()) {
375*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmem_alloc___x *args = ctx;
376*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
377*387f9dfdSAndroid Build Coastguard Worker 		bytes_alloc = BPF_CORE_READ(args, bytes_alloc);
378*387f9dfdSAndroid Build Coastguard Worker 	} else {
379*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmem_cache_alloc___x *args = ctx;
380*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
381*387f9dfdSAndroid Build Coastguard Worker 		bytes_alloc = BPF_CORE_READ(args, bytes_alloc);
382*387f9dfdSAndroid Build Coastguard Worker 	}
383*387f9dfdSAndroid Build Coastguard Worker 
384*387f9dfdSAndroid Build Coastguard Worker 	if (wa_missing_free)
385*387f9dfdSAndroid Build Coastguard Worker 		gen_free_enter(ptr);
386*387f9dfdSAndroid Build Coastguard Worker 
387*387f9dfdSAndroid Build Coastguard Worker 	gen_alloc_enter(bytes_alloc);
388*387f9dfdSAndroid Build Coastguard Worker 
389*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit2(ctx, (u64)ptr);
390*387f9dfdSAndroid Build Coastguard Worker }
391*387f9dfdSAndroid Build Coastguard Worker 
392*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/kmem/kmem_cache_alloc_node")
memleak__kmem_cache_alloc_node(void * ctx)393*387f9dfdSAndroid Build Coastguard Worker int memleak__kmem_cache_alloc_node(void *ctx)
394*387f9dfdSAndroid Build Coastguard Worker {
395*387f9dfdSAndroid Build Coastguard Worker 	const void *ptr;
396*387f9dfdSAndroid Build Coastguard Worker 	size_t bytes_alloc;
397*387f9dfdSAndroid Build Coastguard Worker 
398*387f9dfdSAndroid Build Coastguard Worker 	if (has_kmem_alloc_node()) {
399*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmem_alloc_node___x *args = ctx;
400*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
401*387f9dfdSAndroid Build Coastguard Worker 		bytes_alloc = BPF_CORE_READ(args, bytes_alloc);
402*387f9dfdSAndroid Build Coastguard Worker 
403*387f9dfdSAndroid Build Coastguard Worker 		if (wa_missing_free)
404*387f9dfdSAndroid Build Coastguard Worker 			gen_free_enter(ptr);
405*387f9dfdSAndroid Build Coastguard Worker 
406*387f9dfdSAndroid Build Coastguard Worker 		gen_alloc_enter(bytes_alloc);
407*387f9dfdSAndroid Build Coastguard Worker 
408*387f9dfdSAndroid Build Coastguard Worker 		return gen_alloc_exit2(ctx, (u64)ptr);
409*387f9dfdSAndroid Build Coastguard Worker 	} else {
410*387f9dfdSAndroid Build Coastguard Worker 		/* tracepoint is disabled if not exist, avoid compile warning */
411*387f9dfdSAndroid Build Coastguard Worker 		return 0;
412*387f9dfdSAndroid Build Coastguard Worker 	}
413*387f9dfdSAndroid Build Coastguard Worker }
414*387f9dfdSAndroid Build Coastguard Worker 
415*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/kmem/kmem_cache_free")
memleak__kmem_cache_free(void * ctx)416*387f9dfdSAndroid Build Coastguard Worker int memleak__kmem_cache_free(void *ctx)
417*387f9dfdSAndroid Build Coastguard Worker {
418*387f9dfdSAndroid Build Coastguard Worker 	const void *ptr;
419*387f9dfdSAndroid Build Coastguard Worker 
420*387f9dfdSAndroid Build Coastguard Worker 	if (has_kmem_cache_free()) {
421*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmem_cache_free___x *args = ctx;
422*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
423*387f9dfdSAndroid Build Coastguard Worker 	} else {
424*387f9dfdSAndroid Build Coastguard Worker 		struct trace_event_raw_kmem_free___x *args = ctx;
425*387f9dfdSAndroid Build Coastguard Worker 		ptr = BPF_CORE_READ(args, ptr);
426*387f9dfdSAndroid Build Coastguard Worker 	}
427*387f9dfdSAndroid Build Coastguard Worker 
428*387f9dfdSAndroid Build Coastguard Worker 	return gen_free_enter(ptr);
429*387f9dfdSAndroid Build Coastguard Worker }
430*387f9dfdSAndroid Build Coastguard Worker 
431*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/kmem/mm_page_alloc")
memleak__mm_page_alloc(struct trace_event_raw_mm_page_alloc * ctx)432*387f9dfdSAndroid Build Coastguard Worker int memleak__mm_page_alloc(struct trace_event_raw_mm_page_alloc *ctx)
433*387f9dfdSAndroid Build Coastguard Worker {
434*387f9dfdSAndroid Build Coastguard Worker 	gen_alloc_enter(page_size << ctx->order);
435*387f9dfdSAndroid Build Coastguard Worker 
436*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit2(ctx, ctx->pfn);
437*387f9dfdSAndroid Build Coastguard Worker }
438*387f9dfdSAndroid Build Coastguard Worker 
439*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/kmem/mm_page_free")
memleak__mm_page_free(struct trace_event_raw_mm_page_free * ctx)440*387f9dfdSAndroid Build Coastguard Worker int memleak__mm_page_free(struct trace_event_raw_mm_page_free *ctx)
441*387f9dfdSAndroid Build Coastguard Worker {
442*387f9dfdSAndroid Build Coastguard Worker 	return gen_free_enter((void *)ctx->pfn);
443*387f9dfdSAndroid Build Coastguard Worker }
444*387f9dfdSAndroid Build Coastguard Worker 
445*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/percpu/percpu_alloc_percpu")
memleak__percpu_alloc_percpu(struct trace_event_raw_percpu_alloc_percpu * ctx)446*387f9dfdSAndroid Build Coastguard Worker int memleak__percpu_alloc_percpu(struct trace_event_raw_percpu_alloc_percpu *ctx)
447*387f9dfdSAndroid Build Coastguard Worker {
448*387f9dfdSAndroid Build Coastguard Worker 	gen_alloc_enter(ctx->bytes_alloc);
449*387f9dfdSAndroid Build Coastguard Worker 
450*387f9dfdSAndroid Build Coastguard Worker 	return gen_alloc_exit2(ctx, (u64)(ctx->ptr));
451*387f9dfdSAndroid Build Coastguard Worker }
452*387f9dfdSAndroid Build Coastguard Worker 
453*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/percpu/percpu_free_percpu")
memleak__percpu_free_percpu(struct trace_event_raw_percpu_free_percpu * ctx)454*387f9dfdSAndroid Build Coastguard Worker int memleak__percpu_free_percpu(struct trace_event_raw_percpu_free_percpu *ctx)
455*387f9dfdSAndroid Build Coastguard Worker {
456*387f9dfdSAndroid Build Coastguard Worker 	return gen_free_enter(ctx->ptr);
457*387f9dfdSAndroid Build Coastguard Worker }
458*387f9dfdSAndroid Build Coastguard Worker 
459*387f9dfdSAndroid Build Coastguard Worker char LICENSE[] SEC("license") = "GPL";
460