[trace.py]: allow to use STRCMP helper with binary values (#1900)

* [trace.py]: allow to use STRCMP helper with binary values

Summary:
sometimes in probe you want to compare char* w/ some predefined value
which is not a string. e.g. setsockopt syscall has signature like this:
sys_setsockopt(int fd, int level, int optname, char* optval, int optlen)
and if you want to catch where/who is setting up specific value you are
forced to compare optval against some predefined array. it's not
possible today w/ trace.py and in this diff i'm adding such ability

Test Plan:
as example: we want to catch setsockopt when someone is setting up
IP_TOS equal to 108
trace.py 'sys_setsockopt(int fd, int level, int optname, char* optval,
int optlen)(level==0 && optname == 1 && STRCMP("{0x6C,0x00, 0x00,
0x00}", optval))' -U -M 1 --bin_cmp -v

without this new modifier:
static inline bool streq_0(char const *ignored, uintptr_t str) {
        char needle[] = "{0x6C,0x00, 0x00, 0x00}";
        char haystack[sizeof(needle)];
        bpf_probe_read(&haystack, sizeof(haystack), (void *)str);
        for (int i = 0; i < sizeof(needle) - 1; ++i) {
                if (needle[i] != haystack[i]) {
                        return false;
                }
        }
        return true;
}

// see needle is qouted above

with:

tatic inline bool streq_0(char const *ignored, uintptr_t str) {
        char needle[] = {0x6C,0x00, 0x00, 0x00};
        char haystack[sizeof(needle)];
        bpf_probe_read(&haystack, sizeof(haystack), (void *)str);
        for (int i = 0; i < sizeof(needle) - 1; ++i) {
                if (needle[i] != haystack[i]) {
                        return false;
                }
        }
        return true;
}

...
PID     TID     COMM            FUNC             -
1855611 1863183 worker          sys_setsockopt   found

* adding example of --bin_cmp flag usage
diff --git a/tools/trace.py b/tools/trace.py
index 549fb20..051ba9b 100755
--- a/tools/trace.py
+++ b/tools/trace.py
@@ -48,6 +48,7 @@
                 cls.tgid = args.tgid or -1
                 cls.pid = args.pid or -1
                 cls.page_cnt = args.buffer_pages
+                cls.bin_cmp = args.bin_cmp
 
         def __init__(self, probe, string_size, kernel_stack, user_stack):
                 self.usdt = None
@@ -271,7 +272,11 @@
                         expr = expr.replace(alias, replacement)
                 for alias, replacement in Probe.aliases_common.items():
                     expr = expr.replace(alias, replacement)
-                matches = re.finditer('STRCMP\\(("[^"]+\\")', expr)
+                if self.bin_cmp:
+                    STRCMP_RE = 'STRCMP\\(\"([^"]+)\\"'
+                else:
+                    STRCMP_RE = 'STRCMP\\(("[^"]+\\")'
+                matches = re.finditer(STRCMP_RE, expr)
                 for match in matches:
                         string = match.group(1)
                         fname = self._generate_streq_function(string)
@@ -680,6 +685,8 @@
                   help="print time column")
                 parser.add_argument("-C", "--print_cpu", action="store_true",
                   help="print CPU id")
+                parser.add_argument("-B", "--bin_cmp", action="store_true",
+                  help="allow to use STRCMP with binary values")
                 parser.add_argument("-K", "--kernel-stack",
                   action="store_true", help="output kernel stack trace")
                 parser.add_argument("-U", "--user-stack",