diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py index 5b3ff7b2c559..0aea600033ca 100644 --- a/src/python/bcc/__init__.py +++ b/src/python/bcc/__init__.py @@ -26,7 +26,7 @@ from .libbcc import lib, bcc_symbol, bcc_symbol_option, bcc_stacktrace_build_id, _SYM_CB_TYPE from .table import Table, PerfEventArray from .perf import Perf -from .utils import get_online_cpus, printb, _assert_is_bytes, ArgString +from .utils import get_online_cpus, printb, _assert_is_bytes, ArgString, StrcmpRewrite from .version import __version__ from .disassembler import disassemble_prog, decode_map diff --git a/src/python/bcc/utils.py b/src/python/bcc/utils.py index ef6f81d88db8..45205423383d 100644 --- a/src/python/bcc/utils.py +++ b/src/python/bcc/utils.py @@ -15,6 +15,7 @@ import sys import traceback import warnings +import re from .libbcc import lib @@ -97,3 +98,50 @@ def _assert_is_bytes(arg): return ArgString(arg).__bytes__() return arg +class StrcmpRewrite(object): + @staticmethod + def _generate_streq_function(string, probe_read_func, streq_functions, + probeid): + fname = "streq_%d" % probeid + streq_functions += """ +static inline bool %s(char const *ignored, uintptr_t str) { + char needle[] = %s; + char haystack[sizeof(needle)]; + %s(&haystack, sizeof(haystack), (void *)str); + for (int i = 0; i < sizeof(needle) - 1; ++i) { + if (needle[i] != haystack[i]) { + return false; + } + } + return true; +} + """ % (fname, string, probe_read_func) + return fname, streq_functions + + @staticmethod + def rewrite_expr(expr, bin_cmp, is_user, probe_user_list, streq_functions, + probeid): + if bin_cmp: + STRCMP_RE = 'STRCMP\\(\"([^"]+)\\",(.+?)\\)' + else: + STRCMP_RE = 'STRCMP\\(("[^"]+\\"),(.+?)\\)' + matches = re.finditer(STRCMP_RE, expr) + for match in matches: + string = match.group(1) + probe_read_func = "bpf_probe_read" + # if user probe or @user tag is specified, use + # bpf_probe_read_user for char* read + if is_user or \ + match.group(2).strip() in probe_user_list: + probe_read_func = "bpf_probe_read_user" + fname, streq_functions = StrcmpRewrite._generate_streq_function( + string, probe_read_func, + streq_functions, probeid) + probeid += 1 + expr = expr.replace("STRCMP", fname, 1) + rdict = { + "expr" : expr, + "streq_functions" : streq_functions, + "probeid" : probeid + } + return rdict