xref: /aosp_15_r20/external/bcc/src/python/bcc/libbcc.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1# Copyright 2015 PLUMgrid
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import ctypes as ct
16
17lib = ct.CDLL("libbcc.so.0", use_errno=True)
18
19# needed for perf_event_attr() ctype
20from .perf import Perf
21
22# keep in sync with bcc_common.h
23lib.bpf_module_create_c.restype = ct.c_void_p
24lib.bpf_module_create_c.argtypes = [ct.c_char_p, ct.c_uint,
25        ct.POINTER(ct.c_char_p), ct.c_int, ct.c_bool, ct.c_char_p]
26lib.bpf_module_create_c_from_string.restype = ct.c_void_p
27lib.bpf_module_create_c_from_string.argtypes = [ct.c_char_p, ct.c_uint,
28        ct.POINTER(ct.c_char_p), ct.c_int, ct.c_bool, ct.c_char_p]
29lib.bpf_module_rw_engine_enabled.restype = ct.c_bool
30lib.bpf_module_rw_engine_enabled.argtypes = None
31lib.bpf_module_destroy.restype = None
32lib.bpf_module_destroy.argtypes = [ct.c_void_p]
33lib.bpf_module_license.restype = ct.c_char_p
34lib.bpf_module_license.argtypes = [ct.c_void_p]
35lib.bpf_module_kern_version.restype = ct.c_uint
36lib.bpf_module_kern_version.argtypes = [ct.c_void_p]
37lib.bpf_num_functions.restype = ct.c_ulonglong
38lib.bpf_num_functions.argtypes = [ct.c_void_p]
39lib.bpf_function_name.restype = ct.c_char_p
40lib.bpf_function_name.argtypes = [ct.c_void_p, ct.c_ulonglong]
41lib.bpf_function_start.restype = ct.c_void_p
42lib.bpf_function_start.argtypes = [ct.c_void_p, ct.c_char_p]
43lib.bpf_function_size.restype = ct.c_size_t
44lib.bpf_function_size.argtypes = [ct.c_void_p, ct.c_char_p]
45lib.bpf_table_id.restype = ct.c_ulonglong
46lib.bpf_table_id.argtypes = [ct.c_void_p, ct.c_char_p]
47lib.bpf_table_fd.restype = ct.c_int
48lib.bpf_table_fd.argtypes = [ct.c_void_p, ct.c_char_p]
49lib.bpf_table_type_id.restype = ct.c_int
50lib.bpf_table_type_id.argtypes = [ct.c_void_p, ct.c_ulonglong]
51lib.bpf_table_max_entries_id.restype = ct.c_ulonglong
52lib.bpf_table_max_entries_id.argtypes = [ct.c_void_p, ct.c_ulonglong]
53lib.bpf_table_flags_id.restype = ct.c_int
54lib.bpf_table_flags_id.argtypes = [ct.c_void_p, ct.c_ulonglong]
55lib.bpf_table_key_desc.restype = ct.c_char_p
56lib.bpf_table_key_desc.argtypes = [ct.c_void_p, ct.c_char_p]
57lib.bpf_table_leaf_desc.restype = ct.c_char_p
58lib.bpf_table_leaf_desc.argtypes = [ct.c_void_p, ct.c_char_p]
59lib.bpf_table_key_snprintf.restype = ct.c_int
60lib.bpf_table_key_snprintf.argtypes = [ct.c_void_p, ct.c_ulonglong,
61        ct.c_char_p, ct.c_ulonglong, ct.c_void_p]
62lib.bpf_table_leaf_snprintf.restype = ct.c_int
63lib.bpf_table_leaf_snprintf.argtypes = [ct.c_void_p, ct.c_ulonglong,
64        ct.c_char_p, ct.c_ulonglong, ct.c_void_p]
65lib.bpf_table_key_sscanf.restype = ct.c_int
66lib.bpf_table_key_sscanf.argtypes = [ct.c_void_p, ct.c_ulonglong,
67        ct.c_char_p, ct.c_void_p]
68lib.bpf_table_leaf_sscanf.restype = ct.c_int
69lib.bpf_table_leaf_sscanf.argtypes = [ct.c_void_p, ct.c_ulonglong,
70        ct.c_char_p, ct.c_void_p]
71lib.bpf_perf_event_fields.restype = ct.c_ulonglong
72lib.bpf_perf_event_fields.argtypes = [ct.c_void_p, ct.c_char_p]
73lib.bpf_perf_event_field.restype = ct.c_char_p
74lib.bpf_perf_event_field.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_ulonglong]
75
76# keep in sync with libbpf.h
77lib.bpf_get_next_key.restype = ct.c_int
78lib.bpf_get_next_key.argtypes = [ct.c_int, ct.c_void_p, ct.c_void_p]
79lib.bpf_get_first_key.restype = ct.c_int
80lib.bpf_get_first_key.argtypes = [ct.c_int, ct.c_void_p, ct.c_uint]
81lib.bpf_lookup_elem.restype = ct.c_int
82lib.bpf_lookup_elem.argtypes = [ct.c_int, ct.c_void_p, ct.c_void_p]
83lib.bpf_update_elem.restype = ct.c_int
84lib.bpf_update_elem.argtypes = [ct.c_int, ct.c_void_p, ct.c_void_p,
85        ct.c_ulonglong]
86lib.bpf_delete_elem.restype = ct.c_int
87lib.bpf_delete_elem.argtypes = [ct.c_int, ct.c_void_p]
88lib.bpf_delete_batch.restype = ct.c_int
89lib.bpf_delete_batch.argtypes = [ct.c_int, ct.c_void_p, ct.c_void_p]
90lib.bpf_update_batch.restype = ct.c_int
91lib.bpf_update_batch.argtypes = [ct.c_int, ct.c_void_p, ct.c_void_p,
92        ct.POINTER(ct.c_uint32)]
93lib.bpf_lookup_batch.restype = ct.c_int
94lib.bpf_lookup_batch.argtypes = [ct.c_int, ct.POINTER(ct.c_uint32),
95        ct.POINTER(ct.c_uint32), ct.c_void_p, ct.c_void_p, ct.c_void_p]
96lib.bpf_lookup_and_delete_batch.restype = ct.c_int
97lib.bpf_lookup_and_delete_batch.argtypes = [ct.c_int, ct.POINTER(ct.c_uint32),
98        ct.POINTER(ct.c_uint32), ct.c_void_p, ct.c_void_p, ct.c_void_p]
99lib.bpf_open_raw_sock.restype = ct.c_int
100lib.bpf_open_raw_sock.argtypes = [ct.c_char_p]
101lib.bpf_attach_socket.restype = ct.c_int
102lib.bpf_attach_socket.argtypes = [ct.c_int, ct.c_int]
103lib.bcc_func_load.restype = ct.c_int
104lib.bcc_func_load.argtypes = [ct.c_void_p, ct.c_int, ct.c_char_p, ct.c_void_p,
105        ct.c_size_t, ct.c_char_p, ct.c_uint, ct.c_int, ct.c_char_p, ct.c_uint, ct.c_char_p, ct.c_uint]
106_RAW_CB_TYPE = ct.CFUNCTYPE(None, ct.py_object, ct.c_void_p, ct.c_int)
107_LOST_CB_TYPE = ct.CFUNCTYPE(None, ct.py_object, ct.c_ulonglong)
108lib.bpf_attach_kprobe.restype = ct.c_int
109lib.bpf_attach_kprobe.argtypes = [ct.c_int, ct.c_int, ct.c_char_p, ct.c_char_p,
110        ct.c_ulonglong, ct.c_int]
111lib.bpf_detach_kprobe.restype = ct.c_int
112lib.bpf_detach_kprobe.argtypes = [ct.c_char_p]
113lib.bpf_attach_uprobe.restype = ct.c_int
114lib.bpf_attach_uprobe.argtypes = [ct.c_int, ct.c_int, ct.c_char_p, ct.c_char_p,
115        ct.c_ulonglong, ct.c_int]
116lib.bpf_detach_uprobe.restype = ct.c_int
117lib.bpf_detach_uprobe.argtypes = [ct.c_char_p]
118lib.bpf_attach_tracepoint.restype = ct.c_int
119lib.bpf_attach_tracepoint.argtypes = [ct.c_int, ct.c_char_p, ct.c_char_p]
120lib.bpf_detach_tracepoint.restype = ct.c_int
121lib.bpf_detach_tracepoint.argtypes = [ct.c_char_p, ct.c_char_p]
122lib.bpf_attach_raw_tracepoint.restype = ct.c_int
123lib.bpf_attach_raw_tracepoint.argtypes = [ct.c_int, ct.c_char_p]
124lib.bpf_attach_kfunc.restype = ct.c_int
125lib.bpf_attach_kfunc.argtypes = [ct.c_int]
126lib.bpf_attach_lsm.restype = ct.c_int
127lib.bpf_attach_lsm.argtypes = [ct.c_int]
128lib.bpf_prog_attach.restype = ct.c_int
129lib.bpf_prog_attach.argtype = [ct.c_int, ct.c_int, ct.c_int, ct.c_uint]
130lib.bpf_prog_detach2.restype = ct.c_int
131lib.bpf_prog_detach2.argtype = [ct.c_int, ct.c_int, ct.c_int]
132lib.bpf_has_kernel_btf.restype = ct.c_bool
133lib.bpf_has_kernel_btf.argtypes = None
134lib.kernel_struct_has_field.restype = ct.c_int
135lib.kernel_struct_has_field.argtypes = [ct.c_char_p, ct.c_char_p]
136lib.bpf_open_perf_buffer.restype = ct.c_void_p
137lib.bpf_open_perf_buffer.argtypes = [_RAW_CB_TYPE, _LOST_CB_TYPE, ct.py_object, ct.c_int, ct.c_int, ct.c_int]
138
139class bcc_perf_buffer_opts(ct.Structure):
140    _fields_ = [
141        ('pid', ct.c_int),
142        ('cpu', ct.c_int),
143        ('wakeup_events', ct.c_int),
144    ]
145
146lib.bpf_open_perf_buffer_opts.restype = ct.c_void_p
147lib.bpf_open_perf_buffer_opts.argtypes = [_RAW_CB_TYPE, _LOST_CB_TYPE, ct.py_object, ct.c_int, ct.POINTER(bcc_perf_buffer_opts)]
148lib.bpf_open_perf_event.restype = ct.c_int
149lib.bpf_open_perf_event.argtypes = [ct.c_uint, ct.c_ulonglong, ct.c_int, ct.c_int]
150lib.perf_reader_poll.restype = ct.c_int
151lib.perf_reader_poll.argtypes = [ct.c_int, ct.POINTER(ct.c_void_p), ct.c_int]
152lib.perf_reader_consume.restype = ct.c_int
153lib.perf_reader_consume.argtypes = [ct.c_int, ct.POINTER(ct.c_void_p)]
154lib.perf_reader_free.restype = None
155lib.perf_reader_free.argtypes = [ct.c_void_p]
156lib.perf_reader_fd.restype = int
157lib.perf_reader_fd.argtypes = [ct.c_void_p]
158
159lib.bpf_attach_xdp.restype = ct.c_int
160lib.bpf_attach_xdp.argtypes = [ct.c_char_p, ct.c_int, ct.c_uint]
161
162lib.bpf_attach_perf_event.restype = ct.c_int
163lib.bpf_attach_perf_event.argtype = [ct.c_int, ct.c_uint, ct.c_uint, ct.c_ulonglong, ct.c_ulonglong,
164        ct.c_int, ct.c_int, ct.c_int]
165
166lib.bpf_attach_perf_event_raw.restype = ct.c_int
167lib.bpf_attach_perf_event_raw.argtype = [Perf.perf_event_attr(), ct.c_uint, ct.c_uint, ct.c_uint, ct.c_uint]
168
169lib.bpf_close_perf_event_fd.restype = ct.c_int
170lib.bpf_close_perf_event_fd.argtype = [ct.c_int]
171
172_RINGBUF_CB_TYPE = ct.CFUNCTYPE(ct.c_int, ct.c_void_p, ct.c_void_p, ct.c_int)
173lib.bpf_new_ringbuf.restype = ct.c_void_p
174lib.bpf_new_ringbuf.argtypes = [ct.c_int, _RINGBUF_CB_TYPE, ct.c_void_p]
175lib.bpf_free_ringbuf.restype = None
176lib.bpf_free_ringbuf.argtypes = [ct.c_void_p]
177lib.bpf_add_ringbuf.restype = ct.c_int
178lib.bpf_add_ringbuf.argtypes = [ct.c_void_p, ct.c_int, _RINGBUF_CB_TYPE, ct.c_void_p]
179lib.bpf_poll_ringbuf.restype = ct.c_int
180lib.bpf_poll_ringbuf.argtypes = [ct.c_void_p, ct.c_int]
181lib.bpf_consume_ringbuf.restype = ct.c_int
182lib.bpf_consume_ringbuf.argtypes = [ct.c_void_p]
183
184# bcc symbol helpers
185class bcc_symbol(ct.Structure):
186    _fields_ = [
187            ('name', ct.c_char_p),
188            ('demangle_name', ct.c_char_p),
189            ('module', ct.POINTER(ct.c_char)),
190            ('offset', ct.c_ulonglong),
191        ]
192
193class bcc_ip_offset_union(ct.Union):
194  _fields_ = [
195          ('offset', ct.c_uint64),
196          ('ip', ct.c_uint64)
197        ]
198
199class bcc_stacktrace_build_id(ct.Structure):
200    _fields_ = [
201            ('status', ct.c_uint32),
202            ('build_id',ct.c_ubyte*20),
203            ('u',bcc_ip_offset_union)
204         ]
205
206class bcc_symbol_option(ct.Structure):
207    _fields_ = [
208            ('use_debug_file', ct.c_int),
209            ('check_debug_file_crc', ct.c_int),
210            ('lazy_symbolize', ct.c_int),
211            ('use_symbol_type', ct.c_uint),
212        ]
213
214lib.bcc_procutils_which_so.restype = ct.POINTER(ct.c_char)
215lib.bcc_procutils_which_so.argtypes = [ct.c_char_p, ct.c_int]
216lib.bcc_procutils_free.restype = None
217lib.bcc_procutils_free.argtypes = [ct.c_void_p]
218lib.bcc_procutils_language.restype = ct.POINTER(ct.c_char)
219lib.bcc_procutils_language.argtypes = [ct.c_int]
220
221lib.bcc_resolve_symname.restype = ct.c_int
222lib.bcc_resolve_symname.argtypes = [
223    ct.c_char_p, ct.c_char_p, ct.c_ulonglong, ct.c_int, ct.POINTER(bcc_symbol_option), ct.POINTER(bcc_symbol)]
224
225_SYM_CB_TYPE = ct.CFUNCTYPE(ct.c_int, ct.c_char_p, ct.c_ulonglong)
226lib.bcc_foreach_function_symbol.restype = ct.c_int
227lib.bcc_foreach_function_symbol.argtypes = [ct.c_char_p, _SYM_CB_TYPE]
228
229lib.bcc_symcache_new.restype = ct.c_void_p
230lib.bcc_symcache_new.argtypes = [ct.c_int, ct.POINTER(bcc_symbol_option)]
231
232lib.bcc_free_symcache.restype = ct.c_void_p
233lib.bcc_free_symcache.argtypes = [ct.c_void_p, ct.c_int]
234
235lib.bcc_buildsymcache_new.restype = ct.c_void_p
236lib.bcc_buildsymcache_new.argtypes = None
237
238lib.bcc_free_buildsymcache.restype = None
239lib.bcc_free_buildsymcache.argtypes = [ct.c_void_p]
240
241lib.bcc_buildsymcache_add_module.restype = ct.c_int
242lib.bcc_buildsymcache_add_module.argtypes = [ct.c_void_p, ct.c_char_p]
243
244lib.bcc_buildsymcache_resolve.restype = ct.c_int
245lib.bcc_buildsymcache_resolve.argtypes = [ct.c_void_p, ct.POINTER(bcc_stacktrace_build_id), ct.POINTER(bcc_symbol)]
246
247lib.bcc_symbol_free_demangle_name.restype = ct.c_void_p
248lib.bcc_symbol_free_demangle_name.argtypes = [ct.POINTER(bcc_symbol)]
249
250lib.bcc_symcache_resolve.restype = ct.c_int
251lib.bcc_symcache_resolve.argtypes = [ct.c_void_p, ct.c_ulonglong, ct.POINTER(bcc_symbol)]
252
253lib.bcc_symcache_resolve_no_demangle.restype = ct.c_int
254lib.bcc_symcache_resolve_no_demangle.argtypes = [ct.c_void_p, ct.c_ulonglong, ct.POINTER(bcc_symbol)]
255
256lib.bcc_symcache_resolve_name.restype = ct.c_int
257lib.bcc_symcache_resolve_name.argtypes = [
258    ct.c_void_p, ct.c_char_p, ct.c_char_p, ct.POINTER(ct.c_ulonglong)]
259
260lib.bcc_symcache_refresh.restype = None
261lib.bcc_symcache_refresh.argtypes = [ct.c_void_p]
262
263lib.bcc_free_memory.restype = ct.c_int
264lib.bcc_free_memory.argtypes = None
265
266lib.bcc_usdt_new_frompid.restype = ct.c_void_p
267lib.bcc_usdt_new_frompid.argtypes = [ct.c_int, ct.c_char_p]
268
269lib.bcc_usdt_new_frompath.restype = ct.c_void_p
270lib.bcc_usdt_new_frompath.argtypes = [ct.c_char_p]
271
272lib.bcc_usdt_close.restype = None
273lib.bcc_usdt_close.argtypes = [ct.c_void_p]
274
275lib.bcc_usdt_enable_probe.restype = ct.c_int
276lib.bcc_usdt_enable_probe.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_char_p]
277
278lib.bcc_usdt_enable_fully_specified_probe.restype = ct.c_int
279lib.bcc_usdt_enable_fully_specified_probe.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_char_p, ct.c_char_p]
280
281lib.bcc_usdt_genargs.restype = ct.c_char_p
282lib.bcc_usdt_genargs.argtypes = [ct.POINTER(ct.c_void_p), ct.c_int]
283
284lib.bcc_usdt_get_probe_argctype.restype = ct.c_char_p
285lib.bcc_usdt_get_probe_argctype.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_int]
286
287lib.bcc_usdt_get_fully_specified_probe_argctype.restype = ct.c_char_p
288lib.bcc_usdt_get_fully_specified_probe_argctype.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_char_p, ct.c_int]
289
290class bcc_usdt(ct.Structure):
291    _fields_ = [
292            ('provider', ct.c_char_p),
293            ('name', ct.c_char_p),
294            ('bin_path', ct.c_char_p),
295            ('semaphore', ct.c_ulonglong),
296            ('num_locations', ct.c_int),
297            ('num_arguments', ct.c_int),
298        ]
299
300class bcc_usdt_location(ct.Structure):
301    _fields_ = [
302            ('address', ct.c_ulonglong),
303            ('bin_path', ct.c_char_p),
304        ]
305
306class BCC_USDT_ARGUMENT_FLAGS(object):
307    NONE = 0x0
308    CONSTANT = 0x1
309    DEREF_OFFSET = 0x2
310    DEREF_IDENT = 0x4
311    BASE_REGISTER_NAME = 0x8
312    INDEX_REGISTER_NAME = 0x10
313    SCALE = 0x20
314
315class bcc_usdt_argument(ct.Structure):
316    _fields_ = [
317            ('size', ct.c_int),
318            ('valid', ct.c_int),
319            ('constant', ct.c_longlong),
320            ('deref_offset', ct.c_int),
321            ('deref_ident', ct.c_char_p),
322            ('base_register_name', ct.c_char_p),
323            ('index_register_name', ct.c_char_p),
324            ('scale', ct.c_int)
325        ]
326
327_USDT_CB = ct.CFUNCTYPE(None, ct.POINTER(bcc_usdt))
328
329lib.bcc_usdt_foreach.restype = None
330lib.bcc_usdt_foreach.argtypes = [ct.c_void_p, _USDT_CB]
331
332lib.bcc_usdt_get_location.restype = ct.c_int
333lib.bcc_usdt_get_location.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_char_p, ct.c_int,
334                                      ct.POINTER(bcc_usdt_location)]
335
336lib.bcc_usdt_get_argument.restype = ct.c_int
337lib.bcc_usdt_get_argument.argtypes = [ct.c_void_p, ct.c_char_p, ct.c_char_p, ct.c_int,
338                                      ct.c_int, ct.POINTER(bcc_usdt_argument)]
339
340_USDT_PROBE_CB = ct.CFUNCTYPE(None, ct.c_char_p, ct.c_char_p,
341                              ct.c_ulonglong, ct.c_int)
342
343lib.bcc_usdt_foreach_uprobe.restype = None
344lib.bcc_usdt_foreach_uprobe.argtypes = [ct.c_void_p, _USDT_PROBE_CB]
345