1*387f9dfdSAndroid Build Coastguard Worker /*
2*387f9dfdSAndroid Build Coastguard Worker * Copyright (c) Facebook, Inc.
3*387f9dfdSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License")
4*387f9dfdSAndroid Build Coastguard Worker *
5*387f9dfdSAndroid Build Coastguard Worker * Usage:
6*387f9dfdSAndroid Build Coastguard Worker * ./KFunc
7*387f9dfdSAndroid Build Coastguard Worker * A sample output:
8*387f9dfdSAndroid Build Coastguard Worker * Started tracing, hit Ctrl-C to terminate.
9*387f9dfdSAndroid Build Coastguard Worker * FD FNAME
10*387f9dfdSAndroid Build Coastguard Worker * NONE /proc/stat
11*387f9dfdSAndroid Build Coastguard Worker * 87 /proc/stat
12*387f9dfdSAndroid Build Coastguard Worker * NONE /proc/8208/status
13*387f9dfdSAndroid Build Coastguard Worker * 36 /proc/8208/status
14*387f9dfdSAndroid Build Coastguard Worker * NONE /proc/8208/status
15*387f9dfdSAndroid Build Coastguard Worker * 36 /proc/8208/status
16*387f9dfdSAndroid Build Coastguard Worker * ...
17*387f9dfdSAndroid Build Coastguard Worker *
18*387f9dfdSAndroid Build Coastguard Worker * KFunc support is only available at kernel version 5.5 and later.
19*387f9dfdSAndroid Build Coastguard Worker * This example only works for x64.
20*387f9dfdSAndroid Build Coastguard Worker */
21*387f9dfdSAndroid Build Coastguard Worker
22*387f9dfdSAndroid Build Coastguard Worker #include <fstream>
23*387f9dfdSAndroid Build Coastguard Worker #include <iostream>
24*387f9dfdSAndroid Build Coastguard Worker #include <iomanip>
25*387f9dfdSAndroid Build Coastguard Worker #include <string>
26*387f9dfdSAndroid Build Coastguard Worker
27*387f9dfdSAndroid Build Coastguard Worker #include "bcc_version.h"
28*387f9dfdSAndroid Build Coastguard Worker #include "BPF.h"
29*387f9dfdSAndroid Build Coastguard Worker
30*387f9dfdSAndroid Build Coastguard Worker const std::string BPF_PROGRAM = R"(
31*387f9dfdSAndroid Build Coastguard Worker #include <linux/ptrace.h>
32*387f9dfdSAndroid Build Coastguard Worker
33*387f9dfdSAndroid Build Coastguard Worker struct info_t {
34*387f9dfdSAndroid Build Coastguard Worker char name[64];
35*387f9dfdSAndroid Build Coastguard Worker int fd;
36*387f9dfdSAndroid Build Coastguard Worker int is_ret;
37*387f9dfdSAndroid Build Coastguard Worker };
38*387f9dfdSAndroid Build Coastguard Worker BPF_PERF_OUTPUT(events);
39*387f9dfdSAndroid Build Coastguard Worker
40*387f9dfdSAndroid Build Coastguard Worker KFUNC_PROBE(__x64_sys_openat, struct pt_regs *regs)
41*387f9dfdSAndroid Build Coastguard Worker {
42*387f9dfdSAndroid Build Coastguard Worker const char __user *filename = (char *)PT_REGS_PARM2(regs);
43*387f9dfdSAndroid Build Coastguard Worker struct info_t info = {};
44*387f9dfdSAndroid Build Coastguard Worker
45*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_user_str(info.name, sizeof(info.name), filename);
46*387f9dfdSAndroid Build Coastguard Worker info.is_ret = 0;
47*387f9dfdSAndroid Build Coastguard Worker events.perf_submit(ctx, &info, sizeof(info));
48*387f9dfdSAndroid Build Coastguard Worker return 0;
49*387f9dfdSAndroid Build Coastguard Worker }
50*387f9dfdSAndroid Build Coastguard Worker
51*387f9dfdSAndroid Build Coastguard Worker KRETFUNC_PROBE(__x64_sys_openat, struct pt_regs *regs, int ret)
52*387f9dfdSAndroid Build Coastguard Worker {
53*387f9dfdSAndroid Build Coastguard Worker const char __user *filename = (char *)PT_REGS_PARM2(regs);
54*387f9dfdSAndroid Build Coastguard Worker struct info_t info = {};
55*387f9dfdSAndroid Build Coastguard Worker
56*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_user_str(info.name, sizeof(info.name), filename);
57*387f9dfdSAndroid Build Coastguard Worker info.fd = ret;
58*387f9dfdSAndroid Build Coastguard Worker info.is_ret = 1;
59*387f9dfdSAndroid Build Coastguard Worker events.perf_submit(ctx, &info, sizeof(info));
60*387f9dfdSAndroid Build Coastguard Worker return 0;
61*387f9dfdSAndroid Build Coastguard Worker }
62*387f9dfdSAndroid Build Coastguard Worker )";
63*387f9dfdSAndroid Build Coastguard Worker
64*387f9dfdSAndroid Build Coastguard Worker struct info_t {
65*387f9dfdSAndroid Build Coastguard Worker char name[64];
66*387f9dfdSAndroid Build Coastguard Worker int fd;
67*387f9dfdSAndroid Build Coastguard Worker int is_ret;
68*387f9dfdSAndroid Build Coastguard Worker };
69*387f9dfdSAndroid Build Coastguard Worker
handle_output(void * cb_cookie,void * data,int data_size)70*387f9dfdSAndroid Build Coastguard Worker void handle_output(void *cb_cookie, void *data, int data_size) {
71*387f9dfdSAndroid Build Coastguard Worker auto info = static_cast<info_t *>(data);
72*387f9dfdSAndroid Build Coastguard Worker if (info->is_ret)
73*387f9dfdSAndroid Build Coastguard Worker std::cout << std::setw(5) << info->fd << " " << info->name << std::endl;
74*387f9dfdSAndroid Build Coastguard Worker else
75*387f9dfdSAndroid Build Coastguard Worker std::cout << " NONE " << info->name << std::endl;
76*387f9dfdSAndroid Build Coastguard Worker }
77*387f9dfdSAndroid Build Coastguard Worker
main()78*387f9dfdSAndroid Build Coastguard Worker int main() {
79*387f9dfdSAndroid Build Coastguard Worker ebpf::BPF bpf;
80*387f9dfdSAndroid Build Coastguard Worker auto res = bpf.init(BPF_PROGRAM);
81*387f9dfdSAndroid Build Coastguard Worker if (!res.ok()) {
82*387f9dfdSAndroid Build Coastguard Worker std::cerr << res.msg() << std::endl;
83*387f9dfdSAndroid Build Coastguard Worker return 1;
84*387f9dfdSAndroid Build Coastguard Worker }
85*387f9dfdSAndroid Build Coastguard Worker
86*387f9dfdSAndroid Build Coastguard Worker int prog_fd;
87*387f9dfdSAndroid Build Coastguard Worker res = bpf.load_func("kfunc____x64_sys_openat", BPF_PROG_TYPE_TRACING, prog_fd);
88*387f9dfdSAndroid Build Coastguard Worker if (!res.ok()) {
89*387f9dfdSAndroid Build Coastguard Worker std::cerr << res.msg() << std::endl;
90*387f9dfdSAndroid Build Coastguard Worker return 1;
91*387f9dfdSAndroid Build Coastguard Worker }
92*387f9dfdSAndroid Build Coastguard Worker
93*387f9dfdSAndroid Build Coastguard Worker int ret = bpf_attach_kfunc(prog_fd);
94*387f9dfdSAndroid Build Coastguard Worker if (ret < 0) {
95*387f9dfdSAndroid Build Coastguard Worker std::cerr << "bpf_attach_kfunc failed: " << ret << std::endl;
96*387f9dfdSAndroid Build Coastguard Worker return 1;
97*387f9dfdSAndroid Build Coastguard Worker }
98*387f9dfdSAndroid Build Coastguard Worker
99*387f9dfdSAndroid Build Coastguard Worker res = bpf.load_func("kretfunc____x64_sys_openat", BPF_PROG_TYPE_TRACING, prog_fd);
100*387f9dfdSAndroid Build Coastguard Worker if (!res.ok()) {
101*387f9dfdSAndroid Build Coastguard Worker std::cerr << res.msg() << std::endl;
102*387f9dfdSAndroid Build Coastguard Worker return 1;
103*387f9dfdSAndroid Build Coastguard Worker }
104*387f9dfdSAndroid Build Coastguard Worker
105*387f9dfdSAndroid Build Coastguard Worker ret = bpf_attach_kfunc(prog_fd);
106*387f9dfdSAndroid Build Coastguard Worker if (ret < 0) {
107*387f9dfdSAndroid Build Coastguard Worker std::cerr << "bpf_attach_kfunc failed: " << ret << std::endl;
108*387f9dfdSAndroid Build Coastguard Worker return 1;
109*387f9dfdSAndroid Build Coastguard Worker }
110*387f9dfdSAndroid Build Coastguard Worker
111*387f9dfdSAndroid Build Coastguard Worker auto open_res = bpf.open_perf_buffer("events", &handle_output);
112*387f9dfdSAndroid Build Coastguard Worker if (!open_res.ok()) {
113*387f9dfdSAndroid Build Coastguard Worker std::cerr << open_res.msg() << std::endl;
114*387f9dfdSAndroid Build Coastguard Worker return 1;
115*387f9dfdSAndroid Build Coastguard Worker }
116*387f9dfdSAndroid Build Coastguard Worker
117*387f9dfdSAndroid Build Coastguard Worker std::cout << "Started tracing, hit Ctrl-C to terminate." << std::endl;
118*387f9dfdSAndroid Build Coastguard Worker std::cout << " FD FNAME" << std::endl;
119*387f9dfdSAndroid Build Coastguard Worker auto perf_buffer = bpf.get_perf_buffer("events");
120*387f9dfdSAndroid Build Coastguard Worker if (perf_buffer) {
121*387f9dfdSAndroid Build Coastguard Worker while (true)
122*387f9dfdSAndroid Build Coastguard Worker // 100ms timeout
123*387f9dfdSAndroid Build Coastguard Worker perf_buffer->poll(100);
124*387f9dfdSAndroid Build Coastguard Worker }
125*387f9dfdSAndroid Build Coastguard Worker
126*387f9dfdSAndroid Build Coastguard Worker return 0;
127*387f9dfdSAndroid Build Coastguard Worker }
128