github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/agent/ebpfspy/symtab/bcc.go (about) 1 //go:build ebpfspy 2 3 package symtab 4 5 import ( 6 "debug/elf" 7 "unsafe" 8 ) 9 10 /* 11 #include "bcc_syms/bcc_syms.h" 12 */ 13 import "C" 14 15 type BCCSymTable struct { 16 cache unsafe.Pointer 17 pid int 18 } 19 20 func NewBCCSymbolTable(pid int) *BCCSymTable { 21 pidC := C.int(pid) 22 if pid == 0 { 23 pidC = C.int(-1) // for KSyms 24 } 25 symbolOpt := C.struct_bcc_symbol_option{use_symbol_type: C.uint(1 << elf.STT_FUNC)} 26 symbolOptC := (*C.struct_bcc_symbol_option)(unsafe.Pointer(&symbolOpt)) 27 cache := C.bcc_symcache_new(pidC, symbolOptC) 28 29 res := &BCCSymTable{cache: cache, pid: pid} 30 return res 31 } 32 33 func (t *BCCSymTable) Resolve(addr uint64, refresh bool) Symbol { 34 symbol := C.struct_bcc_symbol{} 35 var symbolC = (*C.struct_bcc_symbol)(unsafe.Pointer(&symbol)) 36 37 var res C.int 38 if t.pid == 0 { 39 res = C.bcc_symcache_resolve_no_demangle(t.cache, C.ulong(addr), symbolC, C.bool(refresh)) 40 } else { 41 res = C.bcc_symcache_resolve(t.cache, C.ulong(addr), symbolC, C.bool(refresh)) 42 defer C.bcc_symbol_free_demangle_name(symbolC) 43 } 44 if res < 0 { 45 if symbol.offset > 0 { 46 return Symbol{"", C.GoString(symbol.module), uint64(symbol.offset)} 47 } 48 return Symbol{"", "", addr} 49 } 50 if t.pid == 0 { 51 return Symbol{C.GoString(symbol.name), C.GoString(symbol.module), uint64(symbol.offset)} 52 } 53 return Symbol{C.GoString(symbol.demangle_name), C.GoString(symbol.module), uint64(symbol.offset)} 54 } 55 56 func (t *BCCSymTable) Close() { 57 C.bcc_free_symcache(t.cache, C.int(t.pid)) 58 }