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  }