xref: /aosp_15_r20/external/bcc/src/cc/api/BPF.h (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker /*
2*387f9dfdSAndroid Build Coastguard Worker  * Copyright (c) 2016 Facebook, Inc.
3*387f9dfdSAndroid Build Coastguard Worker  *
4*387f9dfdSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*387f9dfdSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*387f9dfdSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*387f9dfdSAndroid Build Coastguard Worker  *
8*387f9dfdSAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
9*387f9dfdSAndroid Build Coastguard Worker  *
10*387f9dfdSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*387f9dfdSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*387f9dfdSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*387f9dfdSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*387f9dfdSAndroid Build Coastguard Worker  * limitations under the License.
15*387f9dfdSAndroid Build Coastguard Worker  */
16*387f9dfdSAndroid Build Coastguard Worker 
17*387f9dfdSAndroid Build Coastguard Worker #pragma once
18*387f9dfdSAndroid Build Coastguard Worker 
19*387f9dfdSAndroid Build Coastguard Worker #include <cctype>
20*387f9dfdSAndroid Build Coastguard Worker #include <cstdint>
21*387f9dfdSAndroid Build Coastguard Worker #include <memory>
22*387f9dfdSAndroid Build Coastguard Worker #include <ostream>
23*387f9dfdSAndroid Build Coastguard Worker #include <string>
24*387f9dfdSAndroid Build Coastguard Worker 
25*387f9dfdSAndroid Build Coastguard Worker #include "BPFTable.h"
26*387f9dfdSAndroid Build Coastguard Worker #include "bcc_exception.h"
27*387f9dfdSAndroid Build Coastguard Worker #include "bcc_syms.h"
28*387f9dfdSAndroid Build Coastguard Worker #include "bpf_module.h"
29*387f9dfdSAndroid Build Coastguard Worker #include "linux/bpf.h"
30*387f9dfdSAndroid Build Coastguard Worker #include "libbpf.h"
31*387f9dfdSAndroid Build Coastguard Worker #include "table_storage.h"
32*387f9dfdSAndroid Build Coastguard Worker 
33*387f9dfdSAndroid Build Coastguard Worker static const int DEFAULT_PERF_BUFFER_PAGE_CNT = 8;
34*387f9dfdSAndroid Build Coastguard Worker 
35*387f9dfdSAndroid Build Coastguard Worker namespace ebpf {
36*387f9dfdSAndroid Build Coastguard Worker 
37*387f9dfdSAndroid Build Coastguard Worker struct open_probe_t {
38*387f9dfdSAndroid Build Coastguard Worker   int perf_event_fd;
39*387f9dfdSAndroid Build Coastguard Worker   std::string func;
40*387f9dfdSAndroid Build Coastguard Worker   std::vector<std::pair<int, int>>* per_cpu_fd;
41*387f9dfdSAndroid Build Coastguard Worker };
42*387f9dfdSAndroid Build Coastguard Worker 
43*387f9dfdSAndroid Build Coastguard Worker class BPF;
44*387f9dfdSAndroid Build Coastguard Worker 
45*387f9dfdSAndroid Build Coastguard Worker class USDT {
46*387f9dfdSAndroid Build Coastguard Worker  public:
47*387f9dfdSAndroid Build Coastguard Worker   USDT(const std::string& binary_path, const std::string& provider,
48*387f9dfdSAndroid Build Coastguard Worker        const std::string& name, const std::string& probe_func);
49*387f9dfdSAndroid Build Coastguard Worker   USDT(pid_t pid, const std::string& provider, const std::string& name,
50*387f9dfdSAndroid Build Coastguard Worker        const std::string& probe_func);
51*387f9dfdSAndroid Build Coastguard Worker   USDT(const std::string& binary_path, pid_t pid, const std::string& provider,
52*387f9dfdSAndroid Build Coastguard Worker        const std::string& name, const std::string& probe_func);
53*387f9dfdSAndroid Build Coastguard Worker   USDT(const USDT& usdt);
54*387f9dfdSAndroid Build Coastguard Worker   USDT(USDT&& usdt) noexcept;
55*387f9dfdSAndroid Build Coastguard Worker 
binary_path()56*387f9dfdSAndroid Build Coastguard Worker   const std::string &binary_path() const { return binary_path_; }
pid()57*387f9dfdSAndroid Build Coastguard Worker   pid_t pid() const { return pid_; }
provider()58*387f9dfdSAndroid Build Coastguard Worker   const std::string &provider() const { return provider_; }
name()59*387f9dfdSAndroid Build Coastguard Worker   const std::string &name() const { return name_; }
probe_func()60*387f9dfdSAndroid Build Coastguard Worker   const std::string &probe_func() const { return probe_func_; }
61*387f9dfdSAndroid Build Coastguard Worker 
62*387f9dfdSAndroid Build Coastguard Worker   StatusTuple init();
63*387f9dfdSAndroid Build Coastguard Worker 
64*387f9dfdSAndroid Build Coastguard Worker   bool operator==(const USDT& other) const;
65*387f9dfdSAndroid Build Coastguard Worker 
print_name()66*387f9dfdSAndroid Build Coastguard Worker   std::string print_name() const {
67*387f9dfdSAndroid Build Coastguard Worker     return provider_ + ":" + name_ + " from binary " + binary_path_ + " PID " +
68*387f9dfdSAndroid Build Coastguard Worker            std::to_string(pid_) + " for probe " + probe_func_;
69*387f9dfdSAndroid Build Coastguard Worker   }
70*387f9dfdSAndroid Build Coastguard Worker 
71*387f9dfdSAndroid Build Coastguard Worker   friend std::ostream& operator<<(std::ostream& out, const USDT& usdt) {
72*387f9dfdSAndroid Build Coastguard Worker     return out << usdt.provider_ << ":" << usdt.name_ << " from binary "
73*387f9dfdSAndroid Build Coastguard Worker                << usdt.binary_path_ << " PID " << usdt.pid_ << " for probe "
74*387f9dfdSAndroid Build Coastguard Worker                << usdt.probe_func_;
75*387f9dfdSAndroid Build Coastguard Worker   }
76*387f9dfdSAndroid Build Coastguard Worker 
77*387f9dfdSAndroid Build Coastguard Worker   // When the kludge flag is set to 1 (default), we will only match on inode
78*387f9dfdSAndroid Build Coastguard Worker   // when searching for modules in /proc/PID/maps that might contain the
79*387f9dfdSAndroid Build Coastguard Worker   // tracepoint we're looking for.
80*387f9dfdSAndroid Build Coastguard Worker   // By setting this to 0, we will match on both inode and
81*387f9dfdSAndroid Build Coastguard Worker   // (dev_major, dev_minor), which is a more accurate way to uniquely
82*387f9dfdSAndroid Build Coastguard Worker   // identify a file, but may fail depending on the filesystem backing the
83*387f9dfdSAndroid Build Coastguard Worker   // target file (see bcc#2715)
84*387f9dfdSAndroid Build Coastguard Worker   //
85*387f9dfdSAndroid Build Coastguard Worker   // This hack exists because btrfs and overlayfs report different device
86*387f9dfdSAndroid Build Coastguard Worker   // numbers for files in /proc/PID/maps vs stat syscall. Don't use it unless
87*387f9dfdSAndroid Build Coastguard Worker   // you've had issues with inode collisions. Both btrfs and overlayfs are
88*387f9dfdSAndroid Build Coastguard Worker   // known to require inode-only resolution to accurately match a file.
89*387f9dfdSAndroid Build Coastguard Worker   //
90*387f9dfdSAndroid Build Coastguard Worker   // set_probe_matching_kludge(0) must be called before USDTs are submitted to
91*387f9dfdSAndroid Build Coastguard Worker   // BPF::init()
92*387f9dfdSAndroid Build Coastguard Worker   int set_probe_matching_kludge(uint8_t kludge);
93*387f9dfdSAndroid Build Coastguard Worker 
94*387f9dfdSAndroid Build Coastguard Worker  private:
95*387f9dfdSAndroid Build Coastguard Worker   bool initialized_;
96*387f9dfdSAndroid Build Coastguard Worker 
97*387f9dfdSAndroid Build Coastguard Worker   std::string binary_path_;
98*387f9dfdSAndroid Build Coastguard Worker   pid_t pid_;
99*387f9dfdSAndroid Build Coastguard Worker 
100*387f9dfdSAndroid Build Coastguard Worker   std::string provider_;
101*387f9dfdSAndroid Build Coastguard Worker   std::string name_;
102*387f9dfdSAndroid Build Coastguard Worker   std::string probe_func_;
103*387f9dfdSAndroid Build Coastguard Worker 
104*387f9dfdSAndroid Build Coastguard Worker   std::unique_ptr<void, std::function<void(void*)>> probe_;
105*387f9dfdSAndroid Build Coastguard Worker   std::string program_text_;
106*387f9dfdSAndroid Build Coastguard Worker 
107*387f9dfdSAndroid Build Coastguard Worker   uint8_t mod_match_inode_only_;
108*387f9dfdSAndroid Build Coastguard Worker 
109*387f9dfdSAndroid Build Coastguard Worker   friend class BPF;
110*387f9dfdSAndroid Build Coastguard Worker };
111*387f9dfdSAndroid Build Coastguard Worker 
112*387f9dfdSAndroid Build Coastguard Worker class BPF {
113*387f9dfdSAndroid Build Coastguard Worker  public:
114*387f9dfdSAndroid Build Coastguard Worker   static const int BPF_MAX_STACK_DEPTH = 127;
115*387f9dfdSAndroid Build Coastguard Worker 
116*387f9dfdSAndroid Build Coastguard Worker   explicit BPF(unsigned int flag = 0, TableStorage* ts = nullptr,
117*387f9dfdSAndroid Build Coastguard Worker                bool rw_engine_enabled = bpf_module_rw_engine_enabled(),
118*387f9dfdSAndroid Build Coastguard Worker                const std::string &maps_ns = "",
119*387f9dfdSAndroid Build Coastguard Worker                bool allow_rlimit = true)
flag_(flag)120*387f9dfdSAndroid Build Coastguard Worker       : flag_(flag),
121*387f9dfdSAndroid Build Coastguard Worker         bsymcache_(NULL),
122*387f9dfdSAndroid Build Coastguard Worker         bpf_module_(new BPFModule(flag, ts, rw_engine_enabled, maps_ns,
123*387f9dfdSAndroid Build Coastguard Worker                     allow_rlimit)) {}
124*387f9dfdSAndroid Build Coastguard Worker   StatusTuple init(const std::string& bpf_program,
125*387f9dfdSAndroid Build Coastguard Worker                    const std::vector<std::string>& cflags = {},
126*387f9dfdSAndroid Build Coastguard Worker                    const std::vector<USDT>& usdt = {});
127*387f9dfdSAndroid Build Coastguard Worker 
128*387f9dfdSAndroid Build Coastguard Worker   StatusTuple init_usdt(const USDT& usdt);
129*387f9dfdSAndroid Build Coastguard Worker 
130*387f9dfdSAndroid Build Coastguard Worker   ~BPF();
131*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_all();
132*387f9dfdSAndroid Build Coastguard Worker 
133*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_kprobe(const std::string& kernel_func,
134*387f9dfdSAndroid Build Coastguard Worker                             const std::string& probe_func,
135*387f9dfdSAndroid Build Coastguard Worker                             uint64_t kernel_func_offset = 0,
136*387f9dfdSAndroid Build Coastguard Worker                             bpf_probe_attach_type = BPF_PROBE_ENTRY,
137*387f9dfdSAndroid Build Coastguard Worker                             int maxactive = 0);
138*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_kprobe(
139*387f9dfdSAndroid Build Coastguard Worker       const std::string& kernel_func,
140*387f9dfdSAndroid Build Coastguard Worker       bpf_probe_attach_type attach_type = BPF_PROBE_ENTRY);
141*387f9dfdSAndroid Build Coastguard Worker 
142*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_uprobe(const std::string& binary_path,
143*387f9dfdSAndroid Build Coastguard Worker                             const std::string& symbol,
144*387f9dfdSAndroid Build Coastguard Worker                             const std::string& probe_func,
145*387f9dfdSAndroid Build Coastguard Worker                             uint64_t symbol_addr = 0,
146*387f9dfdSAndroid Build Coastguard Worker                             bpf_probe_attach_type attach_type = BPF_PROBE_ENTRY,
147*387f9dfdSAndroid Build Coastguard Worker                             pid_t pid = -1,
148*387f9dfdSAndroid Build Coastguard Worker                             uint64_t symbol_offset = 0,
149*387f9dfdSAndroid Build Coastguard Worker                             uint32_t ref_ctr_offset = 0);
150*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_uprobe(const std::string& binary_path,
151*387f9dfdSAndroid Build Coastguard Worker                             const std::string& symbol, uint64_t symbol_addr = 0,
152*387f9dfdSAndroid Build Coastguard Worker                             bpf_probe_attach_type attach_type = BPF_PROBE_ENTRY,
153*387f9dfdSAndroid Build Coastguard Worker                             pid_t pid = -1,
154*387f9dfdSAndroid Build Coastguard Worker                             uint64_t symbol_offset = 0);
155*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_usdt(const USDT& usdt, pid_t pid = -1);
156*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_usdt_all();
157*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_usdt(const USDT& usdt, pid_t pid = -1);
158*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_usdt_all();
159*387f9dfdSAndroid Build Coastguard Worker 
160*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_tracepoint(const std::string& tracepoint,
161*387f9dfdSAndroid Build Coastguard Worker                                 const std::string& probe_func);
162*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_tracepoint(const std::string& tracepoint);
163*387f9dfdSAndroid Build Coastguard Worker 
164*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_raw_tracepoint(const std::string& tracepoint,
165*387f9dfdSAndroid Build Coastguard Worker                                     const std::string& probe_func);
166*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_raw_tracepoint(const std::string& tracepoint);
167*387f9dfdSAndroid Build Coastguard Worker 
168*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_perf_event(uint32_t ev_type, uint32_t ev_config,
169*387f9dfdSAndroid Build Coastguard Worker                                 const std::string& probe_func,
170*387f9dfdSAndroid Build Coastguard Worker                                 uint64_t sample_period, uint64_t sample_freq,
171*387f9dfdSAndroid Build Coastguard Worker                                 pid_t pid = -1, int cpu = -1,
172*387f9dfdSAndroid Build Coastguard Worker                                 int group_fd = -1);
173*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_perf_event_raw(void* perf_event_attr,
174*387f9dfdSAndroid Build Coastguard Worker                                     const std::string& probe_func,
175*387f9dfdSAndroid Build Coastguard Worker                                     pid_t pid = -1, int cpu = -1,
176*387f9dfdSAndroid Build Coastguard Worker                                     int group_fd = -1,
177*387f9dfdSAndroid Build Coastguard Worker                                     unsigned long extra_flags = 0);
178*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_perf_event(uint32_t ev_type, uint32_t ev_config);
179*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_perf_event_raw(void* perf_event_attr);
180*387f9dfdSAndroid Build Coastguard Worker   std::string get_syscall_fnname(const std::string& name);
181*387f9dfdSAndroid Build Coastguard Worker 
get_table(const std::string & name)182*387f9dfdSAndroid Build Coastguard Worker   BPFTable get_table(const std::string& name) {
183*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
184*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
185*387f9dfdSAndroid Build Coastguard Worker       return BPFTable(it->second);
186*387f9dfdSAndroid Build Coastguard Worker     return BPFTable({});
187*387f9dfdSAndroid Build Coastguard Worker   }
188*387f9dfdSAndroid Build Coastguard Worker 
189*387f9dfdSAndroid Build Coastguard Worker   template <class ValueType>
get_array_table(const std::string & name)190*387f9dfdSAndroid Build Coastguard Worker   BPFArrayTable<ValueType> get_array_table(const std::string& name) {
191*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
192*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
193*387f9dfdSAndroid Build Coastguard Worker       return BPFArrayTable<ValueType>(it->second);
194*387f9dfdSAndroid Build Coastguard Worker     return BPFArrayTable<ValueType>({});
195*387f9dfdSAndroid Build Coastguard Worker   }
196*387f9dfdSAndroid Build Coastguard Worker 
197*387f9dfdSAndroid Build Coastguard Worker   template <class ValueType>
get_percpu_array_table(const std::string & name)198*387f9dfdSAndroid Build Coastguard Worker   BPFPercpuArrayTable<ValueType> get_percpu_array_table(
199*387f9dfdSAndroid Build Coastguard Worker       const std::string& name) {
200*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
201*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
202*387f9dfdSAndroid Build Coastguard Worker       return BPFPercpuArrayTable<ValueType>(it->second);
203*387f9dfdSAndroid Build Coastguard Worker     return BPFPercpuArrayTable<ValueType>({});
204*387f9dfdSAndroid Build Coastguard Worker   }
205*387f9dfdSAndroid Build Coastguard Worker 
206*387f9dfdSAndroid Build Coastguard Worker   template <class KeyType, class ValueType>
get_hash_table(const std::string & name)207*387f9dfdSAndroid Build Coastguard Worker   BPFHashTable<KeyType, ValueType> get_hash_table(const std::string& name) {
208*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
209*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
210*387f9dfdSAndroid Build Coastguard Worker       return BPFHashTable<KeyType, ValueType>(it->second);
211*387f9dfdSAndroid Build Coastguard Worker     return BPFHashTable<KeyType, ValueType>({});
212*387f9dfdSAndroid Build Coastguard Worker   }
213*387f9dfdSAndroid Build Coastguard Worker 
214*387f9dfdSAndroid Build Coastguard Worker   template <class KeyType, class ValueType>
get_percpu_hash_table(const std::string & name)215*387f9dfdSAndroid Build Coastguard Worker   BPFPercpuHashTable<KeyType, ValueType> get_percpu_hash_table(
216*387f9dfdSAndroid Build Coastguard Worker       const std::string& name) {
217*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
218*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
219*387f9dfdSAndroid Build Coastguard Worker       return BPFPercpuHashTable<KeyType, ValueType>(it->second);
220*387f9dfdSAndroid Build Coastguard Worker     return BPFPercpuHashTable<KeyType, ValueType>({});
221*387f9dfdSAndroid Build Coastguard Worker   }
222*387f9dfdSAndroid Build Coastguard Worker 
223*387f9dfdSAndroid Build Coastguard Worker   template <class ValueType>
get_sk_storage_table(const std::string & name)224*387f9dfdSAndroid Build Coastguard Worker   BPFSkStorageTable<ValueType> get_sk_storage_table(const std::string& name) {
225*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
226*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
227*387f9dfdSAndroid Build Coastguard Worker       return BPFSkStorageTable<ValueType>(it->second);
228*387f9dfdSAndroid Build Coastguard Worker     return BPFSkStorageTable<ValueType>({});
229*387f9dfdSAndroid Build Coastguard Worker   }
230*387f9dfdSAndroid Build Coastguard Worker 
231*387f9dfdSAndroid Build Coastguard Worker   template <class ValueType>
get_inode_storage_table(const std::string & name)232*387f9dfdSAndroid Build Coastguard Worker   BPFInodeStorageTable<ValueType> get_inode_storage_table(const std::string& name) {
233*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
234*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
235*387f9dfdSAndroid Build Coastguard Worker       return BPFInodeStorageTable<ValueType>(it->second);
236*387f9dfdSAndroid Build Coastguard Worker     return BPFInodeStorageTable<ValueType>({});
237*387f9dfdSAndroid Build Coastguard Worker   }
238*387f9dfdSAndroid Build Coastguard Worker 
239*387f9dfdSAndroid Build Coastguard Worker   template <class ValueType>
get_task_storage_table(const std::string & name)240*387f9dfdSAndroid Build Coastguard Worker   BPFTaskStorageTable<ValueType> get_task_storage_table(const std::string& name) {
241*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
242*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
243*387f9dfdSAndroid Build Coastguard Worker       return BPFTaskStorageTable<ValueType>(it->second);
244*387f9dfdSAndroid Build Coastguard Worker     return BPFTaskStorageTable<ValueType>({});
245*387f9dfdSAndroid Build Coastguard Worker   }
246*387f9dfdSAndroid Build Coastguard Worker 
247*387f9dfdSAndroid Build Coastguard Worker   template <class ValueType>
get_cg_storage_table(const std::string & name)248*387f9dfdSAndroid Build Coastguard Worker   BPFCgStorageTable<ValueType> get_cg_storage_table(const std::string& name) {
249*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
250*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
251*387f9dfdSAndroid Build Coastguard Worker       return BPFCgStorageTable<ValueType>(it->second);
252*387f9dfdSAndroid Build Coastguard Worker     return BPFCgStorageTable<ValueType>({});
253*387f9dfdSAndroid Build Coastguard Worker   }
254*387f9dfdSAndroid Build Coastguard Worker 
255*387f9dfdSAndroid Build Coastguard Worker   template <class ValueType>
get_percpu_cg_storage_table(const std::string & name)256*387f9dfdSAndroid Build Coastguard Worker   BPFPercpuCgStorageTable<ValueType> get_percpu_cg_storage_table(const std::string& name) {
257*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
258*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
259*387f9dfdSAndroid Build Coastguard Worker       return BPFPercpuCgStorageTable<ValueType>(it->second);
260*387f9dfdSAndroid Build Coastguard Worker     return BPFPercpuCgStorageTable<ValueType>({});
261*387f9dfdSAndroid Build Coastguard Worker   }
262*387f9dfdSAndroid Build Coastguard Worker 
263*387f9dfdSAndroid Build Coastguard Worker   template <class ValueType>
get_queuestack_table(const std::string & name)264*387f9dfdSAndroid Build Coastguard Worker   BPFQueueStackTable<ValueType> get_queuestack_table(const std::string& name) {
265*387f9dfdSAndroid Build Coastguard Worker     TableStorage::iterator it;
266*387f9dfdSAndroid Build Coastguard Worker     if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
267*387f9dfdSAndroid Build Coastguard Worker       return BPFQueueStackTable<ValueType>(it->second);
268*387f9dfdSAndroid Build Coastguard Worker     return BPFQueueStackTable<ValueType>({});
269*387f9dfdSAndroid Build Coastguard Worker   }
270*387f9dfdSAndroid Build Coastguard Worker 
get_bsymcache(void)271*387f9dfdSAndroid Build Coastguard Worker   void* get_bsymcache(void) {
272*387f9dfdSAndroid Build Coastguard Worker     if (bsymcache_ == NULL) {
273*387f9dfdSAndroid Build Coastguard Worker       bsymcache_ = bcc_buildsymcache_new();
274*387f9dfdSAndroid Build Coastguard Worker     }
275*387f9dfdSAndroid Build Coastguard Worker     return bsymcache_;
276*387f9dfdSAndroid Build Coastguard Worker   }
277*387f9dfdSAndroid Build Coastguard Worker 
278*387f9dfdSAndroid Build Coastguard Worker   BPFProgTable get_prog_table(const std::string& name);
279*387f9dfdSAndroid Build Coastguard Worker 
280*387f9dfdSAndroid Build Coastguard Worker   BPFCgroupArray get_cgroup_array(const std::string& name);
281*387f9dfdSAndroid Build Coastguard Worker 
282*387f9dfdSAndroid Build Coastguard Worker   BPFDevmapTable get_devmap_table(const std::string& name);
283*387f9dfdSAndroid Build Coastguard Worker 
284*387f9dfdSAndroid Build Coastguard Worker   BPFXskmapTable get_xskmap_table(const std::string& name);
285*387f9dfdSAndroid Build Coastguard Worker 
286*387f9dfdSAndroid Build Coastguard Worker   BPFSockmapTable get_sockmap_table(const std::string& name);
287*387f9dfdSAndroid Build Coastguard Worker 
288*387f9dfdSAndroid Build Coastguard Worker   BPFSockhashTable get_sockhash_table(const std::string& name);
289*387f9dfdSAndroid Build Coastguard Worker 
290*387f9dfdSAndroid Build Coastguard Worker   BPFStackTable get_stack_table(const std::string& name,
291*387f9dfdSAndroid Build Coastguard Worker                                 bool use_debug_file = true,
292*387f9dfdSAndroid Build Coastguard Worker                                 bool check_debug_file_crc = true);
293*387f9dfdSAndroid Build Coastguard Worker 
294*387f9dfdSAndroid Build Coastguard Worker   BPFStackBuildIdTable get_stackbuildid_table(const std::string &name,
295*387f9dfdSAndroid Build Coastguard Worker                                               bool use_debug_file = true,
296*387f9dfdSAndroid Build Coastguard Worker                                               bool check_debug_file_crc = true);
297*387f9dfdSAndroid Build Coastguard Worker   template <class KeyType>
get_map_in_map_table(const std::string & name)298*387f9dfdSAndroid Build Coastguard Worker   BPFMapInMapTable<KeyType> get_map_in_map_table(const std::string& name){
299*387f9dfdSAndroid Build Coastguard Worker       TableStorage::iterator it;
300*387f9dfdSAndroid Build Coastguard Worker       if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
301*387f9dfdSAndroid Build Coastguard Worker         return BPFMapInMapTable<KeyType>(it->second);
302*387f9dfdSAndroid Build Coastguard Worker       return BPFMapInMapTable<KeyType>({});
303*387f9dfdSAndroid Build Coastguard Worker   }
304*387f9dfdSAndroid Build Coastguard Worker 
305*387f9dfdSAndroid Build Coastguard Worker   bool add_module(std::string module);
306*387f9dfdSAndroid Build Coastguard Worker 
307*387f9dfdSAndroid Build Coastguard Worker   StatusTuple open_perf_event(const std::string& name, uint32_t type,
308*387f9dfdSAndroid Build Coastguard Worker                               uint64_t config, int pid = -1);
309*387f9dfdSAndroid Build Coastguard Worker 
310*387f9dfdSAndroid Build Coastguard Worker   StatusTuple close_perf_event(const std::string& name);
311*387f9dfdSAndroid Build Coastguard Worker 
312*387f9dfdSAndroid Build Coastguard Worker   // Open a Perf Buffer of given name, providing callback and callback cookie
313*387f9dfdSAndroid Build Coastguard Worker   // to use when polling. BPF class owns the opened Perf Buffer and will free
314*387f9dfdSAndroid Build Coastguard Worker   // it on-demand or on destruction.
315*387f9dfdSAndroid Build Coastguard Worker   StatusTuple open_perf_buffer(const std::string& name, perf_reader_raw_cb cb,
316*387f9dfdSAndroid Build Coastguard Worker                                perf_reader_lost_cb lost_cb = nullptr,
317*387f9dfdSAndroid Build Coastguard Worker                                void* cb_cookie = nullptr,
318*387f9dfdSAndroid Build Coastguard Worker                                int page_cnt = DEFAULT_PERF_BUFFER_PAGE_CNT);
319*387f9dfdSAndroid Build Coastguard Worker   // Close and free the Perf Buffer of given name.
320*387f9dfdSAndroid Build Coastguard Worker   StatusTuple close_perf_buffer(const std::string& name);
321*387f9dfdSAndroid Build Coastguard Worker   // Obtain an pointer to the opened BPFPerfBuffer instance of given name.
322*387f9dfdSAndroid Build Coastguard Worker   // Will return nullptr if such open Perf Buffer doesn't exist.
323*387f9dfdSAndroid Build Coastguard Worker   BPFPerfBuffer* get_perf_buffer(const std::string& name);
324*387f9dfdSAndroid Build Coastguard Worker   // Poll an opened Perf Buffer of given name with given timeout, using callback
325*387f9dfdSAndroid Build Coastguard Worker   // provided when opening. Do nothing if such open Perf Buffer doesn't exist.
326*387f9dfdSAndroid Build Coastguard Worker   // Returns:
327*387f9dfdSAndroid Build Coastguard Worker   //   -1 on error or if perf buffer with such name doesn't exist;
328*387f9dfdSAndroid Build Coastguard Worker   //   0, if no data was available before timeout;
329*387f9dfdSAndroid Build Coastguard Worker   //   number of CPUs that have new data, otherwise.
330*387f9dfdSAndroid Build Coastguard Worker   int poll_perf_buffer(const std::string& name, int timeout_ms = -1);
331*387f9dfdSAndroid Build Coastguard Worker 
332*387f9dfdSAndroid Build Coastguard Worker   StatusTuple load_func(const std::string& func_name, enum bpf_prog_type type,
333*387f9dfdSAndroid Build Coastguard Worker                         int& fd, unsigned flags = 0, enum bpf_attach_type = (bpf_attach_type) -1);
334*387f9dfdSAndroid Build Coastguard Worker   StatusTuple unload_func(const std::string& func_name);
335*387f9dfdSAndroid Build Coastguard Worker 
336*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_func(int prog_fd, int attachable_fd,
337*387f9dfdSAndroid Build Coastguard Worker                           enum bpf_attach_type attach_type,
338*387f9dfdSAndroid Build Coastguard Worker                           uint64_t flags);
339*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_func(int prog_fd, int attachable_fd,
340*387f9dfdSAndroid Build Coastguard Worker                           enum bpf_attach_type attach_type);
341*387f9dfdSAndroid Build Coastguard Worker 
342*387f9dfdSAndroid Build Coastguard Worker   int free_bcc_memory();
343*387f9dfdSAndroid Build Coastguard Worker 
344*387f9dfdSAndroid Build Coastguard Worker  private:
345*387f9dfdSAndroid Build Coastguard Worker   std::string get_kprobe_event(const std::string& kernel_func,
346*387f9dfdSAndroid Build Coastguard Worker                                bpf_probe_attach_type type);
347*387f9dfdSAndroid Build Coastguard Worker   std::string get_uprobe_event(const std::string& binary_path, uint64_t offset,
348*387f9dfdSAndroid Build Coastguard Worker                                bpf_probe_attach_type type, pid_t pid);
349*387f9dfdSAndroid Build Coastguard Worker 
350*387f9dfdSAndroid Build Coastguard Worker   StatusTuple attach_usdt_without_validation(const USDT& usdt, pid_t pid);
351*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_usdt_without_validation(const USDT& usdt, pid_t pid);
352*387f9dfdSAndroid Build Coastguard Worker 
353*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_kprobe_event(const std::string& event, open_probe_t& attr);
354*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_uprobe_event(const std::string& event, open_probe_t& attr);
355*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_tracepoint_event(const std::string& tracepoint,
356*387f9dfdSAndroid Build Coastguard Worker                                       open_probe_t& attr);
357*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_raw_tracepoint_event(const std::string& tracepoint,
358*387f9dfdSAndroid Build Coastguard Worker                                           open_probe_t& attr);
359*387f9dfdSAndroid Build Coastguard Worker   StatusTuple detach_perf_event_all_cpu(open_probe_t& attr);
360*387f9dfdSAndroid Build Coastguard Worker 
attach_type_debug(bpf_probe_attach_type type)361*387f9dfdSAndroid Build Coastguard Worker   std::string attach_type_debug(bpf_probe_attach_type type) {
362*387f9dfdSAndroid Build Coastguard Worker     switch (type) {
363*387f9dfdSAndroid Build Coastguard Worker     case BPF_PROBE_ENTRY:
364*387f9dfdSAndroid Build Coastguard Worker       return "";
365*387f9dfdSAndroid Build Coastguard Worker     case BPF_PROBE_RETURN:
366*387f9dfdSAndroid Build Coastguard Worker       return "return ";
367*387f9dfdSAndroid Build Coastguard Worker     }
368*387f9dfdSAndroid Build Coastguard Worker     return "ERROR";
369*387f9dfdSAndroid Build Coastguard Worker   }
370*387f9dfdSAndroid Build Coastguard Worker 
attach_type_prefix(bpf_probe_attach_type type)371*387f9dfdSAndroid Build Coastguard Worker   std::string attach_type_prefix(bpf_probe_attach_type type) {
372*387f9dfdSAndroid Build Coastguard Worker     switch (type) {
373*387f9dfdSAndroid Build Coastguard Worker     case BPF_PROBE_ENTRY:
374*387f9dfdSAndroid Build Coastguard Worker       return "p";
375*387f9dfdSAndroid Build Coastguard Worker     case BPF_PROBE_RETURN:
376*387f9dfdSAndroid Build Coastguard Worker       return "r";
377*387f9dfdSAndroid Build Coastguard Worker     }
378*387f9dfdSAndroid Build Coastguard Worker     return "ERROR";
379*387f9dfdSAndroid Build Coastguard Worker   }
380*387f9dfdSAndroid Build Coastguard Worker 
kprobe_event_validator(char c)381*387f9dfdSAndroid Build Coastguard Worker   static bool kprobe_event_validator(char c) {
382*387f9dfdSAndroid Build Coastguard Worker     return (c != '+') && (c != '.');
383*387f9dfdSAndroid Build Coastguard Worker   }
384*387f9dfdSAndroid Build Coastguard Worker 
uprobe_path_validator(char c)385*387f9dfdSAndroid Build Coastguard Worker   static bool uprobe_path_validator(char c) {
386*387f9dfdSAndroid Build Coastguard Worker     return std::isalpha(c) || std::isdigit(c) || (c == '_');
387*387f9dfdSAndroid Build Coastguard Worker   }
388*387f9dfdSAndroid Build Coastguard Worker 
389*387f9dfdSAndroid Build Coastguard Worker   StatusTuple check_binary_symbol(const std::string& binary_path,
390*387f9dfdSAndroid Build Coastguard Worker                                   const std::string& symbol,
391*387f9dfdSAndroid Build Coastguard Worker                                   uint64_t symbol_addr, std::string& module_res,
392*387f9dfdSAndroid Build Coastguard Worker                                   uint64_t& offset_res,
393*387f9dfdSAndroid Build Coastguard Worker                                   uint64_t symbol_offset = 0);
394*387f9dfdSAndroid Build Coastguard Worker 
395*387f9dfdSAndroid Build Coastguard Worker   void init_fail_reset();
396*387f9dfdSAndroid Build Coastguard Worker 
397*387f9dfdSAndroid Build Coastguard Worker   int flag_;
398*387f9dfdSAndroid Build Coastguard Worker 
399*387f9dfdSAndroid Build Coastguard Worker   void *bsymcache_;
400*387f9dfdSAndroid Build Coastguard Worker 
401*387f9dfdSAndroid Build Coastguard Worker   std::unique_ptr<std::string> syscall_prefix_;
402*387f9dfdSAndroid Build Coastguard Worker 
403*387f9dfdSAndroid Build Coastguard Worker   std::unique_ptr<BPFModule> bpf_module_;
404*387f9dfdSAndroid Build Coastguard Worker 
405*387f9dfdSAndroid Build Coastguard Worker   std::map<std::string, int> funcs_;
406*387f9dfdSAndroid Build Coastguard Worker 
407*387f9dfdSAndroid Build Coastguard Worker   std::vector<USDT> usdt_;
408*387f9dfdSAndroid Build Coastguard Worker   std::string all_bpf_program_;
409*387f9dfdSAndroid Build Coastguard Worker 
410*387f9dfdSAndroid Build Coastguard Worker   std::map<std::string, open_probe_t> kprobes_;
411*387f9dfdSAndroid Build Coastguard Worker   std::map<std::string, open_probe_t> uprobes_;
412*387f9dfdSAndroid Build Coastguard Worker   std::map<std::string, open_probe_t> tracepoints_;
413*387f9dfdSAndroid Build Coastguard Worker   std::map<std::string, open_probe_t> raw_tracepoints_;
414*387f9dfdSAndroid Build Coastguard Worker   std::map<std::string, BPFPerfBuffer*> perf_buffers_;
415*387f9dfdSAndroid Build Coastguard Worker   std::map<std::string, BPFPerfEventArray*> perf_event_arrays_;
416*387f9dfdSAndroid Build Coastguard Worker   std::map<std::pair<uint32_t, uint32_t>, open_probe_t> perf_events_;
417*387f9dfdSAndroid Build Coastguard Worker };
418*387f9dfdSAndroid Build Coastguard Worker 
419*387f9dfdSAndroid Build Coastguard Worker }  // namespace ebpf
420