xref: /aosp_15_r20/external/bcc/src/cc/usdt.h (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker /*
2*387f9dfdSAndroid Build Coastguard Worker  * Copyright (c) 2016 GitHub, 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 #pragma once
17*387f9dfdSAndroid Build Coastguard Worker 
18*387f9dfdSAndroid Build Coastguard Worker #include <memory>
19*387f9dfdSAndroid Build Coastguard Worker #include <string>
20*387f9dfdSAndroid Build Coastguard Worker #include <unordered_map>
21*387f9dfdSAndroid Build Coastguard Worker #include <vector>
22*387f9dfdSAndroid Build Coastguard Worker 
23*387f9dfdSAndroid Build Coastguard Worker #include "bcc_proc.h"
24*387f9dfdSAndroid Build Coastguard Worker #include "syms.h"
25*387f9dfdSAndroid Build Coastguard Worker #include "vendor/optional.hpp"
26*387f9dfdSAndroid Build Coastguard Worker 
27*387f9dfdSAndroid Build Coastguard Worker struct bcc_usdt;
28*387f9dfdSAndroid Build Coastguard Worker 
29*387f9dfdSAndroid Build Coastguard Worker namespace ebpf {
30*387f9dfdSAndroid Build Coastguard Worker   class BPF;
31*387f9dfdSAndroid Build Coastguard Worker   class USDT;
32*387f9dfdSAndroid Build Coastguard Worker }
33*387f9dfdSAndroid Build Coastguard Worker 
34*387f9dfdSAndroid Build Coastguard Worker namespace USDT {
35*387f9dfdSAndroid Build Coastguard Worker 
36*387f9dfdSAndroid Build Coastguard Worker using std::experimental::optional;
37*387f9dfdSAndroid Build Coastguard Worker using std::experimental::nullopt;
38*387f9dfdSAndroid Build Coastguard Worker class ArgumentParser;
39*387f9dfdSAndroid Build Coastguard Worker 
40*387f9dfdSAndroid Build Coastguard Worker static const std::string USDT_PROGRAM_HEADER =
41*387f9dfdSAndroid Build Coastguard Worker     "#include <uapi/linux/ptrace.h>\n";
42*387f9dfdSAndroid Build Coastguard Worker 
43*387f9dfdSAndroid Build Coastguard Worker static const std::string COMPILER_BARRIER =
44*387f9dfdSAndroid Build Coastguard Worker     "__asm__ __volatile__(\"\": : :\"memory\");";
45*387f9dfdSAndroid Build Coastguard Worker 
46*387f9dfdSAndroid Build Coastguard Worker class Argument {
47*387f9dfdSAndroid Build Coastguard Worker private:
48*387f9dfdSAndroid Build Coastguard Worker   optional<int> arg_size_;
49*387f9dfdSAndroid Build Coastguard Worker   optional<long long> constant_;
50*387f9dfdSAndroid Build Coastguard Worker   optional<int> deref_offset_;
51*387f9dfdSAndroid Build Coastguard Worker   optional<std::string> deref_ident_;
52*387f9dfdSAndroid Build Coastguard Worker   optional<std::string> base_register_name_;
53*387f9dfdSAndroid Build Coastguard Worker   optional<std::string> index_register_name_;
54*387f9dfdSAndroid Build Coastguard Worker   optional<int> scale_;
55*387f9dfdSAndroid Build Coastguard Worker 
56*387f9dfdSAndroid Build Coastguard Worker   bool get_global_address(uint64_t *address, const std::string &binpath,
57*387f9dfdSAndroid Build Coastguard Worker                           const optional<int> &pid) const;
58*387f9dfdSAndroid Build Coastguard Worker 
59*387f9dfdSAndroid Build Coastguard Worker public:
60*387f9dfdSAndroid Build Coastguard Worker   Argument();
61*387f9dfdSAndroid Build Coastguard Worker   ~Argument();
62*387f9dfdSAndroid Build Coastguard Worker 
63*387f9dfdSAndroid Build Coastguard Worker   bool assign_to_local(std::ostream &stream, const std::string &local_name,
64*387f9dfdSAndroid Build Coastguard Worker                        const std::string &binpath,
65*387f9dfdSAndroid Build Coastguard Worker                        const optional<int> &pid = nullopt) const;
66*387f9dfdSAndroid Build Coastguard Worker 
arg_size()67*387f9dfdSAndroid Build Coastguard Worker   int arg_size() const { return arg_size_.value_or(sizeof(void *)); }
68*387f9dfdSAndroid Build Coastguard Worker   std::string ctype() const;
69*387f9dfdSAndroid Build Coastguard Worker   const char *ctype_name() const;
70*387f9dfdSAndroid Build Coastguard Worker 
deref_ident()71*387f9dfdSAndroid Build Coastguard Worker   const optional<std::string> &deref_ident() const { return deref_ident_; }
base_register_name()72*387f9dfdSAndroid Build Coastguard Worker   const optional<std::string> &base_register_name() const {
73*387f9dfdSAndroid Build Coastguard Worker     return base_register_name_;
74*387f9dfdSAndroid Build Coastguard Worker   }
index_register_name()75*387f9dfdSAndroid Build Coastguard Worker   const optional<std::string> &index_register_name() const {
76*387f9dfdSAndroid Build Coastguard Worker     return index_register_name_;
77*387f9dfdSAndroid Build Coastguard Worker   }
scale()78*387f9dfdSAndroid Build Coastguard Worker   const optional<int> scale() const { return scale_; }
constant()79*387f9dfdSAndroid Build Coastguard Worker   const optional<long long> constant() const { return constant_; }
deref_offset()80*387f9dfdSAndroid Build Coastguard Worker   const optional<int> deref_offset() const { return deref_offset_; }
81*387f9dfdSAndroid Build Coastguard Worker 
82*387f9dfdSAndroid Build Coastguard Worker   friend class ArgumentParser;
83*387f9dfdSAndroid Build Coastguard Worker   friend class ArgumentParser_aarch64;
84*387f9dfdSAndroid Build Coastguard Worker   friend class ArgumentParser_loongarch64;
85*387f9dfdSAndroid Build Coastguard Worker   friend class ArgumentParser_powerpc64;
86*387f9dfdSAndroid Build Coastguard Worker   friend class ArgumentParser_s390x;
87*387f9dfdSAndroid Build Coastguard Worker   friend class ArgumentParser_x64;
88*387f9dfdSAndroid Build Coastguard Worker };
89*387f9dfdSAndroid Build Coastguard Worker 
90*387f9dfdSAndroid Build Coastguard Worker class ArgumentParser {
91*387f9dfdSAndroid Build Coastguard Worker  protected:
92*387f9dfdSAndroid Build Coastguard Worker   const char *arg_;
93*387f9dfdSAndroid Build Coastguard Worker   ssize_t cur_pos_;
94*387f9dfdSAndroid Build Coastguard Worker 
95*387f9dfdSAndroid Build Coastguard Worker   void skip_whitespace_from(size_t pos);
96*387f9dfdSAndroid Build Coastguard Worker   void skip_until_whitespace_from(size_t pos);
97*387f9dfdSAndroid Build Coastguard Worker   void print_error(ssize_t pos);
parse_number(ssize_t pos,optional<int> * result)98*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_number(ssize_t pos, optional<int> *result) {
99*387f9dfdSAndroid Build Coastguard Worker     char *endp;
100*387f9dfdSAndroid Build Coastguard Worker     int number = strtol(arg_ + pos, &endp, 0);
101*387f9dfdSAndroid Build Coastguard Worker     if (endp > arg_ + pos)
102*387f9dfdSAndroid Build Coastguard Worker       *result = number;
103*387f9dfdSAndroid Build Coastguard Worker     return endp - arg_;
104*387f9dfdSAndroid Build Coastguard Worker   }
parse_number(ssize_t pos,optional<long long> * result)105*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_number(ssize_t pos, optional<long long> *result) {
106*387f9dfdSAndroid Build Coastguard Worker     char *endp;
107*387f9dfdSAndroid Build Coastguard Worker     long long number = (long long)strtoull(arg_ + pos, &endp, 0);
108*387f9dfdSAndroid Build Coastguard Worker     if (endp > arg_ + pos)
109*387f9dfdSAndroid Build Coastguard Worker       *result = number;
110*387f9dfdSAndroid Build Coastguard Worker     return endp - arg_;
111*387f9dfdSAndroid Build Coastguard Worker   }
error_return(ssize_t error_start,ssize_t skip_start)112*387f9dfdSAndroid Build Coastguard Worker   bool error_return(ssize_t error_start, ssize_t skip_start) {
113*387f9dfdSAndroid Build Coastguard Worker     print_error(error_start);
114*387f9dfdSAndroid Build Coastguard Worker     if (isspace(arg_[skip_start]))
115*387f9dfdSAndroid Build Coastguard Worker         skip_start++;  // Make sure we skip at least one character
116*387f9dfdSAndroid Build Coastguard Worker     skip_until_whitespace_from(skip_start);
117*387f9dfdSAndroid Build Coastguard Worker     return false;
118*387f9dfdSAndroid Build Coastguard Worker   }
119*387f9dfdSAndroid Build Coastguard Worker 
120*387f9dfdSAndroid Build Coastguard Worker  public:
121*387f9dfdSAndroid Build Coastguard Worker   virtual bool parse(Argument *dest) = 0;
done()122*387f9dfdSAndroid Build Coastguard Worker   bool done() { return cur_pos_ < 0 || arg_[cur_pos_] == '\0'; }
123*387f9dfdSAndroid Build Coastguard Worker 
ArgumentParser(const char * arg)124*387f9dfdSAndroid Build Coastguard Worker   ArgumentParser(const char *arg) : arg_(arg), cur_pos_(0) {}
125*387f9dfdSAndroid Build Coastguard Worker };
126*387f9dfdSAndroid Build Coastguard Worker 
127*387f9dfdSAndroid Build Coastguard Worker class ArgumentParser_aarch64 : public ArgumentParser {
128*387f9dfdSAndroid Build Coastguard Worker  private:
129*387f9dfdSAndroid Build Coastguard Worker   bool parse_register(ssize_t pos, ssize_t &new_pos, std::string &reg_name);
130*387f9dfdSAndroid Build Coastguard Worker   bool parse_size(ssize_t pos, ssize_t &new_pos, optional<int> *arg_size);
131*387f9dfdSAndroid Build Coastguard Worker   bool parse_mem(ssize_t pos, ssize_t &new_pos, Argument *dest);
132*387f9dfdSAndroid Build Coastguard Worker 
133*387f9dfdSAndroid Build Coastguard Worker  public:
134*387f9dfdSAndroid Build Coastguard Worker   bool parse(Argument *dest);
ArgumentParser_aarch64(const char * arg)135*387f9dfdSAndroid Build Coastguard Worker   ArgumentParser_aarch64(const char *arg) : ArgumentParser(arg) {}
136*387f9dfdSAndroid Build Coastguard Worker };
137*387f9dfdSAndroid Build Coastguard Worker 
138*387f9dfdSAndroid Build Coastguard Worker class ArgumentParser_loongarch64 : public ArgumentParser {
139*387f9dfdSAndroid Build Coastguard Worker  private:
140*387f9dfdSAndroid Build Coastguard Worker   bool parse_register(ssize_t pos, ssize_t &new_pos, std::string &reg_name);
141*387f9dfdSAndroid Build Coastguard Worker   bool parse_size(ssize_t pos, ssize_t &new_pos, optional<int> *arg_size);
142*387f9dfdSAndroid Build Coastguard Worker   bool parse_mem(ssize_t pos, ssize_t &new_pos, Argument *dest);
143*387f9dfdSAndroid Build Coastguard Worker 
144*387f9dfdSAndroid Build Coastguard Worker  public:
145*387f9dfdSAndroid Build Coastguard Worker   bool parse(Argument *dest);
ArgumentParser_loongarch64(const char * arg)146*387f9dfdSAndroid Build Coastguard Worker   ArgumentParser_loongarch64(const char *arg) : ArgumentParser(arg) {}
147*387f9dfdSAndroid Build Coastguard Worker };
148*387f9dfdSAndroid Build Coastguard Worker 
149*387f9dfdSAndroid Build Coastguard Worker class ArgumentParser_powerpc64 : public ArgumentParser {
150*387f9dfdSAndroid Build Coastguard Worker public:
151*387f9dfdSAndroid Build Coastguard Worker   bool parse(Argument *dest);
ArgumentParser_powerpc64(const char * arg)152*387f9dfdSAndroid Build Coastguard Worker   ArgumentParser_powerpc64(const char *arg) : ArgumentParser(arg) {}
153*387f9dfdSAndroid Build Coastguard Worker };
154*387f9dfdSAndroid Build Coastguard Worker 
155*387f9dfdSAndroid Build Coastguard Worker class ArgumentParser_s390x : public ArgumentParser {
156*387f9dfdSAndroid Build Coastguard Worker public:
157*387f9dfdSAndroid Build Coastguard Worker   bool parse(Argument *dest);
ArgumentParser_s390x(const char * arg)158*387f9dfdSAndroid Build Coastguard Worker   ArgumentParser_s390x(const char *arg) : ArgumentParser(arg) {}
159*387f9dfdSAndroid Build Coastguard Worker };
160*387f9dfdSAndroid Build Coastguard Worker 
161*387f9dfdSAndroid Build Coastguard Worker class ArgumentParser_x64 : public ArgumentParser {
162*387f9dfdSAndroid Build Coastguard Worker private:
163*387f9dfdSAndroid Build Coastguard Worker   enum Register {
164*387f9dfdSAndroid Build Coastguard Worker     X64_REG_A,
165*387f9dfdSAndroid Build Coastguard Worker     X64_REG_B,
166*387f9dfdSAndroid Build Coastguard Worker     X64_REG_C,
167*387f9dfdSAndroid Build Coastguard Worker     X64_REG_D,
168*387f9dfdSAndroid Build Coastguard Worker     X64_REG_SI,
169*387f9dfdSAndroid Build Coastguard Worker     X64_REG_DI,
170*387f9dfdSAndroid Build Coastguard Worker     X64_REG_BP,
171*387f9dfdSAndroid Build Coastguard Worker     X64_REG_SP,
172*387f9dfdSAndroid Build Coastguard Worker     X64_REG_8,
173*387f9dfdSAndroid Build Coastguard Worker     X64_REG_9,
174*387f9dfdSAndroid Build Coastguard Worker     X64_REG_10,
175*387f9dfdSAndroid Build Coastguard Worker     X64_REG_11,
176*387f9dfdSAndroid Build Coastguard Worker     X64_REG_12,
177*387f9dfdSAndroid Build Coastguard Worker     X64_REG_13,
178*387f9dfdSAndroid Build Coastguard Worker     X64_REG_14,
179*387f9dfdSAndroid Build Coastguard Worker     X64_REG_15,
180*387f9dfdSAndroid Build Coastguard Worker     X64_REG_RIP,
181*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM0,
182*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM1,
183*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM2,
184*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM3,
185*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM4,
186*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM5,
187*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM6,
188*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM7,
189*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM8,
190*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM9,
191*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM10,
192*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM11,
193*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM12,
194*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM13,
195*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM14,
196*387f9dfdSAndroid Build Coastguard Worker     X64_REG_XMM15,
197*387f9dfdSAndroid Build Coastguard Worker   };
198*387f9dfdSAndroid Build Coastguard Worker 
199*387f9dfdSAndroid Build Coastguard Worker   struct RegInfo {
200*387f9dfdSAndroid Build Coastguard Worker     Register reg;
201*387f9dfdSAndroid Build Coastguard Worker     int size;
202*387f9dfdSAndroid Build Coastguard Worker   };
203*387f9dfdSAndroid Build Coastguard Worker 
204*387f9dfdSAndroid Build Coastguard Worker   static const std::unordered_map<std::string, RegInfo> registers_;
205*387f9dfdSAndroid Build Coastguard Worker   bool normalize_register(std::string *reg, int *reg_size);
206*387f9dfdSAndroid Build Coastguard Worker   void reg_to_name(std::string *norm, Register reg);
207*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_register(ssize_t pos, std::string &name, int &size);
208*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_identifier(ssize_t pos, optional<std::string> *ident);
209*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_base_register(ssize_t pos, Argument *dest);
210*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_index_register(ssize_t pos, Argument *dest);
211*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_scale(ssize_t pos, Argument *dest);
212*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_expr(ssize_t pos, Argument *dest);
213*387f9dfdSAndroid Build Coastguard Worker   ssize_t parse_1(ssize_t pos, Argument *dest);
214*387f9dfdSAndroid Build Coastguard Worker 
215*387f9dfdSAndroid Build Coastguard Worker public:
216*387f9dfdSAndroid Build Coastguard Worker   bool parse(Argument *dest);
ArgumentParser_x64(const char * arg)217*387f9dfdSAndroid Build Coastguard Worker   ArgumentParser_x64(const char *arg) : ArgumentParser(arg) {}
218*387f9dfdSAndroid Build Coastguard Worker };
219*387f9dfdSAndroid Build Coastguard Worker 
220*387f9dfdSAndroid Build Coastguard Worker struct Location {
221*387f9dfdSAndroid Build Coastguard Worker   uint64_t address_;
222*387f9dfdSAndroid Build Coastguard Worker   std::string bin_path_;
223*387f9dfdSAndroid Build Coastguard Worker   std::vector<Argument> arguments_;
224*387f9dfdSAndroid Build Coastguard Worker   Location(uint64_t addr, const std::string &bin_path, const char *arg_fmt);
225*387f9dfdSAndroid Build Coastguard Worker };
226*387f9dfdSAndroid Build Coastguard Worker 
227*387f9dfdSAndroid Build Coastguard Worker class Probe {
228*387f9dfdSAndroid Build Coastguard Worker   std::string bin_path_; // initial bin_path when Probe is created
229*387f9dfdSAndroid Build Coastguard Worker   std::string provider_;
230*387f9dfdSAndroid Build Coastguard Worker   std::string name_;
231*387f9dfdSAndroid Build Coastguard Worker   uint64_t semaphore_;
232*387f9dfdSAndroid Build Coastguard Worker   uint64_t semaphore_offset_;
233*387f9dfdSAndroid Build Coastguard Worker 
234*387f9dfdSAndroid Build Coastguard Worker   std::vector<Location> locations_;
235*387f9dfdSAndroid Build Coastguard Worker 
236*387f9dfdSAndroid Build Coastguard Worker   optional<int> pid_;
237*387f9dfdSAndroid Build Coastguard Worker   std::unordered_map<std::string, bool> object_type_map_; // bin_path => is shared lib?
238*387f9dfdSAndroid Build Coastguard Worker 
239*387f9dfdSAndroid Build Coastguard Worker   optional<std::string> attached_to_;
240*387f9dfdSAndroid Build Coastguard Worker   optional<uint64_t> attached_semaphore_;
241*387f9dfdSAndroid Build Coastguard Worker   uint8_t mod_match_inode_only_;
242*387f9dfdSAndroid Build Coastguard Worker 
243*387f9dfdSAndroid Build Coastguard Worker   const char *largest_arg_type(size_t arg_n);
244*387f9dfdSAndroid Build Coastguard Worker 
245*387f9dfdSAndroid Build Coastguard Worker   bool add_to_semaphore(int16_t val);
246*387f9dfdSAndroid Build Coastguard Worker   bool resolve_global_address(uint64_t *global, const std::string &bin_path,
247*387f9dfdSAndroid Build Coastguard Worker                               const uint64_t addr);
248*387f9dfdSAndroid Build Coastguard Worker   bool lookup_semaphore_addr(uint64_t *address);
249*387f9dfdSAndroid Build Coastguard Worker   void add_location(uint64_t addr, const std::string &bin_path, const char *fmt);
250*387f9dfdSAndroid Build Coastguard Worker 
251*387f9dfdSAndroid Build Coastguard Worker public:
252*387f9dfdSAndroid Build Coastguard Worker   Probe(const char *bin_path, const char *provider, const char *name,
253*387f9dfdSAndroid Build Coastguard Worker         uint64_t semaphore, uint64_t semaphore_offset,
254*387f9dfdSAndroid Build Coastguard Worker         const optional<int> &pid, uint8_t mod_match_inode_only = 1);
255*387f9dfdSAndroid Build Coastguard Worker 
num_locations()256*387f9dfdSAndroid Build Coastguard Worker   size_t num_locations() const { return locations_.size(); }
num_arguments()257*387f9dfdSAndroid Build Coastguard Worker   size_t num_arguments() const { return locations_.front().arguments_.size(); }
semaphore()258*387f9dfdSAndroid Build Coastguard Worker   uint64_t semaphore()   const { return semaphore_; }
semaphore_offset()259*387f9dfdSAndroid Build Coastguard Worker   uint64_t semaphore_offset() const { return semaphore_offset_; }
260*387f9dfdSAndroid Build Coastguard Worker 
261*387f9dfdSAndroid Build Coastguard Worker   uint64_t address(size_t n = 0) const { return locations_[n].address_; }
262*387f9dfdSAndroid Build Coastguard Worker   const char *location_bin_path(size_t n = 0) const { return locations_[n].bin_path_.c_str(); }
location(size_t n)263*387f9dfdSAndroid Build Coastguard Worker   const Location &location(size_t n) const { return locations_[n]; }
264*387f9dfdSAndroid Build Coastguard Worker 
265*387f9dfdSAndroid Build Coastguard Worker   bool usdt_getarg(std::ostream &stream);
266*387f9dfdSAndroid Build Coastguard Worker   bool usdt_getarg(std::ostream &stream, const std::string& probe_func);
get_arg_ctype(int arg_index)267*387f9dfdSAndroid Build Coastguard Worker   std::string get_arg_ctype(int arg_index) {
268*387f9dfdSAndroid Build Coastguard Worker     return largest_arg_type(arg_index);
269*387f9dfdSAndroid Build Coastguard Worker   }
270*387f9dfdSAndroid Build Coastguard Worker 
get_arg_ctype_name(int arg_index)271*387f9dfdSAndroid Build Coastguard Worker   const char *get_arg_ctype_name(int arg_index) {
272*387f9dfdSAndroid Build Coastguard Worker     return largest_arg_type(arg_index);
273*387f9dfdSAndroid Build Coastguard Worker   }
274*387f9dfdSAndroid Build Coastguard Worker 
275*387f9dfdSAndroid Build Coastguard Worker   void finalize_locations();
need_enable()276*387f9dfdSAndroid Build Coastguard Worker   bool need_enable() const { return semaphore_ != 0x0; }
277*387f9dfdSAndroid Build Coastguard Worker   bool enable(const std::string &fn_name);
278*387f9dfdSAndroid Build Coastguard Worker   bool disable();
enabled()279*387f9dfdSAndroid Build Coastguard Worker   bool enabled() const { return !!attached_to_; }
280*387f9dfdSAndroid Build Coastguard Worker 
281*387f9dfdSAndroid Build Coastguard Worker   bool in_shared_object(const std::string &bin_path);
name()282*387f9dfdSAndroid Build Coastguard Worker   const std::string &name() { return name_; }
bin_path()283*387f9dfdSAndroid Build Coastguard Worker   const std::string &bin_path() { return bin_path_; }
provider()284*387f9dfdSAndroid Build Coastguard Worker   const std::string &provider() { return provider_; }
285*387f9dfdSAndroid Build Coastguard Worker 
286*387f9dfdSAndroid Build Coastguard Worker   friend class Context;
287*387f9dfdSAndroid Build Coastguard Worker 
288*387f9dfdSAndroid Build Coastguard Worker   friend class ::ebpf::BPF;
289*387f9dfdSAndroid Build Coastguard Worker   friend class ::ebpf::USDT;
290*387f9dfdSAndroid Build Coastguard Worker };
291*387f9dfdSAndroid Build Coastguard Worker 
292*387f9dfdSAndroid Build Coastguard Worker class Context {
293*387f9dfdSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Probe>> probes_;
294*387f9dfdSAndroid Build Coastguard Worker   std::unordered_set<std::string> modules_;
295*387f9dfdSAndroid Build Coastguard Worker 
296*387f9dfdSAndroid Build Coastguard Worker   optional<int> pid_;
297*387f9dfdSAndroid Build Coastguard Worker   optional<ProcStat> pid_stat_;
298*387f9dfdSAndroid Build Coastguard Worker   std::string cmd_bin_path_;
299*387f9dfdSAndroid Build Coastguard Worker   bool loaded_;
300*387f9dfdSAndroid Build Coastguard Worker 
301*387f9dfdSAndroid Build Coastguard Worker   static void _each_probe(const char *binpath, const struct bcc_elf_usdt *probe,
302*387f9dfdSAndroid Build Coastguard Worker                           void *p);
303*387f9dfdSAndroid Build Coastguard Worker   static int _each_module(mod_info *, int enter_ns, void *p);
304*387f9dfdSAndroid Build Coastguard Worker 
305*387f9dfdSAndroid Build Coastguard Worker   void add_probe(const char *binpath, const struct bcc_elf_usdt *probe);
306*387f9dfdSAndroid Build Coastguard Worker   std::string resolve_bin_path(const std::string &bin_path);
307*387f9dfdSAndroid Build Coastguard Worker   Probe *get_checked(const std::string &provider_name,
308*387f9dfdSAndroid Build Coastguard Worker                      const std::string &probe_name);
309*387f9dfdSAndroid Build Coastguard Worker 
310*387f9dfdSAndroid Build Coastguard Worker private:
311*387f9dfdSAndroid Build Coastguard Worker   uint8_t mod_match_inode_only_;
312*387f9dfdSAndroid Build Coastguard Worker 
313*387f9dfdSAndroid Build Coastguard Worker public:
314*387f9dfdSAndroid Build Coastguard Worker   Context(const std::string &bin_path, uint8_t mod_match_inode_only = 1);
315*387f9dfdSAndroid Build Coastguard Worker   Context(int pid, uint8_t mod_match_inode_only = 1);
316*387f9dfdSAndroid Build Coastguard Worker   Context(int pid, const std::string &bin_path,
317*387f9dfdSAndroid Build Coastguard Worker           uint8_t mod_match_inode_only = 1);
318*387f9dfdSAndroid Build Coastguard Worker   ~Context();
319*387f9dfdSAndroid Build Coastguard Worker 
pid()320*387f9dfdSAndroid Build Coastguard Worker   optional<int> pid() const { return pid_; }
loaded()321*387f9dfdSAndroid Build Coastguard Worker   bool loaded() const { return loaded_; }
num_probes()322*387f9dfdSAndroid Build Coastguard Worker   size_t num_probes() const { return probes_.size(); }
cmd_bin_path()323*387f9dfdSAndroid Build Coastguard Worker   const std::string & cmd_bin_path() const { return cmd_bin_path_; }
324*387f9dfdSAndroid Build Coastguard Worker 
325*387f9dfdSAndroid Build Coastguard Worker   Probe *get(const std::string &probe_name);
326*387f9dfdSAndroid Build Coastguard Worker   Probe *get(const std::string &provider_name, const std::string &probe_name);
get(int pos)327*387f9dfdSAndroid Build Coastguard Worker   Probe *get(int pos) { return probes_[pos].get(); }
328*387f9dfdSAndroid Build Coastguard Worker 
329*387f9dfdSAndroid Build Coastguard Worker   bool enable_probe(const std::string &probe_name, const std::string &fn_name);
330*387f9dfdSAndroid Build Coastguard Worker   bool enable_probe(const std::string &provider_name,
331*387f9dfdSAndroid Build Coastguard Worker                     const std::string &probe_name, const std::string &fn_name);
332*387f9dfdSAndroid Build Coastguard Worker   bool addsem_probe(const std::string &provider_name,
333*387f9dfdSAndroid Build Coastguard Worker                     const std::string &probe_name, const std::string &fn_name,
334*387f9dfdSAndroid Build Coastguard Worker                     int16_t val);
335*387f9dfdSAndroid Build Coastguard Worker 
336*387f9dfdSAndroid Build Coastguard Worker   typedef void (*each_cb)(struct bcc_usdt *);
337*387f9dfdSAndroid Build Coastguard Worker   void each(each_cb callback);
338*387f9dfdSAndroid Build Coastguard Worker 
339*387f9dfdSAndroid Build Coastguard Worker   typedef void (*each_uprobe_cb)(const char *, const char *, uint64_t, int);
340*387f9dfdSAndroid Build Coastguard Worker   void each_uprobe(each_uprobe_cb callback);
341*387f9dfdSAndroid Build Coastguard Worker 
342*387f9dfdSAndroid Build Coastguard Worker   friend class ::ebpf::BPF;
343*387f9dfdSAndroid Build Coastguard Worker   friend class ::ebpf::USDT;
344*387f9dfdSAndroid Build Coastguard Worker };
345*387f9dfdSAndroid Build Coastguard Worker }
346