diff --git a/.bcc.metadata b/.bcc.metadata
new file mode 100644
index 0000000..933df45
--- /dev/null
+++ b/.bcc.metadata
@@ -0,0 +1 @@
+d5a11c0da3483cad478f6971cbfc9b0eb1bdc932 SOURCES/bcc-0.7.0.tar.gz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6f4147b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/bcc-0.7.0.tar.gz
diff --git a/SOURCES/Bytes-string-encoding-2004.patch b/SOURCES/Bytes-string-encoding-2004.patch
new file mode 100644
index 0000000..5597057
--- /dev/null
+++ b/SOURCES/Bytes-string-encoding-2004.patch
@@ -0,0 +1,791 @@
+From b96ebcd2f328cd694101d657341faeb5869556a9 Mon Sep 17 00:00:00 2001
+From: jeromemarchand <38073585+jeromemarchand@users.noreply.github.com>
+Date: Wed, 10 Oct 2018 01:58:15 +0200
+Subject: [PATCH] Bytes/string encoding (#2004)
+
+* tools: uses 'replace' error handler by default in decode()
+
+Tools might encouter characters from non utf-8 charset (e.g. a file
+name). When this happen, it's better to replace the unexpected
+character by a question mark than crash the tool when all we do is
+to print the string.
+
+* tools: fix a bytes/string issue in attach_perf_event()
+---
+ tools/bashreadline.py   |  2 +-
+ tools/biosnoop.py       |  4 ++--
+ tools/biotop.py         |  4 ++--
+ tools/btrfsslower.py    | 10 ++++++----
+ tools/cachetop.py       |  2 +-
+ tools/capable.py        |  4 ++--
+ tools/dcsnoop.py        |  5 +++--
+ tools/ext4slower.py     | 10 ++++++----
+ tools/filelife.py       |  3 ++-
+ tools/fileslower.py     |  6 +++---
+ tools/filetop.py        |  7 ++++---
+ tools/funcslower.py     |  4 ++--
+ tools/gethostlatency.py |  4 ++--
+ tools/hardirqs.py       |  2 +-
+ tools/llcstat.py        |  2 +-
+ tools/mdflush.py        |  3 ++-
+ tools/mountsnoop.py     |  4 ++--
+ tools/nfsslower.py      |  4 ++--
+ tools/offcputime.py     |  4 ++--
+ tools/offwaketime.py    |  8 ++++----
+ tools/old/offcputime.py |  2 +-
+ tools/old/oomkill.py    |  4 ++--
+ tools/old/profile.py    |  2 +-
+ tools/old/wakeuptime.py |  8 ++++----
+ tools/oomkill.py        |  4 ++--
+ tools/opensnoop.py      |  3 ++-
+ tools/profile.py        |  8 ++++----
+ tools/sslsniff.py       |  5 +++--
+ tools/stackcount.py     |  2 +-
+ tools/statsnoop.py      |  5 +++--
+ tools/tcpaccept.py      |  7 ++++---
+ tools/tcpconnect.py     |  7 ++++---
+ tools/tcpconnlat.py     |  8 ++++----
+ tools/tcplife.py        |  4 ++--
+ tools/tcpstates.py      |  4 ++--
+ tools/tcptracer.py      |  4 ++--
+ tools/trace.py          |  3 ++-
+ tools/ttysnoop.py       |  2 +-
+ tools/zfsslower.py      | 10 ++++++----
+ 39 files changed, 100 insertions(+), 84 deletions(-)
+
+diff --git a/tools/bashreadline.py b/tools/bashreadline.py
+index aaf6fc7..89c37c3 100755
+--- a/tools/bashreadline.py
++++ b/tools/bashreadline.py
+@@ -57,7 +57,7 @@ print("%-9s %-6s %s" % ("TIME", "PID", "COMMAND"))
+ def print_event(cpu, data, size):
+     event = ct.cast(data, ct.POINTER(Data)).contents
+     print("%-9s %-6d %s" % (strftime("%H:%M:%S"), event.pid,
+-                            event.str.decode()))
++                            event.str.decode('utf-8', 'replace')))
+ 
+ b["events"].open_perf_buffer(print_event)
+ while 1:
+diff --git a/tools/biosnoop.py b/tools/biosnoop.py
+index 7f61180..2b1e77d 100755
+--- a/tools/biosnoop.py
++++ b/tools/biosnoop.py
+@@ -176,8 +176,8 @@ delta = 0
+         delta = float(delta) + (event.ts - prev_ts)
+ 
+     print("%-14.9f %-14.14s %-6s %-7s %-2s %-9s %-7s %7.2f" % (
+-        delta / 1000000, event.name.decode(), event.pid,
+-        event.disk_name.decode(), rwflg, val,
++        delta / 1000000, event.name.decode('utf-8', 'replace'), event.pid,
++        event.disk_name.decode('utf-8', 'replace'), rwflg, val,
+         event.len, float(event.delta) / 1000000))
+ 
+     prev_ts = event.ts
+diff --git a/tools/biotop.py b/tools/biotop.py
+index 63d6642..c6e1ca2 100755
+--- a/tools/biotop.py
++++ b/tools/biotop.py
+@@ -221,8 +221,8 @@ exiting = 0
+         # print line
+         avg_ms = (float(v.us) / 1000) / v.io
+         print("%-6d %-16s %1s %-3d %-3d %-8s %5s %7s %6.2f" % (k.pid,
+-            k.name.decode(), "W" if k.rwflag else "R", k.major, k.minor,
+-            diskname, v.io, v.bytes / 1024, avg_ms))
++            k.name.decode('utf-8', 'replace'), "W" if k.rwflag else "R",
++            k.major, k.minor, diskname, v.io, v.bytes / 1024, avg_ms))
+ 
+         line += 1
+         if line >= maxrows:
+diff --git a/tools/btrfsslower.py b/tools/btrfsslower.py
+index 644cb22..d48e04c 100755
+--- a/tools/btrfsslower.py
++++ b/tools/btrfsslower.py
+@@ -316,12 +316,14 @@ TASK_COMM_LEN = 16      # linux/sched.h
+ 
+     if (csv):
+         print("%d,%s,%d,%s,%d,%d,%d,%s" % (
+-            event.ts_us, event.task.decode(), event.pid, type, event.size,
+-            event.offset, event.delta_us, event.file.decode()))
++            event.ts_us, event.task.decode('utf-8', 'replace'), event.pid,
++            type, event.size, event.offset, event.delta_us,
++            event.file.decode('utf-8', 'replace')))
+         return
+     print("%-8s %-14.14s %-6s %1s %-7s %-8d %7.2f %s" % (strftime("%H:%M:%S"),
+-        event.task.decode(), event.pid, type, event.size, event.offset / 1024,
+-        float(event.delta_us) / 1000, event.file.decode()))
++        event.task.decode('utf-8', 'replace'), event.pid, type, event.size,
++        event.offset / 1024, float(event.delta_us) / 1000,
++        event.file.decode('utf-8', 'replace')))
+ 
+ # initialize BPF
+ b = BPF(text=bpf_text)
+diff --git a/tools/cachetop.py b/tools/cachetop.py
+index 0e08af9..1013675 100755
+--- a/tools/cachetop.py
++++ b/tools/cachetop.py
+@@ -72,7 +72,7 @@ def get_processes_stats(
+     counts = bpf.get_table("counts")
+     stats = defaultdict(lambda: defaultdict(int))
+     for k, v in counts.items():
+-        stats["%d-%d-%s" % (k.pid, k.uid, k.comm.decode())][k.ip] = v.value
++        stats["%d-%d-%s" % (k.pid, k.uid, k.comm.decode('utf-8', 'replace'))][k.ip] = v.value
+     stats_list = []
+ 
+     for pid, count in sorted(stats.items(), key=lambda stat: stat[0]):
+diff --git a/tools/capable.py b/tools/capable.py
+index 3e032e9..efcff4d 100755
+--- a/tools/capable.py
++++ b/tools/capable.py
+@@ -148,8 +148,8 @@ print("%-9s %-6s %-6s %-16s %-4s %-20s %s" % (
+     else:
+         name = "?"
+     print("%-9s %-6d %-6d %-16s %-4d %-20s %d" % (strftime("%H:%M:%S"),
+-        event.uid, event.pid, event.comm.decode(), event.cap, name,
+-        event.audit))
++        event.uid, event.pid, event.comm.decode('utf-8', 'replace'),
++        event.cap, name, event.audit))
+ 
+ # loop with callback to print_event
+ b["events"].open_perf_buffer(print_event)
+diff --git a/tools/dcsnoop.py b/tools/dcsnoop.py
+index 070c87a..13152c2 100755
+--- a/tools/dcsnoop.py
++++ b/tools/dcsnoop.py
+@@ -153,8 +153,9 @@ start_ts = time.time()
+ def print_event(cpu, data, size):
+     event = ct.cast(data, ct.POINTER(Data)).contents
+     print("%-11.6f %-6d %-16s %1s %s" % (
+-            time.time() - start_ts, event.pid, event.comm.decode(),
+-            mode_s[event.type], event.filename.decode()))
++            time.time() - start_ts, event.pid,
++            event.comm.decode('utf-8', 'replace'), mode_s[event.type],
++            event.filename.decode('utf-8', 'replace')))
+ 
+ # header
+ print("%-11s %-6s %-16s %1s %s" % ("TIME(s)", "PID", "COMM", "T", "FILE"))
+diff --git a/tools/ext4slower.py b/tools/ext4slower.py
+index eb6430e..88db831 100755
+--- a/tools/ext4slower.py
++++ b/tools/ext4slower.py
+@@ -314,12 +314,14 @@ TASK_COMM_LEN = 16      # linux/sched.h
+ 
+     if (csv):
+         print("%d,%s,%d,%s,%d,%d,%d,%s" % (
+-            event.ts_us, event.task.decode(), event.pid, type, event.size,
+-            event.offset, event.delta_us, event.file.decode()))
++            event.ts_us, event.task.decode('utf-8', 'replace'), event.pid,
++            type, event.size, event.offset, event.delta_us,
++            event.file.decode('utf-8', 'replace')))
+         return
+     print("%-8s %-14.14s %-6s %1s %-7s %-8d %7.2f %s" % (strftime("%H:%M:%S"),
+-        event.task.decode(), event.pid, type, event.size, event.offset / 1024,
+-        float(event.delta_us) / 1000, event.file.decode()))
++        event.task.decode('utf-8', 'replace'), event.pid, type, event.size,
++        event.offset / 1024, float(event.delta_us) / 1000,
++        event.file.decode('utf-8', 'replace')))
+ 
+ # initialize BPF
+ b = BPF(text=bpf_text)
+diff --git a/tools/filelife.py b/tools/filelife.py
+index 0f4e269..410659d 100755
+--- a/tools/filelife.py
++++ b/tools/filelife.py
+@@ -136,7 +136,8 @@ print("%-8s %-6s %-16s %-7s %s" % ("TIME", "PID", "COMM", "AGE(s)", "FILE"))
+ def print_event(cpu, data, size):
+     event = ct.cast(data, ct.POINTER(Data)).contents
+     print("%-8s %-6d %-16s %-7.2f %s" % (strftime("%H:%M:%S"), event.pid,
+-        event.comm.decode(), float(event.delta) / 1000, event.fname.decode()))
++        event.comm.decode('utf-8', 'replace'), float(event.delta) / 1000,
++        event.fname.decode('utf-8', 'replace')))
+ 
+ b["events"].open_perf_buffer(print_event)
+ while 1:
+diff --git a/tools/fileslower.py b/tools/fileslower.py
+index 5caa4ca..25443a2 100755
+--- a/tools/fileslower.py
++++ b/tools/fileslower.py
+@@ -240,13 +240,13 @@ start_ts = time.time()
+     event = ct.cast(data, ct.POINTER(Data)).contents
+ 
+     ms = float(event.delta_us) / 1000
+-    name = event.name.decode()
++    name = event.name.decode('utf-8', 'replace')
+     if event.name_len > DNAME_INLINE_LEN:
+         name = name[:-3] + "..."
+ 
+     print("%-8.3f %-14.14s %-6s %1s %-7s %7.2f %s" % (
+-        time.time() - start_ts, event.comm.decode(), event.pid,
+-        mode_s[event.mode], event.sz, ms, name))
++        time.time() - start_ts, event.comm.decode('utf-8', 'replace'),
++        event.pid, mode_s[event.mode], event.sz, ms, name))
+ 
+ b["events"].open_perf_buffer(print_event, page_cnt=64)
+ while 1:
+diff --git a/tools/filetop.py b/tools/filetop.py
+index 454dfd8..4c7a28a 100755
+--- a/tools/filetop.py
++++ b/tools/filetop.py
+@@ -190,14 +190,15 @@ exiting = 0
+     for k, v in reversed(sorted(counts.items(),
+                                 key=lambda counts:
+                                   getattr(counts[1], args.sort))):
+-        name = k.name.decode()
++        name = k.name.decode('utf-8', 'replace')
+         if k.name_len > DNAME_INLINE_LEN:
+             name = name[:-3] + "..."
+ 
+         # print line
+         print("%-6d %-16s %-6d %-6d %-7d %-7d %1s %s" % (k.pid,
+-            k.comm.decode(), v.reads, v.writes, v.rbytes / 1024,
+-            v.wbytes / 1024, k.type.decode(), name))
++            k.comm.decode('utf-8', 'replace'), v.reads, v.writes,
++            v.rbytes / 1024, v.wbytes / 1024,
++            k.type.decode('utf-8', 'replace'), name))
+ 
+         line += 1
+         if line >= maxrows:
+diff --git a/tools/funcslower.py b/tools/funcslower.py
+index 93fb846..261869e 100755
+--- a/tools/funcslower.py
++++ b/tools/funcslower.py
+@@ -306,7 +306,7 @@ earliest_ts = 0
+         # print folded stack output
+         user_stack = list(user_stack)
+         kernel_stack = list(kernel_stack)
+-        line = [event.comm.decode()] + \
++        line = [event.comm.decode('utf-8', 'replace')] + \
+             [b.sym(addr, event.tgid_pid) for addr in reversed(user_stack)] + \
+             (do_delimiter and ["-"] or []) + \
+             [b.ksym(addr) for addr in reversed(kernel_stack)]
+@@ -323,7 +323,7 @@ earliest_ts = 0
+     ts = float(event.duration_ns) / time_multiplier
+     if not args.folded:
+         print((time_str(event) + "%-14.14s %-6s %7.2f %16x %s %s") %
+-            (event.comm.decode(), event.tgid_pid >> 32,
++            (event.comm.decode('utf-8', 'replace'), event.tgid_pid >> 32,
+              ts, event.retval, args.functions[event.id], args_str(event)))
+     if args.user_stack or args.kernel_stack:
+         print_stack(event)
+diff --git a/tools/gethostlatency.py b/tools/gethostlatency.py
+index f1d7dea..3a967ae 100755
+--- a/tools/gethostlatency.py
++++ b/tools/gethostlatency.py
+@@ -129,8 +129,8 @@ print("%-9s %-6s %-16s %10s %s" % ("TIME", "PID", "COMM", "LATms", "HOST"))
+ def print_event(cpu, data, size):
+     event = ct.cast(data, ct.POINTER(Data)).contents
+     print("%-9s %-6d %-16s %10.2f %s" % (strftime("%H:%M:%S"), event.pid,
+-        event.comm.decode(), (float(event.delta) / 1000000),
+-        event.host.decode()))
++        event.comm.decode('utf-8', 'replace'), (float(event.delta) / 1000000),
++        event.host.decode('utf-8', 'replace')))
+ 
+ # loop with callback to print_event
+ b["events"].open_perf_buffer(print_event)
+diff --git a/tools/hardirqs.py b/tools/hardirqs.py
+index 3835d63..589a890 100755
+--- a/tools/hardirqs.py
++++ b/tools/hardirqs.py
+@@ -172,7 +172,7 @@ dist = b.get_table("dist")
+     else:
+         print("%-26s %11s" % ("HARDIRQ", "TOTAL_" + label))
+         for k, v in sorted(dist.items(), key=lambda dist: dist[1].value):
+-            print("%-26s %11d" % (k.name.decode(), v.value / factor))
++            print("%-26s %11d" % (k.name.decode('utf-8', 'replace'), v.value / factor))
+     dist.clear()
+ 
+     countdown -= 1
+diff --git a/tools/llcstat.py b/tools/llcstat.py
+index fe8bdd9..ec2c1f8 100755
+--- a/tools/llcstat.py
++++ b/tools/llcstat.py
+@@ -113,7 +113,7 @@ tot_miss = 0
+     # This happens on some PIDs due to missed counts caused by sampling
+     hit = (v.value - miss) if (v.value >= miss) else 0
+     print('{:<8d} {:<16s} {:<4d} {:>12d} {:>12d} {:>6.2f}%'.format(
+-        k.pid, k.name.decode(), k.cpu, v.value, miss,
++        k.pid, k.name.decode('utf-8', 'replace'), k.cpu, v.value, miss,
+         (float(hit) / float(v.value)) * 100.0))
+ print('Total References: {} Total Misses: {} Hit Rate: {:.2f}%'.format(
+     tot_ref, tot_miss, (float(tot_ref - tot_miss) / float(tot_ref)) * 100.0))
+diff --git a/tools/mdflush.py b/tools/mdflush.py
+index 1d29bf1..70afc4d 100755
+--- a/tools/mdflush.py
++++ b/tools/mdflush.py
+@@ -72,7 +72,8 @@ print("%-8s %-6s %-16s %s" % ("TIME", "PID", "COMM", "DEVICE"))
+ def print_event(cpu, data, size):
+     event = ct.cast(data, ct.POINTER(Data)).contents
+     print("%-8s %-6d %-16s %s" % (strftime("%H:%M:%S"), event.pid,
+-        event.comm.decode(), event.disk.decode()))
++        event.comm.decode('utf-8', 'replace'),
++        event.disk.decode('utf-8', 'replace')))
+ 
+ # read events
+ b["events"].open_perf_buffer(print_event)
+diff --git a/tools/mountsnoop.py b/tools/mountsnoop.py
+index 2d0fa1a..e9b5865 100755
+--- a/tools/mountsnoop.py
++++ b/tools/mountsnoop.py
+@@ -382,8 +382,8 @@ _escape_chars = {
+                     flags=decode_umount_flags(syscall['flags']),
+                     retval=decode_errno(event.union.retval))
+             print('{:16} {:<7} {:<7} {:<11} {}'.format(
+-                syscall['comm'].decode(), syscall['tgid'], syscall['pid'],
+-                syscall['mnt_ns'], call))
++                syscall['comm'].decode('utf-8', 'replace'), syscall['tgid'],
++                syscall['pid'], syscall['mnt_ns'], call))
+     except KeyError:
+         # This might happen if we lost an event.
+         pass
+diff --git a/tools/nfsslower.py b/tools/nfsslower.py
+index 0f836af..2f92c90 100755
+--- a/tools/nfsslower.py
++++ b/tools/nfsslower.py
+@@ -280,13 +280,13 @@ TASK_COMM_LEN = 16      # linux/sched.h
+         return
+     print("%-8s %-14.14s %-6s %1s %-7s %-8d %7.2f %s" %
+           (strftime("%H:%M:%S"),
+-           event.task.decode(),
++           event.task.decode('utf-8', 'replace'),
+            event.pid,
+            type,
+            event.size,
+            event.offset / 1024,
+            float(event.delta_us) / 1000,
+-           event.file.decode()))
++           event.file.decode('utf-8', 'replace')))
+ 
+ 
+ # Currently specifically works for NFSv4, the other kprobes are generic
+diff --git a/tools/offcputime.py b/tools/offcputime.py
+index de77fb4..d84ae52 100755
+--- a/tools/offcputime.py
++++ b/tools/offcputime.py
+@@ -281,7 +281,7 @@ stack_traces = b.get_table("stack_traces")
+         # print folded stack output
+         user_stack = list(user_stack)
+         kernel_stack = list(kernel_stack)
+-        line = [k.name.decode()]
++        line = [k.name.decode('utf-8', 'replace')]
+         # if we failed to get the stack is, such as due to no space (-ENOMEM) or
+         # hash collision (-EEXIST), we still print a placeholder for consistency
+         if not args.kernel_stacks_only:
+@@ -312,7 +312,7 @@ stack_traces = b.get_table("stack_traces")
+             else:
+                 for addr in user_stack:
+                     print("    %s" % b.sym(addr, k.tgid))
+-        print("    %-16s %s (%d)" % ("-", k.name.decode(), k.pid))
++        print("    %-16s %s (%d)" % ("-", k.name.decode('utf-8', 'replace'), k.pid))
+         print("        %d\n" % v.value)
+ 
+ if missing_stacks > 0:
+diff --git a/tools/offwaketime.py b/tools/offwaketime.py
+index 01961ee..674be22 100755
+--- a/tools/offwaketime.py
++++ b/tools/offwaketime.py
+@@ -316,7 +316,7 @@ need_delimiter = args.delimited and not (args.kernel_stacks_only or
+ 
+     if folded:
+         # print folded stack output
+-        line = [k.target.decode()]
++        line = [k.target.decode('utf-8', 'replace')]
+         if not args.kernel_stacks_only:
+             if stack_id_err(k.t_u_stack_id):
+                 line.append("[Missed User Stack]")
+@@ -344,11 +344,11 @@ need_delimiter = args.delimited and not (args.kernel_stacks_only or
+             else:
+                 line.extend([b.sym(addr, k.w_tgid)
+                     for addr in reversed(list(waker_user_stack))])
+-        line.append(k.waker.decode())
++        line.append(k.waker.decode('utf-8', 'replace'))
+         print("%s %d" % (";".join(line), v.value))
+     else:
+         # print wakeup name then stack in reverse order
+-        print("    %-16s %s %s" % ("waker:", k.waker.decode(), k.t_pid))
++        print("    %-16s %s %s" % ("waker:", k.waker.decode('utf-8', 'replace'), k.t_pid))
+         if not args.kernel_stacks_only:
+             if stack_id_err(k.w_u_stack_id):
+                 print("    [Missed User Stack]")
+@@ -381,7 +381,7 @@ need_delimiter = args.delimited and not (args.kernel_stacks_only or
+             else:
+                 for addr in target_user_stack:
+                     print("    %s" % b.sym(addr, k.t_tgid))
+-        print("    %-16s %s %s" % ("target:", k.target.decode(), k.w_pid))
++        print("    %-16s %s %s" % ("target:", k.target.decode('utf-8', 'replace'), k.w_pid))
+         print("        %d\n" % v.value)
+ 
+ if missing_stacks > 0:
+diff --git a/tools/old/offcputime.py b/tools/old/offcputime.py
+index 680d924..38d12a2 100755
+--- a/tools/old/offcputime.py
++++ b/tools/old/offcputime.py
+@@ -185,7 +185,7 @@ matched = b.num_open_kprobes()
+     for k, v in sorted(counts.items(), key=lambda counts: counts[1].value):
+         if folded:
+             # print folded stack output
+-            line = k.name.decode() + ";"
++            line = k.name.decode('utf-8', 'replace') + ";"
+             for i in reversed(range(0, maxdepth)):
+                 if k.ret[i] == 0:
+                     continue
+diff --git a/tools/old/oomkill.py b/tools/old/oomkill.py
+index e8e0321..b99f852 100755
+--- a/tools/old/oomkill.py
++++ b/tools/old/oomkill.py
+@@ -68,8 +68,8 @@ TASK_COMM_LEN = 16  # linux/sched.h
+         avgline = stats.read().rstrip()
+     print(("%s Triggered by PID %d (\"%s\"), OOM kill of PID %d (\"%s\")"
+         ", %d pages, loadavg: %s") % (strftime("%H:%M:%S"), event.fpid,
+-        event.fcomm.decode(), event.tpid, event.tcomm.decode(), event.pages,
+-        avgline))
++        event.fcomm.decode('utf-8', 'replace'), event.tpid,
++        event.tcomm.decode('utf-8', 'replace'), event.pages, avgline))
+ 
+ # initialize BPF
+ b = BPF(text=bpf_text)
+diff --git a/tools/old/profile.py b/tools/old/profile.py
+index 04ca13a..e308208 100755
+--- a/tools/old/profile.py
++++ b/tools/old/profile.py
+@@ -339,7 +339,7 @@ stack_traces = b.get_table("stack_traces")
+         # print folded stack output
+         user_stack = list(user_stack)
+         kernel_stack = list(kernel_stack)
+-        line = [k.name.decode()] + \
++        line = [k.name.decode('utf-8', 'replace')] + \
+             [b.sym(addr, k.pid) for addr in reversed(user_stack)] + \
+             (do_delimiter and ["-"] or []) + \
+             [aksym(addr) for addr in reversed(kernel_stack)]
+diff --git a/tools/old/wakeuptime.py b/tools/old/wakeuptime.py
+index e09840a..783c7ff 100644
+--- a/tools/old/wakeuptime.py
++++ b/tools/old/wakeuptime.py
+@@ -199,23 +199,23 @@ matched = b.num_open_kprobes()
+     for k, v in sorted(counts.items(), key=lambda counts: counts[1].value):
+         if folded:
+             # print folded stack output
+-            line = k.waker.decode() + ";"
++            line = k.waker.decode('utf-8', 'replace') + ";"
+             for i in reversed(range(0, maxdepth)):
+                 if k.ret[i] == 0:
+                     continue
+                 line = line + b.ksym(k.ret[i])
+                 if i != 0:
+                     line = line + ";"
+-            print("%s;%s %d" % (line, k.target.decode(), v.value))
++            print("%s;%s %d" % (line, k.target.decode('utf-8', 'replace'), v.value))
+         else:
+             # print default multi-line stack output
+-            print("    %-16s %s" % ("target:", k.target.decode()))
++            print("    %-16s %s" % ("target:", k.target.decode('utf-8', 'replace')))
+             for i in range(0, maxdepth):
+                 if k.ret[i] == 0:
+                     break
+                 print("    %-16x %s" % (k.ret[i],
+                     b.ksym(k.ret[i])))
+-            print("    %-16s %s" % ("waker:", k.waker.decode()))
++            print("    %-16s %s" % ("waker:", k.waker.decode('utf-8', 'replace')))
+             print("        %d\n" % v.value)
+     counts.clear()
+ 
+diff --git a/tools/oomkill.py b/tools/oomkill.py
+index e831d44..0677e49 100755
+--- a/tools/oomkill.py
++++ b/tools/oomkill.py
+@@ -69,8 +69,8 @@ TASK_COMM_LEN = 16  # linux/sched.h
+         avgline = stats.read().rstrip()
+     print(("%s Triggered by PID %d (\"%s\"), OOM kill of PID %d (\"%s\")"
+         ", %d pages, loadavg: %s") % (strftime("%H:%M:%S"), event.fpid,
+-        event.fcomm.decode(), event.tpid, event.tcomm.decode(), event.pages,
+-        avgline))
++        event.fcomm.decode('utf-8', 'replace'), event.tpid,
++        event.tcomm.decode('utf-8', 'replace'), event.pages, avgline))
+ 
+ # initialize BPF
+ b = BPF(text=bpf_text)
+diff --git a/tools/opensnoop.py b/tools/opensnoop.py
+index a0657d4..418d47b 100755
+--- a/tools/opensnoop.py
++++ b/tools/opensnoop.py
+@@ -184,7 +184,8 @@ print("%-6s %-16s %4s %3s %s" %
+ 
+     print("%-6d %-16s %4d %3d %s" %
+           (event.id & 0xffffffff if args.tid else event.id >> 32,
+-           event.comm.decode(), fd_s, err, event.fname.decode()))
++           event.comm.decode('utf-8', 'replace'), fd_s, err,
++           event.fname.decode('utf-8', 'replace')))
+ 
+ # loop with callback to print_event
+ b["events"].open_perf_buffer(print_event, page_cnt=64)
+diff --git a/tools/profile.py b/tools/profile.py
+index 1530b98..d1d3d26 100755
+--- a/tools/profile.py
++++ b/tools/profile.py
+@@ -268,7 +268,7 @@ b.attach_perf_event(ev_type=PerfType.SOFTWARE,
+ 
+ def aksym(addr):
+     if args.annotations:
+-        return b.ksym(addr) + "_[k]"
++        return b.ksym(addr) + "_[k]".encode()
+     else:
+         return b.ksym(addr)
+ 
+@@ -320,7 +320,7 @@ need_delimiter = args.delimited and not (args.kernel_stacks_only or
+                 line.append("[Missed Kernel Stack]")
+             else:
+                 line.extend([b.ksym(addr) for addr in reversed(kernel_stack)])
+-        print("%s %d" % (b";".join(line).decode(), v.value))
++        print("%s %d" % (b";".join(line).decode('utf-8', 'replace'), v.value))
+     else:
+         # print default multi-line stack output
+         if not args.user_stacks_only:
+@@ -336,8 +336,8 @@ need_delimiter = args.delimited and not (args.kernel_stacks_only or
+                 print("    [Missed User Stack]")
+             else:
+                 for addr in user_stack:
+-                    print("    %s" % b.sym(addr, k.pid).decode())
+-        print("    %-16s %s (%d)" % ("-", k.name.decode(), k.pid))
++                    print("    %s" % b.sym(addr, k.pid).decode('utf-8', 'replace'))
++        print("    %-16s %s (%d)" % ("-", k.name.decode('utf-8', 'replace'), k.pid))
+         print("        %d\n" % v.value)
+ 
+ # check missing
+diff --git a/tools/sslsniff.py b/tools/sslsniff.py
+index 2e74fba..0c9f976 100755
+--- a/tools/sslsniff.py
++++ b/tools/sslsniff.py
+@@ -221,8 +221,9 @@ start = 0
+                 " bytes lost) " + "-" * 5
+ 
+     fmt = "%-12s %-18.9f %-16s %-6d %-6d\n%s\n%s\n%s\n\n"
+-    print(fmt % (rw, time_s, event.comm.decode(), event.pid, event.len, s_mark,
+-                 event.v0.decode(), e_mark))
++    print(fmt % (rw, time_s, event.comm.decode('utf-8', 'replace'),
++                 event.pid, event.len, s_mark,
++                 event.v0.decode('utf-8', 'replace'), e_mark))
+ 
+ b["perf_SSL_write"].open_perf_buffer(print_event_write)
+ b["perf_SSL_read"].open_perf_buffer(print_event_read)
+diff --git a/tools/stackcount.py b/tools/stackcount.py
+index 8781879..5554014 100755
+--- a/tools/stackcount.py
++++ b/tools/stackcount.py
+@@ -339,7 +339,7 @@ BPF_STACK_TRACE(stack_traces, 1024);
+                     # print folded stack output
+                     user_stack = list(user_stack)
+                     kernel_stack = list(kernel_stack)
+-                    line = [k.name.decode()] + \
++                    line = [k.name.decode('utf-8', 'replace')] + \
+                         [b.sym(addr, k.tgid) for addr in
+                         reversed(user_stack)] + \
+                         (self.need_delimiter and ["-"] or []) + \
+diff --git a/tools/statsnoop.py b/tools/statsnoop.py
+index 6fd8049..4e62ebd 100755
+--- a/tools/statsnoop.py
++++ b/tools/statsnoop.py
+@@ -172,8 +172,9 @@ print("%-6s %-16s %4s %3s %s" % ("PID", "COMM", "FD", "ERR", "PATH"))
+     if args.timestamp:
+         print("%-14.9f" % (float(event.ts_ns - start_ts) / 1000000000), end="")
+ 
+-    print("%-6d %-16s %4d %3d %s" % (event.pid, event.comm.decode(),
+-        fd_s, err, event.fname.decode()))
++    print("%-6d %-16s %4d %3d %s" % (event.pid,
++        event.comm.decode('utf-8', 'replace'), fd_s, err,
++        event.fname.decode('utf-8', 'replace')))
+ 
+ # loop with callback to print_event
+ b["events"].open_perf_buffer(print_event, page_cnt=64)
+diff --git a/tools/tcpaccept.py b/tools/tcpaccept.py
+index 044f15c..884b0c5 100755
+--- a/tools/tcpaccept.py
++++ b/tools/tcpaccept.py
+@@ -239,7 +239,7 @@ TASK_COMM_LEN = 16      # linux/sched.h
+             start_ts = event.ts_us
+         print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="")
+     print("%-6d %-12.12s %-2d %-16s %-16s %-4d" % (event.pid,
+-        event.task.decode(), event.ip,
++        event.task.decode('utf-8', 'replace'), event.ip,
+         inet_ntop(AF_INET, pack("I", event.daddr)),
+         inet_ntop(AF_INET, pack("I", event.saddr)), event.lport))
+ 
+@@ -251,8 +251,9 @@ TASK_COMM_LEN = 16      # linux/sched.h
+             start_ts = event.ts_us
+         print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="")
+     print("%-6d %-12.12s %-2d %-16s %-16s %-4d" % (event.pid,
+-        event.task.decode(), event.ip, inet_ntop(AF_INET6, event.daddr),
+-        inet_ntop(AF_INET6, event.saddr), event.lport))
++        event.task.decode('utf-8', 'replace'), event.ip,
++        inet_ntop(AF_INET6, event.daddr),inet_ntop(AF_INET6, event.saddr),
++        event.lport))
+ 
+ # initialize BPF
+ b = BPF(text=bpf_text)
+diff --git a/tools/tcpconnect.py b/tools/tcpconnect.py
+index f0b23b0..ac84326 100755
+--- a/tools/tcpconnect.py
++++ b/tools/tcpconnect.py
+@@ -202,7 +202,7 @@ TASK_COMM_LEN = 16      # linux/sched.h
+             start_ts = event.ts_us
+         print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="")
+     print("%-6d %-12.12s %-2d %-16s %-16s %-4d" % (event.pid,
+-        event.task.decode(), event.ip,
++        event.task.decode('utf-8', 'replace'), event.ip,
+         inet_ntop(AF_INET, pack("I", event.saddr)),
+         inet_ntop(AF_INET, pack("I", event.daddr)), event.dport))
+ 
+@@ -214,8 +214,9 @@ TASK_COMM_LEN = 16      # linux/sched.h
+             start_ts = event.ts_us
+         print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="")
+     print("%-6d %-12.12s %-2d %-16s %-16s %-4d" % (event.pid,
+-        event.task.decode(), event.ip, inet_ntop(AF_INET6, event.saddr),
+-        inet_ntop(AF_INET6, event.daddr), event.dport))
++        event.task.decode('utf-8', 'replace'), event.ip,
++        inet_ntop(AF_INET6, event.saddr), inet_ntop(AF_INET6, event.daddr),
++        event.dport))
+ 
+ # initialize BPF
+ b = BPF(text=bpf_text)
+diff --git a/tools/tcpconnlat.py b/tools/tcpconnlat.py
+index 233612b..0d21b83 100755
+--- a/tools/tcpconnlat.py
++++ b/tools/tcpconnlat.py
+@@ -237,7 +237,7 @@ start_ts = 0
+             start_ts = event.ts_us
+         print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="")
+     print("%-6d %-12.12s %-2d %-16s %-16s %-5d %.2f" % (event.pid,
+-        event.task.decode(), event.ip,
++        event.task.decode('utf-8', 'replace'), event.ip,
+         inet_ntop(AF_INET, pack("I", event.saddr)),
+         inet_ntop(AF_INET, pack("I", event.daddr)), event.dport,
+         float(event.delta_us) / 1000))
+@@ -250,9 +250,9 @@ start_ts = 0
+             start_ts = event.ts_us
+         print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="")
+     print("%-6d %-12.12s %-2d %-16s %-16s %-5d %.2f" % (event.pid,
+-        event.task.decode(), event.ip, inet_ntop(AF_INET6, event.saddr),
+-        inet_ntop(AF_INET6, event.daddr), event.dport,
+-        float(event.delta_us) / 1000))
++        event.task.decode('utf-8', 'replace'), event.ip,
++        inet_ntop(AF_INET6, event.saddr), inet_ntop(AF_INET6, event.daddr),
++        event.dport, float(event.delta_us) / 1000))
+ 
+ # header
+ if args.timestamp:
+diff --git a/tools/tcplife.py b/tools/tcplife.py
+index f8bab43..51ed7ae 100755
+--- a/tools/tcplife.py
++++ b/tools/tcplife.py
+@@ -454,7 +454,7 @@ format_string = "%-5d %-10.10s %s%-15s %-5d %-15s %-5d %5d %5d %.2f"
+             print("%.6f," % delta_s, end="")
+         else:
+             print("%-9.6f " % delta_s, end="")
+-    print(format_string % (event.pid, event.task.decode(),
++    print(format_string % (event.pid, event.task.decode('utf-8', 'replace'),
+         "4" if args.wide or args.csv else "",
+         inet_ntop(AF_INET, pack("I", event.saddr)), event.ports >> 32,
+         inet_ntop(AF_INET, pack("I", event.daddr)), event.ports & 0xffffffff,
+@@ -476,7 +476,7 @@ format_string = "%-5d %-10.10s %s%-15s %-5d %-15s %-5d %5d %5d %.2f"
+             print("%.6f," % delta_s, end="")
+         else:
+             print("%-9.6f " % delta_s, end="")
+-    print(format_string % (event.pid, event.task.decode(),
++    print(format_string % (event.pid, event.task.decode('utf-8', 'replace'),
+         "6" if args.wide or args.csv else "",
+         inet_ntop(AF_INET6, event.saddr), event.ports >> 32,
+         inet_ntop(AF_INET6, event.daddr), event.ports & 0xffffffff,
+diff --git a/tools/tcpstates.py b/tools/tcpstates.py
+index ec758d2..381a6d5 100755
+--- a/tools/tcpstates.py
++++ b/tools/tcpstates.py
+@@ -276,7 +276,7 @@ format_string = ("%-16x %-5d %-10.10s %s%-15s %-5d %-15s %-5d %-11s " +
+             print("%.6f," % delta_s, end="")
+         else:
+             print("%-9.6f " % delta_s, end="")
+-    print(format_string % (event.skaddr, event.pid, event.task.decode(),
++    print(format_string % (event.skaddr, event.pid, event.task.decode('utf-8', 'replace'),
+         "4" if args.wide or args.csv else "",
+         inet_ntop(AF_INET, pack("I", event.saddr)), event.ports >> 32,
+         inet_ntop(AF_INET, pack("I", event.daddr)), event.ports & 0xffffffff,
+@@ -299,7 +299,7 @@ format_string = ("%-16x %-5d %-10.10s %s%-15s %-5d %-15s %-5d %-11s " +
+             print("%.6f," % delta_s, end="")
+         else:
+             print("%-9.6f " % delta_s, end="")
+-    print(format_string % (event.skaddr, event.pid, event.task.decode(),
++    print(format_string % (event.skaddr, event.pid, event.task.decode('utf-8', 'replace'),
+         "6" if args.wide or args.csv else "",
+         inet_ntop(AF_INET6, event.saddr), event.ports >> 32,
+         inet_ntop(AF_INET6, event.daddr), event.ports & 0xffffffff,
+diff --git a/tools/tcptracer.py b/tools/tcptracer.py
+index 5e97ee6..16bb4b1 100755
+--- a/tools/tcptracer.py
++++ b/tools/tcptracer.py
+@@ -556,7 +556,7 @@ verbose_types = {"C": "connect", "A": "accept",
+         print("%-2s " % (type_str), end="")
+ 
+     print("%-6d %-16s %-2d %-16s %-16s %-6d %-6d" %
+-          (event.pid, event.comm.decode('utf-8'),
++          (event.pid, event.comm.decode('utf-8', 'replace'),
+            event.ip,
+            inet_ntop(AF_INET, pack("I", event.saddr)),
+            inet_ntop(AF_INET, pack("I", event.daddr)),
+@@ -593,7 +593,7 @@ verbose_types = {"C": "connect", "A": "accept",
+         print("%-2s " % (type_str), end="")
+ 
+     print("%-6d %-16s %-2d %-16s %-16s %-6d %-6d" %
+-          (event.pid, event.comm.decode('utf-8'),
++          (event.pid, event.comm.decode('utf-8', 'replace'),
+            event.ip,
+            "[" + inet_ntop(AF_INET6, event.saddr) + "]",
+            "[" + inet_ntop(AF_INET6, event.daddr) + "]",
+diff --git a/tools/trace.py b/tools/trace.py
+index 16e9b6b..2233305 100755
+--- a/tools/trace.py
++++ b/tools/trace.py
+@@ -558,7 +558,8 @@ BPF_PERF_OUTPUT(%s);
+                 if Probe.print_cpu:
+                     print("%-3s " % event.cpu, end="")
+                 print("%-7d %-7d %-15s %-16s %s" %
+-                      (event.tgid, event.pid, event.comm.decode(),
++                      (event.tgid, event.pid,
++                       event.comm.decode('utf-8', 'replace'),
+                        self._display_function(), msg))
+ 
+                 if self.kernel_stack:
+diff --git a/tools/ttysnoop.py b/tools/ttysnoop.py
+index e934486..9780518 100755
+--- a/tools/ttysnoop.py
++++ b/tools/ttysnoop.py
+@@ -115,7 +115,7 @@ BUFSIZE = 256
+ # process event
+ def print_event(cpu, data, size):
+     event = ct.cast(data, ct.POINTER(Data)).contents
+-    print("%s" % event.buf[0:event.count].decode(), end="")
++    print("%s" % event.buf[0:event.count].decode('utf-8', 'replace'), end="")
+     sys.stdout.flush()
+ 
+ # loop with callback to print_event
+diff --git a/tools/zfsslower.py b/tools/zfsslower.py
+index 6de4606..8ab283a 100755
+--- a/tools/zfsslower.py
++++ b/tools/zfsslower.py
+@@ -265,12 +265,14 @@ TASK_COMM_LEN = 16      # linux/sched.h
+ 
+     if (csv):
+         print("%d,%s,%d,%s,%d,%d,%d,%s" % (
+-            event.ts_us, event.task.decode(), event.pid, type, event.size,
+-            event.offset, event.delta_us, event.file.decode()))
++            event.ts_us, event.task.decode('utf-8', 'replace'), event.pid,
++            type, event.size, event.offset, event.delta_us,
++            event.file.decode('utf-8', 'replace')))
+         return
+     print("%-8s %-14.14s %-6s %1s %-7s %-8d %7.2f %s" % (strftime("%H:%M:%S"),
+-        event.task.decode(), event.pid, type, event.size, event.offset / 1024,
+-        float(event.delta_us) / 1000, event.file.decode()))
++        event.task.decode('utf-8', 'replace'), event.pid, type, event.size,
++        event.offset / 1024, float(event.delta_us) / 1000,
++        event.file.decode('utf-8', 'replace')))
+ 
+ # initialize BPF
+ b = BPF(text=bpf_text)
+-- 
+2.17.2
+
diff --git a/SOURCES/Disable-tests-cc.patch b/SOURCES/Disable-tests-cc.patch
new file mode 100644
index 0000000..8661bf3
--- /dev/null
+++ b/SOURCES/Disable-tests-cc.patch
@@ -0,0 +1,28 @@
+From b3faa19c61a5a5385899a80bdd0d6a3052f1415a Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Thu, 24 May 2018 16:11:30 +0200
+Subject: [PATCH] Disable tests/cc
+
+Some files in tests/cc/ don't compile on s390x. We can just disable
+them until a better fix is available: the build target are not
+installed anyway.
+
+---
+ tests/CMakeLists.txt | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+index 86abec9..48e9029 100644
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -8,7 +8,6 @@ add_test(NAME style-check COMMAND ${CMAKE_SOURCE_DIR}/scripts/style-check.sh)
+ set_tests_properties(style-check PROPERTIES PASS_REGULAR_EXPRESSION ".*")
+ 
+ if(ENABLE_CLANG_JIT)
+-add_subdirectory(cc)
+ add_subdirectory(python)
+ add_subdirectory(lua)
+ endif()
+-- 
+2.13.6
+
diff --git a/SOURCES/Tools-fixes-2009.patch b/SOURCES/Tools-fixes-2009.patch
new file mode 100644
index 0000000..95c5489
--- /dev/null
+++ b/SOURCES/Tools-fixes-2009.patch
@@ -0,0 +1,69 @@
+From 09f9d3c8dd016ee10dc8b57057763dc25b0d2208 Mon Sep 17 00:00:00 2001
+From: jeromemarchand <38073585+jeromemarchand@users.noreply.github.com>
+Date: Sat, 13 Oct 2018 01:01:22 +0200
+Subject: [PATCH] Tools fixes (#2009)
+
+* tools: the argument of get_kprobe_functions() should be a bytes object
+
+It fixes the following error:
+Traceback (most recent call last):
+  File "/usr/share/bcc/tools/ext4dist", line 189, in <module>
+    if BPF.get_kprobe_functions('ext4_file_read_iter'):
+  File "/usr/lib/python3.6/site-packages/bcc/__init__.py", line 519, in get_kprobe_functions
+    if (t.lower() in [b't', b'w']) and re.match(event_re, fn) \
+  File "/usr/lib64/python3.6/re.py", line 172, in match
+    return _compile(pattern, flags).match(string)
+TypeError: cannot use a string pattern on a bytes-like object
+
+* tools: fix freeze in offwaketime
+
+Since commit 47cecb65ce6e, the sigint signal is ignored
+unconditionally which prevents offwaketime to be stopped by
+pressing Ctrl-C when run without a specified duration.
+---
+ tools/ext4dist.py    |  4 ++--
+ tools/offwaketime.py | 10 ++++++----
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/tools/ext4dist.py b/tools/ext4dist.py
+index 1806953..bc797fb 100755
+--- a/tools/ext4dist.py
++++ b/tools/ext4dist.py
+@@ -183,10 +183,10 @@ b = BPF(text=bpf_text)
+ # Comment by Joe Yin 
+ # From Linux 4.10, the function .read_iter at the ext4_file_operations has 
+ # changed to ext4_file_read_iter.
+-# So, I add get_kprobe_functions('ext4_file_read_iter'),it will first to attach ext4_file_read_iter,
++# So, I add get_kprobe_functions(b'ext4_file_read_iter'),it will first to attach ext4_file_read_iter,
+ # if fails and will attach the generic_file_read_iter which used to pre-4.10.
+ 
+-if BPF.get_kprobe_functions('ext4_file_read_iter'):
++if BPF.get_kprobe_functions(b'ext4_file_read_iter'):
+ 	b.attach_kprobe(event="ext4_file_read_iter", fn_name="trace_entry")
+ else:
+ 	b.attach_kprobe(event="generic_file_read_iter", fn_name="trace_read_entry")
+diff --git a/tools/offwaketime.py b/tools/offwaketime.py
+index 674be22..0e4f35e 100755
+--- a/tools/offwaketime.py
++++ b/tools/offwaketime.py
+@@ -277,11 +277,13 @@ matched = b.num_open_kprobes()
+     else:
+         print("... Hit Ctrl-C to end.")
+ 
+-# as cleanup can take many seconds, trap Ctrl-C:
+-# print a newline for folded output on Ctrl-C
+-signal.signal(signal.SIGINT, signal_ignore)
++try:
++    sleep(duration)
++except KeyboardInterrupt:
++    # as cleanup can take many seconds, trap Ctrl-C:
++    # print a newline for folded output on Ctrl-C
++    signal.signal(signal.SIGINT, signal_ignore)
+ 
+-sleep(duration)
+ 
+ if not folded:
+     print()
+-- 
+2.17.2
+
diff --git a/SOURCES/biolatency-Fix-disks-bpf_probe_read-1980.patch b/SOURCES/biolatency-Fix-disks-bpf_probe_read-1980.patch
new file mode 100644
index 0000000..5008511
--- /dev/null
+++ b/SOURCES/biolatency-Fix-disks-bpf_probe_read-1980.patch
@@ -0,0 +1,48 @@
+From fc245dfe9dabbd77e3adbf89a45aaab0cb1552fd Mon Sep 17 00:00:00 2001
+From: Mark Drayton <mark@markdrayton.info>
+Date: Wed, 19 Sep 2018 16:41:49 -0700
+Subject: [PATCH] biolatency: Fix --disks bpf_probe_read() (#1980)
+
+bpf_probe_read()'s third argument is no longer rewritten. Instead, use a
+temporary variable (like #1973) to avoid a memory access error.
+
+Before:
+
+```
+$ sudo biolatency -D 1
+bpf: Failed to load program: Permission denied
+0: (79) r1 = *(u64 *)(r1 +112)
+1: (7b) *(u64 *)(r10 -8) = r1
+[..]
+R1 invalid mem access 'inv'
+
+HINT: The invalid mem access 'inv' error can happen if you try to
+dereference memory without first using bpf_probe_read() to copy it to
+the BPF stack. Sometimes the bpf_probe_read is automatic by the bcc
+rewriter, other times you'll need to be explicit.
+```
+
+After, works as expected.
+---
+ tools/biolatency.py | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/biolatency.py b/tools/biolatency.py
+index 49ee7cf..3879af1 100755
+--- a/tools/biolatency.py
++++ b/tools/biolatency.py
+@@ -99,8 +99,9 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req)
+         'BPF_HISTOGRAM(dist, disk_key_t);')
+     bpf_text = bpf_text.replace('STORE',
+         'disk_key_t key = {.slot = bpf_log2l(delta)}; ' +
+-        'bpf_probe_read(&key.disk, sizeof(key.disk), ' +
+-        'req->rq_disk->disk_name); dist.increment(key);')
++        'void *__tmp = (void *)req->rq_disk->disk_name; ' +
++        'bpf_probe_read(&key.disk, sizeof(key.disk), __tmp); ' +
++        'dist.increment(key);')
+ else:
+     bpf_text = bpf_text.replace('STORAGE', 'BPF_HISTOGRAM(dist);')
+     bpf_text = bpf_text.replace('STORE',
+-- 
+2.19.2
+
diff --git a/SOURCES/covscan-fix-miscellaneaous-errors-2003.patch b/SOURCES/covscan-fix-miscellaneaous-errors-2003.patch
new file mode 100644
index 0000000..f5adf5f
--- /dev/null
+++ b/SOURCES/covscan-fix-miscellaneaous-errors-2003.patch
@@ -0,0 +1,153 @@
+From 415bd4e43b2c27e3999923c16f5ff39f9b1adcae Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Thu, 1 Nov 2018 06:18:14 +0100
+Subject: [PATCH] covscan: fix miscellaneaous errors (#2003)
+
+* Coverity #def53: COPY_PASTE_ERROR
+
+* Coverity #def18: DC.STREAM_BUFFER. Double-check max length of dev
+
+* Coverity #def44: MISSING_BREAK. This looks like it should be here
+
+* Coverity #def67: STRING_NULL: potential OOB read if 0 bytes read.
+
+* Coverity #def66: FORWARD_NULL: potential null ptr deref
+
+* Coverity #def17: RESOURCE_LEAK: missing free()
+
+* Dont free the result of dirname
+
+dirname() may return pointers to statically allocated memory. Don't
+free the pointer it returns.
+---
+ src/cc/bcc_elf.c                          | 11 +++++++----
+ src/cc/bcc_proc.c                         |  4 ++--
+ src/cc/frontends/b/type_check.cc          |  1 +
+ src/cc/frontends/p4/compiler/ebpfTable.py |  2 +-
+ src/cc/libbpf.c                           | 20 +++++++++++---------
+ 5 files changed, 22 insertions(+), 16 deletions(-)
+
+diff --git a/src/cc/bcc_elf.c b/src/cc/bcc_elf.c
+index c425db6..0c696bd 100644
+--- a/src/cc/bcc_elf.c
++++ b/src/cc/bcc_elf.c
+@@ -398,6 +398,7 @@ static int verify_checksum(const char *file, unsigned int crc) {
+ static char *find_debug_via_debuglink(Elf *e, const char *binpath,
+                                       int check_crc) {
+   char fullpath[PATH_MAX];
++  char *tmppath;
+   char *bindir = NULL;
+   char *res = NULL;
+   unsigned int crc;
+@@ -406,8 +407,8 @@ static char *find_debug_via_debuglink(Elf *e, const char *binpath,
+   if (!find_debuglink(e, &name, &crc))
+     return NULL;
+ 
+-  bindir = strdup(binpath);
+-  bindir = dirname(bindir);
++  tmppath = strdup(binpath);
++  bindir = dirname(tmppath);
+ 
+   // Search for the file in 'binpath', but ignore the file we find if it
+   // matches the binary itself: the binary will always be probed later on,
+@@ -434,9 +435,11 @@ static char *find_debug_via_debuglink(Elf *e, const char *binpath,
+   }
+ 
+ DONE:
+-  free(bindir);
+-  if (res && check_crc && !verify_checksum(res, crc))
++  free(tmppath);
++  if (res && check_crc && !verify_checksum(res, crc)) {
++    free(res);
+     return NULL;
++  }
+   return res;
+ }
+ 
+diff --git a/src/cc/bcc_proc.c b/src/cc/bcc_proc.c
+index d694eb9..f1c30c2 100644
+--- a/src/cc/bcc_proc.c
++++ b/src/cc/bcc_proc.c
+@@ -92,14 +92,14 @@ int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback,
+   if (!procmap)
+     return -1;
+ 
+-  char buf[PATH_MAX + 1], perm[5], dev[8];
++  char buf[PATH_MAX + 1], perm[5], dev[6];
+   char *name;
+   uint64_t begin, end, inode;
+   unsigned long long offset;
+   while (true) {
+     buf[0] = '\0';
+     // From fs/proc/task_mmu.c:show_map_vma
+-    if (fscanf(procmap, "%lx-%lx %s %llx %s %lu%[^\n]", &begin, &end, perm,
++    if (fscanf(procmap, "%lx-%lx %4s %llx %5s %lu%[^\n]", &begin, &end, perm,
+                &offset, dev, &inode, buf) != 7)
+       break;
+ 
+diff --git a/src/cc/frontends/b/type_check.cc b/src/cc/frontends/b/type_check.cc
+index 8d49de9..7c5b7ce 100644
+--- a/src/cc/frontends/b/type_check.cc
++++ b/src/cc/frontends/b/type_check.cc
+@@ -204,6 +204,7 @@ StatusTuple TypeCheck::visit_binop_expr_node(BinopExprNode *n) {
+     case Tok::TCGT:
+     case Tok::TCGE:
+       n->bit_width_ = 1;
++      break;
+     default:
+       n->bit_width_ = std::max(n->lhs_->bit_width_, n->rhs_->bit_width_);
+   }
+diff --git a/src/cc/frontends/p4/compiler/ebpfTable.py b/src/cc/frontends/p4/compiler/ebpfTable.py
+index eb1efd9..4b7e023 100644
+--- a/src/cc/frontends/p4/compiler/ebpfTable.py
++++ b/src/cc/frontends/p4/compiler/ebpfTable.py
+@@ -110,7 +110,7 @@ import ebpfAction
+                 ebpfHeader = program.getInstance(instance.name)
+                 assert isinstance(ebpfHeader, ebpfInstance.SimpleInstance)
+                 basetype = ebpfHeader.type
+-                eInstance = program.getInstance(instance.base_name)
++                eInstance = program.getInstance(instance.name)
+ 
+             ebpfField = basetype.getField(fieldname)
+             assert isinstance(ebpfField, ebpfStructType.EbpfField)
+diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c
+index 8a7caec..5cf3554 100644
+--- a/src/cc/libbpf.c
++++ b/src/cc/libbpf.c
+@@ -521,14 +521,16 @@ int bpf_prog_load(enum bpf_prog_type prog_type, const char *name,
+     }
+   }
+ 
+-  if (strncmp(name, "kprobe__", 8) == 0)
+-    name_offset = 8;
+-  else if (strncmp(name, "tracepoint__", 12) == 0)
+-    name_offset = 12;
+-  else if (strncmp(name, "raw_tracepoint__", 16) == 0)
+-    name_offset = 16;
+-  memcpy(attr.prog_name, name + name_offset,
+-         min(name_len - name_offset, BPF_OBJ_NAME_LEN - 1));
++  if (name_len) {
++    if (strncmp(name, "kprobe__", 8) == 0)
++      name_offset = 8;
++    else if (strncmp(name, "tracepoint__", 12) == 0)
++      name_offset = 12;
++    else if (strncmp(name, "raw_tracepoint__", 16) == 0)
++      name_offset = 16;
++    memcpy(attr.prog_name, name + name_offset,
++           min(name_len - name_offset, BPF_OBJ_NAME_LEN - 1));
++  }
+ 
+   ret = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
+   // BPF object name is not supported on older Kernels.
+@@ -698,7 +700,7 @@ static int bpf_get_retprobe_bit(const char *event_type)
+   close(fd);
+   if (ret < 0 || ret >= sizeof(buf))
+     return -1;
+-  if (strlen(buf) < strlen("config:"))
++  if (strncmp(buf, "config:", strlen("config:")))
+     return -1;
+   errno = 0;
+   ret = (int)strtol(buf + strlen("config:"), NULL, 10);
+-- 
+2.17.2
+
diff --git a/SOURCES/fix-killsnoop.py-srr-bytes-type-error-2007.patch b/SOURCES/fix-killsnoop.py-srr-bytes-type-error-2007.patch
new file mode 100644
index 0000000..e712d6b
--- /dev/null
+++ b/SOURCES/fix-killsnoop.py-srr-bytes-type-error-2007.patch
@@ -0,0 +1,28 @@
+From 1d2348027404307b6cd51c0c452207be27c64863 Mon Sep 17 00:00:00 2001
+From: yonghong-song <ys114321@gmail.com>
+Date: Thu, 11 Oct 2018 08:32:04 -0700
+Subject: [PATCH] fix killsnoop.py srr/bytes type error (#2007)
+
+Fix issue #2002
+
+Signed-off-by: Yonghong Song <yhs@fb.com>
+---
+ tools/killsnoop.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/killsnoop.py b/tools/killsnoop.py
+index 89ea5cd..d60c72e 100755
+--- a/tools/killsnoop.py
++++ b/tools/killsnoop.py
+@@ -139,7 +139,7 @@ print("%-9s %-6s %-16s %-4s %-6s %s" % (
+     if (args.failed and (event.ret >= 0)):
+         return
+ 
+-    printb(b"%-9s %-6d %-16s %-4d %-6d %d" % (strftime("%H:%M:%S"),
++    printb(b"%-9s %-6d %-16s %-4d %-6d %d" % (strftime("%H:%M:%S").encode('ascii'),
+         event.pid, event.comm, event.sig, event.tpid, event.ret))
+ 
+ # loop with callback to print_event
+-- 
+2.17.2
+
diff --git a/SOURCES/manpage-remove-non-existent-p-option-from-the-biotop.patch b/SOURCES/manpage-remove-non-existent-p-option-from-the-biotop.patch
new file mode 100644
index 0000000..1b64154
--- /dev/null
+++ b/SOURCES/manpage-remove-non-existent-p-option-from-the-biotop.patch
@@ -0,0 +1,30 @@
+From b29ede1b052b5706581370ee98d2eccfbf700e77 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Wed, 12 Dec 2018 10:50:08 +0100
+Subject: [PATCH] manpage: remove non-existent -p option from the biotop
+ manpage
+
+The biotop manpage references a -p option that the tools doesn't have,
+and AFAICT, never had. It's only referenced in the manpage option, not
+in the synopsis, in "biotop -h" output not biotop_example.txt.
+---
+ man/man8/biotop.8 | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/man/man8/biotop.8 b/man/man8/biotop.8
+index 8b872aa..ed25521 100644
+--- a/man/man8/biotop.8
++++ b/man/man8/biotop.8
+@@ -30,9 +30,6 @@ Don't clear the screen.
+ \-r MAXROWS
+ Maximum number of rows to print. Default is 20.
+ .TP
+-\-p PID
+-Trace this PID only.
+-.TP
+ interval
+ Interval between updates, seconds.
+ .TP
+-- 
+2.19.2
+
diff --git a/SOURCES/tools-prepare-block-tools-for-the-removing-of-legacy.patch b/SOURCES/tools-prepare-block-tools-for-the-removing-of-legacy.patch
new file mode 100644
index 0000000..4416269
--- /dev/null
+++ b/SOURCES/tools-prepare-block-tools-for-the-removing-of-legacy.patch
@@ -0,0 +1,60 @@
+From 74e25edb248a62e437cdc1b4aaa8a0f44c112880 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Mon, 10 Dec 2018 08:54:50 +0100
+Subject: [PATCH] tools: prepare block tools for the removing of legacy I/O
+ path (#2070)
+
+Recent -next kernels don't have blk_start_request() function
+anymore. It has been removed in a recent cleanup. bio* tools should be
+able to handle the lack of this probe.
+---
+ tools/biolatency.py | 3 ++-
+ tools/biosnoop.py   | 3 ++-
+ tools/biotop.py     | 3 ++-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/tools/biolatency.py b/tools/biolatency.py
+index 3879af1..68aa577 100755
+--- a/tools/biolatency.py
++++ b/tools/biolatency.py
+@@ -116,7 +116,8 @@ b = BPF(text=bpf_text)
+ if args.queued:
+     b.attach_kprobe(event="blk_account_io_start", fn_name="trace_req_start")
+ else:
+-    b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start")
++    if BPF.get_kprobe_functions(b'blk_start_request'):
++        b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start")
+     b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_req_start")
+ b.attach_kprobe(event="blk_account_io_completion",
+     fn_name="trace_req_completion")
+diff --git a/tools/biosnoop.py b/tools/biosnoop.py
+index 2b1e77d..d036c0b 100755
+--- a/tools/biosnoop.py
++++ b/tools/biosnoop.py
+@@ -122,7 +122,8 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req)
+ }
+ """, debug=0)
+ b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start")
+-b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start")
++if BPF.get_kprobe_functions(b'blk_start_request'):
++    b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start")
+ b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_req_start")
+ b.attach_kprobe(event="blk_account_io_completion",
+     fn_name="trace_req_completion")
+diff --git a/tools/biotop.py b/tools/biotop.py
+index c6e1ca2..b2b5089 100755
+--- a/tools/biotop.py
++++ b/tools/biotop.py
+@@ -173,7 +173,8 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req)
+ 
+ b = BPF(text=bpf_text)
+ b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start")
+-b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start")
++if BPF.get_kprobe_functions(b'blk_start_request'):
++    b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start")
+ b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_req_start")
+ b.attach_kprobe(event="blk_account_io_completion",
+     fn_name="trace_req_completion")
+-- 
+2.19.2
+
diff --git a/SOURCES/uflow-str-bytes.patch b/SOURCES/uflow-str-bytes.patch
new file mode 100644
index 0000000..e28b98e
--- /dev/null
+++ b/SOURCES/uflow-str-bytes.patch
@@ -0,0 +1,65 @@
+From 215fc84bac0037ac5b2047940f97ecc97f0860b9 Mon Sep 17 00:00:00 2001
+From: Marko Myllynen <myllynen@redhat.com>
+Date: Fri, 5 Oct 2018 16:47:29 +0300
+Subject: [PATCH 1/2] uflow: convert bytes to str
+
+Python 3 fix, similar to commit 99d1468 and commit 4e4c9e0 for ucalls.
+
+Closes #1996.
+---
+ tools/lib/uflow.py | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/lib/uflow.py b/tools/lib/uflow.py
+index fb306e31d..fdbcfc332 100755
+--- a/tools/lib/uflow.py
++++ b/tools/lib/uflow.py
+@@ -196,7 +196,9 @@ def print_event(cpu, data, size):
+     direction = "<- " if event.depth & (1 << 63) else "-> "
+     print("%-3d %-6d %-6d %-8.3f %-40s" % (cpu, event.pid >> 32,
+         event.pid & 0xFFFFFFFF, time.time() - start_ts,
+-        ("  " * (depth - 1)) + direction + event.clazz + "." + event.method))
++        ("  " * (depth - 1)) + direction + \
++            event.clazz.decode('utf-8', 'replace') + "." + \
++            event.method.decode('utf-8', 'replace')))
+ 
+ bpf["calls"].open_perf_buffer(print_event)
+ while 1:
+
+From 1c7e2a8f3fb02d4516fccc410272324fff250be9 Mon Sep 17 00:00:00 2001
+From: Marko Myllynen <myllynen@redhat.com>
+Date: Fri, 5 Oct 2018 17:16:13 +0300
+Subject: [PATCH 2/2] uflow: drop unused timestamp field
+
+---
+ tools/lib/uflow.py | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/tools/lib/uflow.py b/tools/lib/uflow.py
+index fdbcfc332..f2a458d7b 100755
+--- a/tools/lib/uflow.py
++++ b/tools/lib/uflow.py
+@@ -49,7 +49,6 @@
+ struct call_t {
+     u64 depth;                  // first bit is direction (0 entry, 1 return)
+     u64 pid;                    // (tgid << 32) + pid from bpf_get_current...
+-    u64 timestamp;              // ns
+     char clazz[80];
+     char method[80];
+ };
+@@ -89,7 +88,6 @@
+     FILTER_METHOD
+ 
+     data.pid = bpf_get_current_pid_tgid();
+-    data.timestamp = bpf_ktime_get_ns();
+     depth = entry.lookup_or_init(&data.pid, &zero);
+     data.depth = DEPTH;
+     UPDATE
+@@ -183,7 +181,6 @@ class CallEvent(ct.Structure):
+     _fields_ = [
+         ("depth", ct.c_ulonglong),
+         ("pid", ct.c_ulonglong),
+-        ("timestamp", ct.c_ulonglong),
+         ("clazz", ct.c_char * 80),
+         ("method", ct.c_char * 80)
+         ]
diff --git a/SPECS/bcc.spec b/SPECS/bcc.spec
new file mode 100644
index 0000000..a815764
--- /dev/null
+++ b/SPECS/bcc.spec
@@ -0,0 +1,302 @@
+# luajit is not available RHEL 8
+%bcond_with lua
+
+%bcond_without llvm_static
+
+Name:           bcc
+Version:        0.7.0
+Release:        5%{?dist}
+Summary:        BPF Compiler Collection (BCC)
+License:        ASL 2.0
+URL:            https://github.com/iovisor/bcc
+Source0:        %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
+Patch0:         uflow-str-bytes.patch
+Patch1:         fix-killsnoop.py-srr-bytes-type-error-2007.patch
+Patch2:         Tools-fixes-2009.patch
+Patch3:         Bytes-string-encoding-2004.patch
+Patch4:         covscan-fix-miscellaneaous-errors-2003.patch
+Patch5:         tools-prepare-block-tools-for-the-removing-of-legacy.patch
+Patch6:         biolatency-Fix-disks-bpf_probe_read-1980.patch
+Patch7:         manpage-remove-non-existent-p-option-from-the-biotop.patch
+# tests/cc doesn't compile on s390x, so disable it until we have a better fix
+Patch10:        Disable-tests-cc.patch
+
+# Arches will be included as upstream support is added and dependencies are
+# satisfied in the respective arches
+ExcludeArch: i686
+
+BuildRequires:  bison, cmake >= 2.8.7, flex, libxml2-devel
+BuildRequires:  python3-devel
+BuildRequires:  elfutils-libelf-devel
+BuildRequires:  llvm-devel
+BuildRequires:  clang-devel
+BuildRequires:  ncurses-devel
+%if %{with lua}
+BuildRequires: pkgconfig(luajit)
+%endif
+%if %{with llvm_static}
+BuildRequires:  llvm-static
+%endif
+
+BuildRequires: clang
+
+Requires:       %{name}-tools = %{version}-%{release}
+
+%description
+BCC is a toolkit for creating efficient kernel tracing and manipulation
+programs, and includes several useful tools and examples. It makes use of
+extended BPF (Berkeley Packet Filters), formally known as eBPF, a new feature
+that was first added to Linux 3.15. BCC makes BPF programs easier to write,
+with kernel instrumentation in C (and includes a C wrapper around LLVM), and
+front-ends in Python and lua. It is suited for many tasks, including
+performance analysis and network traffic control.
+
+
+%package devel
+Summary:        Shared library for BPF Compiler Collection (BCC)
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+
+%description devel
+The %{name}-devel package contains libraries and header files for developing
+application that use BPF Compiler Collection (BCC).
+
+
+%package doc
+Summary:        Examples for BPF Compiler Collection (BCC)
+Recommends:     python3-%{name} = %{version}-%{release}
+%if %{with lua}
+Recommends:     %{name}-lua = %{version}-%{release}
+%endif
+BuildArch:      noarch
+
+%description doc
+Examples for BPF Compiler Collection (BCC)
+
+
+%package -n python3-%{name}
+Summary:        Python3 bindings for BPF Compiler Collection (BCC)
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+%{?python_provide:%python_provide python3-%{srcname}}
+
+%description -n python3-%{name}
+Python3 bindings for BPF Compiler Collection (BCC)
+
+
+%if %{with lua}
+%package lua
+Summary:        Standalone tool to run BCC tracers written in Lua
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+
+%description lua
+Standalone tool to run BCC tracers written in Lua
+%endif
+
+
+%package tools
+Summary:        Command line tools for BPF Compiler Collection (BCC)
+Requires:       python3-%{name} = %{version}-%{release}
+Requires:       python3-netaddr
+Requires:       kernel-devel
+
+%description tools
+Command line tools for BPF Compiler Collection (BCC)
+
+%prep
+%setup
+
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+
+%ifarch s390x
+%patch10 -p1
+%endif
+
+%build
+%cmake . \
+        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+        -DREVISION_LAST=%{version} -DREVISION=%{version} -DPYTHON_CMD=python3
+%make_build
+
+%install
+%make_install
+
+# Fix python shebangs
+# This messes the timestamp and rpmdiff complains about it
+# Let's set the all thing according to a reference file
+touch -r %{buildroot}%{_datadir}/%{name}/examples/hello_world.py %{_tmppath}/timestamp
+
+find %{buildroot}%{_datadir}/%{name}/{tools,examples} -type f -exec \
+  sed -i -e '1s=^#!/usr/bin/python\([0-9.]\+\)\?$=#!%{__python3}=' \
+         -e '1s=^#!/usr/bin/env python\([0-9.]\+\)\?$=#!%{__python3}=' \
+         -e '1s=^#!/usr/bin/env bcc-lua$=#!/usr/bin/bcc-lua=' {} \;
+
+for i in `find %{buildroot}%{_datadir}/%{name}/examples/` ; do
+    touch -h -r %{_tmppath}/timestamp $i
+done
+
+# Move man pages to the right location
+mkdir -p %{buildroot}%{_mandir}
+mv %{buildroot}%{_datadir}/%{name}/man/* %{buildroot}%{_mandir}/
+# Avoid conflict with other manpages
+# https://bugzilla.redhat.com/show_bug.cgi?id=1517408
+for i in `find %{buildroot}%{_mandir} -name "*.gz"`; do
+  tname=$(basename $i)
+  rename $tname %{name}-$tname $i
+done
+# Fix the symlink too
+for i in `find %{buildroot}%{_mandir} -lname \*.gz` ; do
+    target=`readlink $i`;
+    ln -sf bcc-$target $i;
+done
+
+# We cannot run the test suit since it requires root and it makes changes to
+# the machine (e.g, IP address)
+#%check
+
+%ldconfig_scriptlets
+
+%files
+%doc README.md
+%license LICENSE.txt
+%{_libdir}/lib%{name}.so.*
+%{_libdir}/libbpf.so.*
+
+%files devel
+%{_libdir}/lib%{name}.so
+%{_libdir}/libbpf.so
+%{_libdir}/pkgconfig/lib%{name}.pc
+%{_includedir}/%{name}/
+
+%files -n python3-%{name}
+%{python3_sitelib}/%{name}*
+
+%files doc
+# % dir % {_docdir}/% {name}
+%doc %{_datadir}/%{name}/examples/
+%if %{without lua}
+%exclude %{_datadir}/%{name}/examples/lua
+%endif
+
+%files tools
+%dir %{_datadir}/%{name}
+%dir %{_datadir}/%{name}/tools
+%dir %{_datadir}/%{name}/introspection
+%{_datadir}/%{name}/tools/*
+%{_datadir}/%{name}/introspection/*
+%exclude %{_datadir}/%{name}/tools/old/
+# inject relies on BPF_KPROBE_OVERRIDE which is not set on RHEL 8
+%exclude %{_datadir}/%{name}/tools/inject
+# Neither btrfs nor zfs are available on RHEL8
+%exclude %{_datadir}/%{name}/tools/btrfs*
+%exclude %{_datadir}/%{name}/tools/zfs*
+%{_mandir}/man8/*
+
+%if %{with lua}
+%files lua
+%{_bindir}/bcc-lua
+%endif
+
+
+%changelog
+* Thu Dec 13 2018 Jerome Marchand <jmarchan@redhat.com> - 0.7.0-5
+- Fix biolatency -D
+- Fix biotop manpage
+- Rebuild for LLVM 7.0.1 (from Tom Stellard)
+
+* Mon Dec 10 2018 Jerome Marchand <jmarchan@redhat.com> - 0.7.0-4
+- Fix bio* tools
+
+* Mon Nov 05 2018 Jerome Marchand <jmarchan@redhat.com> - 0.7.0-3
+- Fix multiple bytes/string encoding issues
+- Fix misc covscan warning
+
+* Mon Oct 15 2018 Tom Stellard <tstellar@redhat.com> - 0.7.0-2
+- Drop explicit dependency on clang-libs
+
+* Fri Oct 12 2018 Jerome Marchand <jmarchan@redhat.com> - 0.7.0-1
+- Rebase on bcc-7.0.0
+- Remove useless tools (zfs*, btrfs* and inject) 
+
+* Thu Sep 20 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.1-1
+- Rebase on bcc-0.6.1
+
+* Thu Sep 20 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-6
+- llcstat: print a nicer error message on virtual machine
+- Add NSS support to sslsniff
+- Fixes miscellaneous error uncovered by covscan
+
+* Wed Aug 08 2018 Tom Stellard <tstellar@redhat.com> - 0.6.0-5
+- Use llvm-toolset-6.0 prefix for clang-libs dependency
+
+* Fri Aug 03 2018 Tom Stellard <tstellar@redhat.com> - 0.6.0-4
+- Rebuld for llvm-toolset-6.0
+
+* Wed Jul 18 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-3
+ - Disable lua on all arches
+
+* Tue Jun 26 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-2
+- Add clang-libs requirement
+- Fix manpages symlinks
+
+* Tue Jun 19 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-1
+- Rebase on bcc-0.6.0
+
+* Thu May 24 2018 Jerome Marchand <jmarchan@redhat.com> - 0.5.0-5
+- Enables build on ppc64(le) and s390x arches
+
+* Thu Apr 05 2018 Rafael Santos <rdossant@redhat.com> - 0.5.0-4
+- Resolves #1555627 - fix compilation error with latest llvm/clang
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Fri Feb 02 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.5.0-2
+- Switch to %%ldconfig_scriptlets
+
+* Wed Jan 03 2018 Rafael Santos <rdossant@redhat.com> - 0.5.0-1
+- Rebase to new released version
+
+* Thu Nov 16 2017 Rafael Santos <rdossant@redhat.com> - 0.4.0-4
+- Resolves #1517408 - avoid conflict with other manpages
+
+* Thu Nov 02 2017 Rafael Santos <rdossant@redhat.com> - 0.4.0-3
+- Use weak deps to not require lua subpkg on ppc64(le)
+
+* Wed Nov 01 2017 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.4.0-2
+- Rebuild for LLVM5
+
+* Wed Nov 01 2017 Rafael Fonseca <rdossant@redhat.com> - 0.4.0-1
+- Resolves #1460482 - rebase to new release
+- Resolves #1505506 - add support for LLVM 5.0
+- Resolves #1460482 - BPF module compilation issue
+- Partially address #1479990 - location of man pages
+- Enable ppc64(le) support without lua
+- Soname versioning for libbpf by ignatenkobrain
+
+* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.3.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.3.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Thu Mar 30 2017 Igor Gnatenko <ignatenko@redhat.com> - 0.3.0-2
+- Rebuild for LLVM4
+- Trivial fixes in spec
+
+* Fri Mar 10 2017 Rafael Fonseca <rdossant@redhat.com> - 0.3.0-1
+- Rebase to new release.
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.2.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Tue Jan 10 2017 Rafael Fonseca <rdossant@redhat.com> - 0.2.0-2
+- Fix typo
+
+* Tue Nov 29 2016 Rafael Fonseca <rdossant@redhat.com> - 0.2.0-1
+- Initial import