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