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