From: Teng Qin Date: Thu, 4 May 2017 07:09:20 +0000 (-0700) Subject: Add option to control bcc_elf_foreach_sym behavior X-Git-Tag: submit/tizen_4.0/20171018.110122~108^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0336a290ebff88bd4c547cf09e653959e342406c;p=platform%2Fupstream%2Fbcc.git Add option to control bcc_elf_foreach_sym behavior This commit adds a `bcc_symbol_option` to configure various symboling behaviors. Currently added options for reading debug file, and what type of symbols are wanted. This commit also makes bcc_elf_foreach_sym take a `bcc_symbol_option` parameter and repect the specified configurations. --- diff --git a/src/cc/bcc_elf.c b/src/cc/bcc_elf.c index 8540a605..4b742eba 100644 --- a/src/cc/bcc_elf.c +++ b/src/cc/bcc_elf.c @@ -26,7 +26,10 @@ #include #include "bcc_elf.h" +#include "bcc_syms.h" + #define NT_STAPSDT 3 +#define ELF_ST_TYPE(x) (((uint32_t) x) & 0xf) static int openelf(const char *path, Elf **elf_out, int *fd_out) { if (elf_version(EV_CURRENT) == EV_NONE) @@ -150,6 +153,7 @@ int bcc_elf_foreach_usdt(const char *path, bcc_elf_probecb callback, } static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize, + struct bcc_symbol_option *option, bcc_elf_symcb callback, void *payload) { Elf_Data *data = NULL; @@ -168,6 +172,15 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize, if ((name = elf_strptr(e, stridx, sym.st_name)) == NULL) continue; + if (name[0] == 0) + continue; + + if (sym.st_value == 0) + continue; + + uint32_t flag = 1 << ELF_ST_TYPE(sym.st_info); + if (!(option->use_symbol_type & flag)) + continue; if (callback(name, sym.st_value, sym.st_size, sym.st_info, payload) < 0) return 1; // signal termination to caller @@ -177,7 +190,8 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize, return 0; } -static int listsymbols(Elf *e, bcc_elf_symcb callback, void *payload) { +static int listsymbols(Elf *e, bcc_elf_symcb callback, void *payload, + struct bcc_symbol_option *option) { Elf_Scn *section = NULL; while ((section = elf_nextscn(e, section)) != 0) { @@ -190,7 +204,7 @@ static int listsymbols(Elf *e, bcc_elf_symcb callback, void *payload) { continue; int rc = list_in_scn(e, section, header.sh_link, header.sh_entsize, - callback, payload); + option, callback, payload); if (rc == 1) break; // callback signaled termination @@ -347,7 +361,8 @@ static int verify_checksum(const char *file, unsigned int crc) { return actual == crc; } -static char *find_debug_via_debuglink(Elf *e, const char *binpath) { +static char *find_debug_via_debuglink(Elf *e, const char *binpath, + int check_crc) { char fullpath[PATH_MAX]; char *bindir = NULL; char *res = NULL; @@ -386,9 +401,9 @@ static char *find_debug_via_debuglink(Elf *e, const char *binpath) { DONE: free(bindir); - if (verify_checksum(res, crc)) - return res; - return NULL; + if (check_crc && !verify_checksum(res, crc)) + return NULL; + return res; } static char *find_debug_via_buildid(Elf *e) { @@ -412,11 +427,15 @@ static char *find_debug_via_buildid(Elf *e) { } static int foreach_sym_core(const char *path, bcc_elf_symcb callback, - void *payload, int is_debug_file) { + struct bcc_symbol_option *option, void *payload, + int is_debug_file) { Elf *e; int fd, res; char *debug_file; + if (!option) + return -1; + if (openelf(path, &e, &fd) < 0) return -1; @@ -424,27 +443,29 @@ static int foreach_sym_core(const char *path, bcc_elf_symcb callback, // using the build-id section, then using the debuglink section. These are // also the rules that GDB folows. // See: https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html - if (!is_debug_file) { + if (option->use_debug_file && !is_debug_file) { // The is_debug_file argument helps avoid infinitely resolving debuginfo // files for debuginfo files and so on. debug_file = find_debug_via_buildid(e); if (!debug_file) - debug_file = find_debug_via_debuglink(e, path); + debug_file = find_debug_via_debuglink(e, path, + option->check_debug_file_crc); if (debug_file) { - foreach_sym_core(debug_file, callback, payload, 1); + foreach_sym_core(debug_file, callback, option, payload, 1); free(debug_file); } } - res = listsymbols(e, callback, payload); + res = listsymbols(e, callback, payload, option); elf_end(e); close(fd); return res; } int bcc_elf_foreach_sym(const char *path, bcc_elf_symcb callback, - void *payload) { - return foreach_sym_core(path, callback, payload, 0); + void *option, void *payload) { + return foreach_sym_core( + path, callback, (struct bcc_symbol_option*)option, payload, 0); } static int loadaddr(Elf *e, uint64_t *addr) { diff --git a/src/cc/bcc_elf.h b/src/cc/bcc_elf.h index e87b037f..bece5867 100644 --- a/src/cc/bcc_elf.h +++ b/src/cc/bcc_elf.h @@ -40,7 +40,7 @@ int bcc_elf_foreach_usdt(const char *path, bcc_elf_probecb callback, void *payload); int bcc_elf_loadaddr(const char *path, uint64_t *address); int bcc_elf_foreach_sym(const char *path, bcc_elf_symcb callback, - void *payload); + void *option, void *payload); int bcc_elf_get_type(const char *path); int bcc_elf_is_shared_obj(const char *path); diff --git a/src/cc/bcc_syms.h b/src/cc/bcc_syms.h index 46f477ec..bb5aa05b 100644 --- a/src/cc/bcc_syms.h +++ b/src/cc/bcc_syms.h @@ -31,6 +31,14 @@ struct bcc_symbol { typedef int (*SYM_CB)(const char *symname, uint64_t addr); +static const uint32_t BCC_SYM_ALL_TYPES = 65535; +struct bcc_symbol_option { + int use_debug_file; + int check_debug_file_crc; + // Bitmask flags indicating what types of ELF symbols to use + uint32_t use_symbol_type; +}; + void *bcc_symcache_new(int pid); void bcc_free_symcache(void *symcache, int pid); diff --git a/src/lua/bcc/libbcc.lua b/src/lua/bcc/libbcc.lua index ef95074b..b00277ec 100644 --- a/src/lua/bcc/libbcc.lua +++ b/src/lua/bcc/libbcc.lua @@ -114,6 +114,12 @@ struct bcc_symbol { uint64_t offset; }; +struct bcc_symbol_option { + int use_debug_file; + int check_debug_file_crc; + uint32_t use_symbol_type; +}; + int bcc_resolve_symname(const char *module, const char *symname, const uint64_t addr, int pid, struct bcc_symbol *sym); void bcc_procutils_free(const char *ptr); diff --git a/src/python/bcc/libbcc.py b/src/python/bcc/libbcc.py index 0bba2c65..0c87214d 100644 --- a/src/python/bcc/libbcc.py +++ b/src/python/bcc/libbcc.py @@ -133,6 +133,13 @@ class bcc_symbol(ct.Structure): ('offset', ct.c_ulonglong), ] +class bcc_symbol_option(ct.Structure): + _fields_ = [ + ('use_debug_file', ct.c_int), + ('check_debug_file_crc', ct.c_int), + ('use_symbol_type', ct.c_uint), + ] + lib.bcc_procutils_which_so.restype = ct.POINTER(ct.c_char) lib.bcc_procutils_which_so.argtypes = [ct.c_char_p, ct.c_int] lib.bcc_procutils_free.restype = None