diff --git a/.bcc.metadata b/.bcc.metadata
new file mode 100644
index 0000000..71269e3
--- /dev/null
+++ b/.bcc.metadata
@@ -0,0 +1 @@
+34cd5c38225fedc75417f55108a306d6cbc198dd SOURCES/bcc-0.6.1.tar.gz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7c6148e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/bcc-0.6.1.tar.gz
diff --git a/README.md b/README.md
deleted file mode 100644
index 98f42b4..0000000
--- a/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-The master branch has no content
-
-Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6
-If you find this file in a distro specific branch, it means that no content has been checked in yet
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/Fix-tools-for-RHEL-7.patch b/SOURCES/Fix-tools-for-RHEL-7.patch
new file mode 100644
index 0000000..be136bb
--- /dev/null
+++ b/SOURCES/Fix-tools-for-RHEL-7.patch
@@ -0,0 +1,559 @@
+From c28fdc2ad6c6acbd6c61dc78a6c6e114572357a5 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Thu, 16 Aug 2018 14:58:56 +0200
+Subject: [PATCH] Fix tools for RHEL 7
+
+There some differences on RHEL 7 that make some tools fail. This patch
+fixes the following:
+ - missing /sys/kernel/debug/kprobes/blacklist file
+ - missing __vfs_read() function
+ - aio_read/write methods replaced by read/write_iter in file_operations
+ - changes in mnt_namespace structure
+ - change in finish_task_switch() argument list
+ - changes in sock_common struct
+ - missing TCP_NEW_SYN_RECV TCP state
+ - mm_page_alloc tracepoint returns page struct instead of PFN
+ - iocb argument removed from tcp_sendmsg()
+---
+ src/python/bcc/__init__.py |  7 +++++--
+ tools/btrfsdist.py         | 13 +++++++------
+ tools/btrfsslower.py       | 13 +++++++------
+ tools/cpudist.py           |  4 +++-
+ tools/ext4dist.py          | 11 ++++++-----
+ tools/ext4slower.py        | 13 +++++++------
+ tools/fileslower.py        | 13 +++++++++----
+ tools/memleak.py           | 12 ++++++++++--
+ tools/mountsnoop.py        |  9 ++++-----
+ tools/nfsslower.py         |  1 +
+ tools/offcputime.py        |  4 +++-
+ tools/offwaketime.py       |  4 +++-
+ tools/runqlat.py           |  2 +-
+ tools/runqslower.py        |  2 +-
+ tools/solisten.py          |  2 +-
+ tools/tcpsubnet.py         |  4 ++--
+ tools/tcptracer.py         |  9 ++++-----
+ tools/xfsdist.py           |  8 ++++----
+ tools/xfsslower.py         | 11 ++++++-----
+ 19 files changed, 84 insertions(+), 58 deletions(-)
+
+diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py
+index 8f793aa..470ac49 100644
+--- a/src/python/bcc/__init__.py
++++ b/src/python/bcc/__init__.py
+@@ -500,8 +500,11 @@ DEBUG_BPF_REGISTER_STATE = 0x10
+ 
+     @staticmethod
+     def get_kprobe_functions(event_re):
+-        with open("%s/../kprobes/blacklist" % TRACEFS, "rb") as blacklist_f:
+-            blacklist = set([line.rstrip().split()[1] for line in blacklist_f])
++        try:
++            with open("%s/../kprobes/blacklist" % TRACEFS, "rb") as blacklist_f:
++                blacklist = set([line.rstrip().split()[1] for line in blacklist_f])
++        except:
++            blacklist = set()
+         fns = []
+ 
+         in_init_section = 0
+diff --git a/tools/btrfsdist.py b/tools/btrfsdist.py
+index 4659ab4..3326b67 100755
+--- a/tools/btrfsdist.py
++++ b/tools/btrfsdist.py
+@@ -60,6 +60,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ 
+ #define OP_NAME_LEN 8
+@@ -81,7 +82,7 @@ int trace_entry(struct pt_regs *ctx)
+     return 0;
+ }
+ 
+-// The current btrfs (Linux 4.5) uses generic_file_read_iter() instead of it's
++// btrfs uses generic_file_aio_read() instead of it's
+ // own read function. So we need to trace that and then filter on btrfs, which
+ // I do by checking file->f_op.
+ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+@@ -193,13 +194,13 @@ bpf_text = bpf_text.replace('FACTOR', str(factor))
+ # load BPF program
+ b = BPF(text=bpf_text)
+ 
+-# Common file functions. See earlier comment about generic_file_read_iter().
+-b.attach_kprobe(event="generic_file_read_iter", fn_name="trace_read_entry")
+-b.attach_kprobe(event="btrfs_file_write_iter", fn_name="trace_entry")
++# Common file functions. See earlier comment about generic_file_aio_read().
++b.attach_kprobe(event="generic_file_aio_read", fn_name="trace_read_entry")
++b.attach_kprobe(event="btrfs_file_aio_write", fn_name="trace_entry")
+ b.attach_kprobe(event="generic_file_open", fn_name="trace_open_entry")
+ b.attach_kprobe(event="btrfs_sync_file", fn_name="trace_entry")
+-b.attach_kretprobe(event="generic_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="btrfs_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="generic_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="btrfs_file_aio_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="generic_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="btrfs_sync_file", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/btrfsslower.py b/tools/btrfsslower.py
+index 644cb22..a720396 100755
+--- a/tools/btrfsslower.py
++++ b/tools/btrfsslower.py
+@@ -63,6 +63,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ #include <linux/dcache.h>
+ 
+@@ -97,7 +98,7 @@ BPF_PERF_OUTPUT(events);
+ // Store timestamp and size on entry
+ //
+ 
+-// The current btrfs (Linux 4.5) uses generic_file_read_iter() instead of it's
++// btrfs uses generic_file_aio_read() instead of it's
+ // own read function. So we need to trace that and then filter on btrfs, which
+ // I do by checking file->f_op.
+ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+@@ -124,7 +125,7 @@ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+     return 0;
+ }
+ 
+-// btrfs_file_write_iter():
++// btrfs_file_aio_write():
+ int trace_write_entry(struct pt_regs *ctx, struct kiocb *iocb)
+ {
+     u64 id = bpf_get_current_pid_tgid();
+@@ -327,12 +328,12 @@ TASK_COMM_LEN = 16      # linux/sched.h
+ b = BPF(text=bpf_text)
+ 
+ # Common file functions. See earlier comment about generic_*().
+-b.attach_kprobe(event="generic_file_read_iter", fn_name="trace_read_entry")
+-b.attach_kprobe(event="btrfs_file_write_iter", fn_name="trace_write_entry")
++b.attach_kprobe(event="generic_file_aio_read", fn_name="trace_read_entry")
++b.attach_kprobe(event="btrfs_file_aio_write", fn_name="trace_write_entry")
+ b.attach_kprobe(event="generic_file_open", fn_name="trace_open_entry")
+ b.attach_kprobe(event="btrfs_sync_file", fn_name="trace_fsync_entry")
+-b.attach_kretprobe(event="generic_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="btrfs_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="generic_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="btrfs_file_aio_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="generic_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="btrfs_sync_file", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/cpudist.py b/tools/cpudist.py
+index 4d7c9eb..ddb675e 100755
+--- a/tools/cpudist.py
++++ b/tools/cpudist.py
+@@ -94,7 +94,9 @@ static inline void update_hist(u32 tgid, u32 pid, u64 ts)
+     STORE
+ }
+ 
+-int sched_switch(struct pt_regs *ctx, struct task_struct *prev)
++struct rq;
++
++int sched_switch(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev)
+ {
+     u64 ts = bpf_ktime_get_ns();
+     u64 pid_tgid = bpf_get_current_pid_tgid();
+diff --git a/tools/ext4dist.py b/tools/ext4dist.py
+index 227c138..f57cda8 100755
+--- a/tools/ext4dist.py
++++ b/tools/ext4dist.py
+@@ -60,6 +60,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ 
+ #define OP_NAME_LEN 8
+@@ -81,7 +82,7 @@ int trace_entry(struct pt_regs *ctx)
+     return 0;
+ }
+ 
+-// The current ext4 (Linux 4.5) uses generic_file_read_iter(), instead of it's
++// ext4 uses generic_file_aio_read(), instead of it's
+ // own function, for reads. So we need to trace that and then filter on ext4,
+ // which I do by checking file->f_op.
+ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+@@ -183,12 +184,12 @@ b = BPF(text=bpf_text)
+ if BPF.get_kprobe_functions('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")
+-b.attach_kprobe(event="ext4_file_write_iter", fn_name="trace_entry")
++	b.attach_kprobe(event="generic_file_aio_read", fn_name="trace_read_entry")
++b.attach_kprobe(event="ext4_file_write", fn_name="trace_entry")
+ b.attach_kprobe(event="ext4_file_open", fn_name="trace_entry")
+ b.attach_kprobe(event="ext4_sync_file", fn_name="trace_entry")
+-b.attach_kretprobe(event="generic_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="ext4_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="generic_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="ext4_file_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="ext4_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="ext4_sync_file", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/ext4slower.py b/tools/ext4slower.py
+index eb6430e..276123f 100755
+--- a/tools/ext4slower.py
++++ b/tools/ext4slower.py
+@@ -64,6 +64,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ #include <linux/dcache.h>
+ 
+@@ -98,7 +99,7 @@ BPF_PERF_OUTPUT(events);
+ // Store timestamp and size on entry
+ //
+ 
+-// The current ext4 (Linux 4.5) uses generic_file_read_iter(), instead of it's
++// ext4 uses generic_file_aio_read(), instead of it's
+ // own function, for reads. So we need to trace that and then filter on ext4,
+ // which I do by checking file->f_op.
+ // The new Linux version (since form 4.10) uses ext4_file_read_iter(), And if the 'CONFIG_FS_DAX' 
+@@ -128,7 +129,7 @@ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+     return 0;
+ }
+ 
+-// ext4_file_write_iter():
++// ext4_file_write():
+ int trace_write_entry(struct pt_regs *ctx, struct kiocb *iocb)
+ {
+     u64 id = bpf_get_current_pid_tgid();
+@@ -328,15 +329,15 @@ b = BPF(text=bpf_text)
+ if BPF.get_kprobe_functions(b'ext4_file_read_iter'):
+     b.attach_kprobe(event="ext4_file_read_iter", fn_name="trace_read_entry")
+ else:
+-    b.attach_kprobe(event="generic_file_read_iter", fn_name="trace_read_entry")
+-b.attach_kprobe(event="ext4_file_write_iter", fn_name="trace_write_entry")
++    b.attach_kprobe(event="generic_file_aio_read", fn_name="trace_read_entry")
++b.attach_kprobe(event="ext4_file_write", fn_name="trace_write_entry")
+ b.attach_kprobe(event="ext4_file_open", fn_name="trace_open_entry")
+ b.attach_kprobe(event="ext4_sync_file", fn_name="trace_fsync_entry")
+ if BPF.get_kprobe_functions(b'ext4_file_read_iter'):
+     b.attach_kretprobe(event="ext4_file_read_iter", fn_name="trace_read_return")
+ else:
+-    b.attach_kretprobe(event="generic_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="ext4_file_write_iter", fn_name="trace_write_return")
++    b.attach_kretprobe(event="generic_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="ext4_file_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="ext4_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="ext4_sync_file", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/fileslower.py b/tools/fileslower.py
+index 5caa4ca..6af91af 100755
+--- a/tools/fileslower.py
++++ b/tools/fileslower.py
+@@ -124,7 +124,7 @@ int trace_read_entry(struct pt_regs *ctx, struct file *file,
+     char __user *buf, size_t count)
+ {
+     // skip non-sync I/O; see kernel code for __vfs_read()
+-    if (!(file->f_op->read_iter))
++    if (!(file->f_op->aio_read))
+         return 0;
+     return trace_rw_entry(ctx, file, buf, count);
+ }
+@@ -133,7 +133,7 @@ int trace_write_entry(struct pt_regs *ctx, struct file *file,
+     char __user *buf, size_t count)
+ {
+     // skip non-sync I/O; see kernel code for __vfs_write()
+-    if (!(file->f_op->write_iter))
++    if (!(file->f_op->aio_write))
+         return 0;
+     return trace_rw_entry(ctx, file, buf, count);
+ }
+@@ -200,8 +200,13 @@ b = BPF(text=bpf_text)
+ # do_sync_read/do_sync_write), but those became static. So trace these from
+ # the parent functions, at the cost of more overhead, instead.
+ # Ultimately, we should be using [V]FS tracepoints.
+-b.attach_kprobe(event="__vfs_read", fn_name="trace_read_entry")
+-b.attach_kretprobe(event="__vfs_read", fn_name="trace_read_return")
++try:
++    b.attach_kprobe(event="__vfs_read", fn_name="trace_read_entry")
++    b.attach_kretprobe(event="__vfs_read", fn_name="trace_read_return")
++except:
++    # older kernels don't have __vfs_read so try vfs_read instead
++    b.attach_kprobe(event="vfs_read", fn_name="trace_read_entry")
++    b.attach_kretprobe(event="vfs_read", fn_name="trace_read_return")
+ try:
+     b.attach_kprobe(event="__vfs_write", fn_name="trace_write_entry")
+     b.attach_kretprobe(event="__vfs_write", fn_name="trace_write_return")
+diff --git a/tools/memleak.py b/tools/memleak.py
+index 5d69538..3cf9ee0 100755
+--- a/tools/memleak.py
++++ b/tools/memleak.py
+@@ -354,13 +354,21 @@ TRACEPOINT_PROBE(kmem, kmem_cache_free) {
+         return gen_free_enter((struct pt_regs *)args, (void *)args->ptr);
+ }
+ 
++/*
++ * Upstream reads the PFN here, but on RHEL7 kernel this is not available
++ * and the address of the pages struct is returned instead. This value is
++ * used as the key in a hash to identify each allocation. No other allocation
++ * should return an address belonging to mem_map, so there's no risk of
++ * colision
++ */
++
+ TRACEPOINT_PROBE(kmem, mm_page_alloc) {
+         gen_alloc_enter((struct pt_regs *)args, PAGE_SIZE << args->order);
+-        return gen_alloc_exit2((struct pt_regs *)args, args->pfn);
++        return gen_alloc_exit2((struct pt_regs *)args, (size_t)args->page);
+ }
+ 
+ TRACEPOINT_PROBE(kmem, mm_page_free) {
+-        return gen_free_enter((struct pt_regs *)args, (void *)args->pfn);
++        return gen_free_enter((struct pt_regs *)args, (void *)args->page);
+ }
+ """
+ 
+diff --git a/tools/mountsnoop.py b/tools/mountsnoop.py
+index 2d0fa1a..bec8993 100755
+--- a/tools/mountsnoop.py
++++ b/tools/mountsnoop.py
+@@ -24,7 +24,6 @@ bpf_text = r"""
+ #include <linux/sched.h>
+ 
+ #include <linux/nsproxy.h>
+-#include <linux/ns_common.h>
+ 
+ /*
+  * XXX: struct mnt_namespace is defined in fs/mount.h, which is private to the
+@@ -34,7 +33,7 @@ bpf_text = r"""
+  */
+ struct mnt_namespace {
+     atomic_t count;
+-    struct ns_common ns;
++    unsigned int proc_inum;
+ };
+ 
+ /*
+@@ -69,7 +68,7 @@ struct data_t {
+     union {
+         /* EVENT_MOUNT, EVENT_UMOUNT */
+         struct {
+-            /* current->nsproxy->mnt_ns->ns.inum */
++            /* current->nsproxy->proc_inum */
+             unsigned int mnt_ns;
+             char comm[TASK_COMM_LEN];
+             unsigned long flags;
+@@ -106,7 +105,7 @@ int syscall__mount(struct pt_regs *ctx, char __user *source,
+     task = (struct task_struct *)bpf_get_current_task();
+     nsproxy = task->nsproxy;
+     mnt_ns = nsproxy->mnt_ns;
+-    event.enter.mnt_ns = mnt_ns->ns.inum;
++    event.enter.mnt_ns = mnt_ns->proc_inum;
+     events.perf_submit(ctx, &event, sizeof(event));
+ 
+     event.type = EVENT_MOUNT_SOURCE;
+@@ -161,7 +160,7 @@ int syscall__umount(struct pt_regs *ctx, char __user *target, int flags)
+     task = (struct task_struct *)bpf_get_current_task();
+     nsproxy = task->nsproxy;
+     mnt_ns = nsproxy->mnt_ns;
+-    event.enter.mnt_ns = mnt_ns->ns.inum;
++    event.enter.mnt_ns = mnt_ns->proc_inum;
+     events.perf_submit(ctx, &event, sizeof(event));
+ 
+     event.type = EVENT_UMOUNT_TARGET;
+diff --git a/tools/nfsslower.py b/tools/nfsslower.py
+index 0f836af..a7018cb 100755
+--- a/tools/nfsslower.py
++++ b/tools/nfsslower.py
+@@ -65,6 +65,7 @@ bpf_text = """
+ 
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ #include <linux/dcache.h>
+ 
+diff --git a/tools/offcputime.py b/tools/offcputime.py
+index e1f3af9..802fbfd 100755
+--- a/tools/offcputime.py
++++ b/tools/offcputime.py
+@@ -128,7 +128,9 @@ BPF_HASH(counts, struct key_t);
+ BPF_HASH(start, u32);
+ BPF_STACK_TRACE(stack_traces, STACK_STORAGE_SIZE);
+ 
+-int oncpu(struct pt_regs *ctx, struct task_struct *prev) {
++struct rq;
++
++int oncpu(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev) {
+     u32 pid = prev->pid;
+     u32 tgid = prev->tgid;
+     u64 ts, *tsp;
+diff --git a/tools/offwaketime.py b/tools/offwaketime.py
+index 2b78c89..83838c9 100755
+--- a/tools/offwaketime.py
++++ b/tools/offwaketime.py
+@@ -163,7 +163,9 @@ int waker(struct pt_regs *ctx, struct task_struct *p) {
+     return 0;
+ }
+ 
+-int oncpu(struct pt_regs *ctx, struct task_struct *p) {
++struct rq;
++
++int oncpu(struct pt_regs *ctx, struct rq *rq, struct task_struct *p) {
+     // PID and TGID of the previous Process (Process going into waiting)
+     u32 pid = p->pid;
+     u32 tgid = p->tgid;
+diff --git a/tools/runqlat.py b/tools/runqlat.py
+index 9fd4064..0c9bb1c 100755
+--- a/tools/runqlat.py
++++ b/tools/runqlat.py
+@@ -111,7 +111,7 @@ int trace_ttwu_do_wakeup(struct pt_regs *ctx, struct rq *rq, struct task_struct
+ }
+ 
+ // calculate latency
+-int trace_run(struct pt_regs *ctx, struct task_struct *prev)
++int trace_run(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev)
+ {
+     u32 pid, tgid;
+ 
+diff --git a/tools/runqslower.py b/tools/runqslower.py
+index 7a1869c..b3e3fac 100755
+--- a/tools/runqslower.py
++++ b/tools/runqslower.py
+@@ -98,7 +98,7 @@ int trace_ttwu_do_wakeup(struct pt_regs *ctx, struct rq *rq, struct task_struct
+ }
+ 
+ // calculate latency
+-int trace_run(struct pt_regs *ctx, struct task_struct *prev)
++int trace_run(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev)
+ {
+     u32 pid, tgid;
+ 
+diff --git a/tools/solisten.py b/tools/solisten.py
+index 6a35f82..a9e8722 100755
+--- a/tools/solisten.py
++++ b/tools/solisten.py
+@@ -100,7 +100,7 @@ int kprobe__inet_listen(struct pt_regs *ctx, struct socket *sock, int backlog)
+ 
+         // Get network namespace id, if kernel supports it
+ #ifdef CONFIG_NET_NS
+-        evt.netns = sk->__sk_common.skc_net.net->ns.inum;
++        evt.netns = sk->__sk_common.skc_net->proc_inum;
+ #else
+         evt.netns = 0;
+ #endif
+diff --git a/tools/tcpsubnet.py b/tools/tcpsubnet.py
+index 2779276..f47eea7 100755
+--- a/tools/tcpsubnet.py
++++ b/tools/tcpsubnet.py
+@@ -110,8 +110,8 @@ struct index_key_t {
+ 
+ BPF_HASH(ipv4_send_bytes, struct index_key_t);
+ 
+-int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct sock *sk,
+-    struct msghdr *msg, size_t size)
++int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct kiocb *iocb,
++    struct sock *sk, struct msghdr *msg, size_t size)
+ {
+     u16 family = sk->__sk_common.skc_family;
+     u64 *val, zero = 0;
+diff --git a/tools/tcptracer.py b/tools/tcptracer.py
+index 5e97ee6..177e860 100755
+--- a/tools/tcptracer.py
++++ b/tools/tcptracer.py
+@@ -116,7 +116,7 @@ static int read_ipv4_tuple(struct ipv4_tuple_t *tuple, struct sock *skp)
+   u16 sport = sockp->inet_sport;
+   u16 dport = skp->__sk_common.skc_dport;
+ #ifdef CONFIG_NET_NS
+-  net_ns_inum = skp->__sk_common.skc_net.net->ns.inum;
++  net_ns_inum = skp->__sk_common.skc_net->proc_inum;
+ #endif
+ 
+   ##FILTER_NETNS##
+@@ -143,7 +143,7 @@ static int read_ipv6_tuple(struct ipv6_tuple_t *tuple, struct sock *skp)
+   u16 sport = sockp->inet_sport;
+   u16 dport = skp->__sk_common.skc_dport;
+ #ifdef CONFIG_NET_NS
+-  net_ns_inum = skp->__sk_common.skc_net.net->ns.inum;
++  net_ns_inum = skp->__sk_common.skc_net->proc_inum;
+ #endif
+   bpf_probe_read(&saddr, sizeof(saddr),
+                  skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
+@@ -361,8 +361,7 @@ int trace_close_entry(struct pt_regs *ctx, struct sock *skp)
+   // Don't generate close events for connections that were never
+   // established in the first place.
+   if (oldstate == TCP_SYN_SENT ||
+-      oldstate == TCP_SYN_RECV ||
+-      oldstate == TCP_NEW_SYN_RECV)
++      oldstate == TCP_SYN_RECV )
+       return 0;
+ 
+   u8 ipver = 0;
+@@ -433,7 +432,7 @@ int trace_accept_return(struct pt_regs *ctx)
+ 
+   // Get network namespace id, if kernel supports it
+ #ifdef CONFIG_NET_NS
+-  net_ns_inum = newsk->__sk_common.skc_net.net->ns.inum;
++  net_ns_inum = newsk->__sk_common.skc_net->proc_inum;
+ #endif
+ 
+   ##FILTER_NETNS##
+diff --git a/tools/xfsdist.py b/tools/xfsdist.py
+index f409f90..2976f9e 100755
+--- a/tools/xfsdist.py
++++ b/tools/xfsdist.py
+@@ -137,12 +137,12 @@ bpf_text = bpf_text.replace('FACTOR', str(factor))
+ b = BPF(text=bpf_text)
+ 
+ # common file functions
+-b.attach_kprobe(event="xfs_file_read_iter", fn_name="trace_entry")
+-b.attach_kprobe(event="xfs_file_write_iter", fn_name="trace_entry")
++b.attach_kprobe(event="xfs_file_aio_read", fn_name="trace_entry")
++b.attach_kprobe(event="xfs_file_aio_write", fn_name="trace_entry")
+ b.attach_kprobe(event="xfs_file_open", fn_name="trace_entry")
+ b.attach_kprobe(event="xfs_file_fsync", fn_name="trace_entry")
+-b.attach_kretprobe(event="xfs_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="xfs_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="xfs_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="xfs_file_aio_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="xfs_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="xfs_file_fsync", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/xfsslower.py b/tools/xfsslower.py
+index da70c57..4320284 100755
+--- a/tools/xfsslower.py
++++ b/tools/xfsslower.py
+@@ -60,6 +60,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ #include <linux/dcache.h>
+ 
+@@ -94,7 +95,7 @@ BPF_PERF_OUTPUT(events);
+ // Store timestamp and size on entry
+ //
+ 
+-// xfs_file_read_iter(), xfs_file_write_iter():
++// xfs_file_aio_read(), xfs_file_aio_write():
+ int trace_rw_entry(struct pt_regs *ctx, struct kiocb *iocb)
+ {
+     u64 id = bpf_get_current_pid_tgid();
+@@ -273,12 +274,12 @@ TASK_COMM_LEN = 16      # linux/sched.h
+ b = BPF(text=bpf_text)
+ 
+ # common file functions
+-b.attach_kprobe(event="xfs_file_read_iter", fn_name="trace_rw_entry")
+-b.attach_kprobe(event="xfs_file_write_iter", fn_name="trace_rw_entry")
++b.attach_kprobe(event="xfs_file_aio_read", fn_name="trace_rw_entry")
++b.attach_kprobe(event="xfs_file_aio_write", fn_name="trace_rw_entry")
+ b.attach_kprobe(event="xfs_file_open", fn_name="trace_open_entry")
+ b.attach_kprobe(event="xfs_file_fsync", fn_name="trace_fsync_entry")
+-b.attach_kretprobe(event="xfs_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="xfs_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="xfs_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="xfs_file_aio_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="xfs_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="xfs_file_fsync", fn_name="trace_fsync_return")
+ 
+-- 
+2.17.1
+
diff --git a/SOURCES/Miscellaneous-fixes-1914.patch b/SOURCES/Miscellaneous-fixes-1914.patch
new file mode 100644
index 0000000..20eba8c
--- /dev/null
+++ b/SOURCES/Miscellaneous-fixes-1914.patch
@@ -0,0 +1,127 @@
+From b84714a47a3a1ec646bbd489442b305c84b35e15 Mon Sep 17 00:00:00 2001
+From: jeromemarchand <38073585+jeromemarchand@users.noreply.github.com>
+Date: Wed, 8 Aug 2018 18:09:44 +0200
+Subject: [PATCH] Miscellaneous fixes (#1914)
+
+* Fix multiple memory access errors
+
+Fixes a buffer overflow in get_pid_exe(), a use-after-free error in
+bcc_usdt_get_probe_argctype() and a possible NULL pointer dereference
+in find_debug_via_debuglink().
+
+* Fix multiple ressource leaks
+
+Leaked file descriptors in bpf_attach_uprobe() and verify_checksum().
+Memory leaks in  Parser::func_add() and bcc_procutils_language().
+
+* fixup! Fix multiple ressource leaks
+---
+ src/cc/bcc_elf.c             | 6 ++++--
+ src/cc/bcc_proc.c            | 4 +++-
+ src/cc/common.cc             | 2 ++
+ src/cc/frontends/b/parser.cc | 4 +++-
+ src/cc/libbpf.c              | 1 +
+ src/cc/usdt/usdt.cc          | 5 +++--
+ 6 files changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/src/cc/bcc_elf.c b/src/cc/bcc_elf.c
+index e848912..c425db6 100644
+--- a/src/cc/bcc_elf.c
++++ b/src/cc/bcc_elf.c
+@@ -377,8 +377,10 @@ static int verify_checksum(const char *file, unsigned int crc) {
+   if (fd < 0)
+     return 0;
+ 
+-  if (fstat(fd, &st) < 0)
++  if (fstat(fd, &st) < 0) {
++    close(fd);
+     return 0;
++  }
+ 
+   buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+   if (!buf) {
+@@ -433,7 +435,7 @@ static char *find_debug_via_debuglink(Elf *e, const char *binpath,
+ 
+ DONE:
+   free(bindir);
+-  if (check_crc && !verify_checksum(res, crc))
++  if (res && check_crc && !verify_checksum(res, crc))
+     return NULL;
+   return res;
+ }
+diff --git a/src/cc/bcc_proc.c b/src/cc/bcc_proc.c
+index 14ee18e..6fe11a0 100644
+--- a/src/cc/bcc_proc.c
++++ b/src/cc/bcc_proc.c
+@@ -446,8 +446,10 @@ const char *bcc_procutils_language(int pid) {
+       while (isspace(mapname[0])) mapname++;
+       for (i = 0; i < nb_languages; i++) {
+         snprintf(pathname, sizeof(pathname), "/lib%s", languages[i]);
+-        if (strstr(mapname, pathname))
++        if (strstr(mapname, pathname)) {
++          fclose(procfile);
+           return languages[i];
++	}
+         if ((str = strstr(mapname, "libc")) &&
+             (str[4] == '-' || str[4] == '.'))
+           libc = true;
+diff --git a/src/cc/common.cc b/src/cc/common.cc
+index 1cfe91a..c8370a3 100644
+--- a/src/cc/common.cc
++++ b/src/cc/common.cc
+@@ -57,6 +57,8 @@ std::string get_pid_exe(pid_t pid) {
+   res = readlink(exe_link.c_str(), exe_path, sizeof(exe_path));
+   if (res == -1)
+     return "";
++  if (res >= sizeof(exe_path))
++    res = sizeof(exe_path) - 1;
+   exe_path[res] = '\0';
+   return std::string(exe_path);
+ }
+diff --git a/src/cc/frontends/b/parser.cc b/src/cc/frontends/b/parser.cc
+index 9e61346..8a5e149 100644
+--- a/src/cc/frontends/b/parser.cc
++++ b/src/cc/frontends/b/parser.cc
+@@ -199,8 +199,10 @@ StmtNode * Parser::func_add(vector<int> *types, Scopes::StateScope *scope,
+   auto cur_scope = scopes_->current_var();
+   scopes_->set_current(scope);
+   for (auto it = formals->begin(); it != formals->end(); ++it)
+-    if (!variable_add(nullptr, it->get()))
++    if (!variable_add(nullptr, it->get())) {
++      delete decl;
+       return nullptr;
++    }
+   scopes_->set_current(cur_scope);
+   decl->scope_ = scope;
+   scopes_->top_func()->add(id->name_, decl);
+diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c
+index c23030e..acfbc5e 100644
+--- a/src/cc/libbpf.c
++++ b/src/cc/libbpf.c
+@@ -925,6 +925,7 @@ static void exit_mount_ns(int fd) {
+ 
+   if (setns(fd, CLONE_NEWNS))
+     perror("setns");
++  close(fd);
+ }
+ 
+ int bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type,
+diff --git a/src/cc/usdt/usdt.cc b/src/cc/usdt/usdt.cc
+index 2992593..2010520 100644
+--- a/src/cc/usdt/usdt.cc
++++ b/src/cc/usdt/usdt.cc
+@@ -478,8 +478,9 @@ const char *bcc_usdt_get_probe_argctype(
+   void *ctx, const char* probe_name, const int arg_index
+ ) {
+   USDT::Probe *p = static_cast<USDT::Context *>(ctx)->get(probe_name);
+-  std::string res = p ? p->get_arg_ctype(arg_index) : "";
+-  return res.c_str();
++  if (p)
++    return p->get_arg_ctype(arg_index).c_str();
++  return "";
+ }
+ 
+ void bcc_usdt_foreach(void *usdt, bcc_usdt_cb callback) {
+-- 
+2.17.1
+
diff --git a/SOURCES/link-against-libLLVM.so-instead-of-static-libs.patch b/SOURCES/link-against-libLLVM.so-instead-of-static-libs.patch
new file mode 100644
index 0000000..c39e643
--- /dev/null
+++ b/SOURCES/link-against-libLLVM.so-instead-of-static-libs.patch
@@ -0,0 +1,30 @@
+From ddbdaef40b7db8259f7728a64839b9ff38fbfd76 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Fri, 15 Jun 2018 11:41:47 +0200
+Subject: [PATCH] Link against libLLVM.so instead of static libs
+
+---
+ src/cc/CMakeLists.txt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cc/CMakeLists.txt b/src/cc/CMakeLists.txt
+index 8ddfd8f..0c3d7df 100644
+--- a/src/cc/CMakeLists.txt
++++ b/src/cc/CMakeLists.txt
+@@ -62,11 +62,11 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${llvm_lib_exclude_f
+ # bcc_common_libs_for_a for archive libraries
+ # bcc_common_libs_for_s for shared libraries
+ set(bcc_common_libs_for_a b_frontend clang_frontend bpf-static
+-  -Wl,--whole-archive ${clang_libs} ${llvm_libs} -Wl,--no-whole-archive
++  -Wl,--whole-archive ${clang_libs} libLLVM-6.0-rhel.so -Wl,--no-whole-archive
+   ${LIBELF_LIBRARIES})
+ set(bcc_common_libs_for_s ${bcc_common_libs_for_a})
+ set(bcc_common_libs_for_lua b_frontend clang_frontend bpf-static
+-  ${clang_libs} ${llvm_libs} ${LIBELF_LIBRARIES})
++  ${clang_libs} libLLVM-6.0-rhel.so ${LIBELF_LIBRARIES})
+ 
+ if(ENABLE_CPP_API)
+   add_subdirectory(api)
+-- 
+2.17.1
+
diff --git a/SOURCES/llcstat-print-a-nicer-error-message-when-hardware-ev.patch b/SOURCES/llcstat-print-a-nicer-error-message-when-hardware-ev.patch
new file mode 100644
index 0000000..bec257c
--- /dev/null
+++ b/SOURCES/llcstat-print-a-nicer-error-message-when-hardware-ev.patch
@@ -0,0 +1,43 @@
+From d274b66f58d59d97543c8b64e9f88449581e4299 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Tue, 7 Aug 2018 17:24:31 +0200
+Subject: [PATCH] llcstat: print a nicer error message when hardware events are
+ missing
+
+Hardware events such as CACHE_MISSES and CACHE_REFERENCES are usually
+not available on virtual machine. Print a more useful message when
+this happen.
+---
+ tools/llcstat.py | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/tools/llcstat.py b/tools/llcstat.py
+index e59f9a8..fe8bdd9 100755
+--- a/tools/llcstat.py
++++ b/tools/llcstat.py
+@@ -78,12 +78,16 @@ int on_cache_ref(struct bpf_perf_event_data *ctx) {
+     exit()
+ 
+ b = BPF(text=bpf_text)
+-b.attach_perf_event(
+-    ev_type=PerfType.HARDWARE, ev_config=PerfHWConfig.CACHE_MISSES,
+-    fn_name="on_cache_miss", sample_period=args.sample_period)
+-b.attach_perf_event(
+-    ev_type=PerfType.HARDWARE, ev_config=PerfHWConfig.CACHE_REFERENCES,
+-    fn_name="on_cache_ref", sample_period=args.sample_period)
++try:
++    b.attach_perf_event(
++        ev_type=PerfType.HARDWARE, ev_config=PerfHWConfig.CACHE_MISSES,
++        fn_name="on_cache_miss", sample_period=args.sample_period)
++    b.attach_perf_event(
++        ev_type=PerfType.HARDWARE, ev_config=PerfHWConfig.CACHE_REFERENCES,
++        fn_name="on_cache_ref", sample_period=args.sample_period)
++except:
++    print("Failed to attach to a hardware event. Is this a virtual machine?")
++    exit()
+ 
+ print("Running for {} seconds or hit Ctrl-C to end.".format(args.duration))
+ 
+-- 
+2.17.1
+
diff --git a/SOURCES/sslsniff-add-NSS-support-1908.patch b/SOURCES/sslsniff-add-NSS-support-1908.patch
new file mode 100644
index 0000000..fc1c74d
--- /dev/null
+++ b/SOURCES/sslsniff-add-NSS-support-1908.patch
@@ -0,0 +1,185 @@
+From 8b17dc3472a9c11139d0058bbf8b42eae66022b8 Mon Sep 17 00:00:00 2001
+From: jeromemarchand <38073585+jeromemarchand@users.noreply.github.com>
+Date: Sat, 4 Aug 2018 07:09:36 +0200
+Subject: [PATCH] sslsniff: add NSS support (#1908)
+
+* sslsniff: add NSS support
+
+* sslsniff: update documentation
+---
+ man/man8/sslsniff.8        | 18 +++++++++---------
+ tools/sslsniff.py          | 21 +++++++++++++++++++--
+ tools/sslsniff_example.txt | 16 +++++++++-------
+ 3 files changed, 37 insertions(+), 18 deletions(-)
+
+diff --git a/man/man8/sslsniff.8 b/man/man8/sslsniff.8
+index e20e28a..72836e2 100644
+--- a/man/man8/sslsniff.8
++++ b/man/man8/sslsniff.8
+@@ -1,12 +1,12 @@
+ .TH sslsniff 8  "2016-08-16" "USER COMMANDS"
+ .SH NAME
+-sslsniff \- Print data passed to OpenSSL. Uses Linux eBPF/bcc.
++sslsniff \- Print data passed to OpenSSL, GnuTLS or NSS. Uses Linux eBPF/bcc.
+ .SH SYNOPSIS
+-.B sslsniff
++.B sslsniff [-h] [-p PID] [-c COMM] [-o] [-g] [-n] [-d]
+ .SH DESCRIPTION
+-sslsniff prints data sent to SSL_write and SSL_read OpenSSL functions, allowing
+-us to read plain text content before encryption (when writing) and after
+-decryption (when reading).
++sslsniff prints data sent to write/send and read/recv functions of
++OpenSSL, GnuTLS and NSS, allowing us to read plain text content before
++encryption (when writing) and after decryption (when reading).
+ 
+ This works reading the second parameter of both functions (*buf).
+ 
+@@ -15,13 +15,13 @@ Since this uses BPF, only the root user can use this tool.
+ CONFIG_BPF and bcc.
+ .SH EXAMPLES
+ .TP
+-Print all calls to SSL_write and SSL_read system-wide:
++Print all calls to SSL write/send and read/recv system-wide:
+ #
+ .B sslsniff
+ .SH FIELDS
+ .TP
+ FUNC
+-Which function is being called (SSL_write or SSL_read)
++Which function is being called (write/send or read/recv)
+ .TP
+ TIME
+ Time of the command, in seconds.
+@@ -30,10 +30,10 @@ COMM
+ Entered command.
+ .TP
+ PID
+-Process ID calling OpenSSL.
++Process ID calling SSL.
+ .TP
+ LEN
+-Bytes written or read by OpenSSL functions.
++Bytes written or read by SSL functions.
+ .SH SOURCE
+ This is from bcc.
+ .IP
+diff --git a/tools/sslsniff.py b/tools/sslsniff.py
+index 174577b..2e74fba 100755
+--- a/tools/sslsniff.py
++++ b/tools/sslsniff.py
+@@ -1,7 +1,7 @@
+ #!/usr/bin/python
+ #
+-# sslsniff  Captures data on read/recv or write/send functions of OpenSSL and
+-#           GnuTLS
++# sslsniff  Captures data on read/recv or write/send functions of OpenSSL,
++#           GnuTLS and NSS
+ #           For Linux, uses BCC, eBPF.
+ #
+ # USAGE: sslsniff.py [-h] [-p PID] [-c COMM] [-o] [-g] [-d]
+@@ -25,6 +25,7 @@ import argparse
+     ./sslsniff -c curl      # sniff curl command only
+     ./sslsniff --no-openssl # don't show OpenSSL calls
+     ./sslsniff --no-gnutls  # don't show GnuTLS calls
++    ./sslsniff --no-nss     # don't show NSS calls
+ """
+ parser = argparse.ArgumentParser(
+     description="Sniff SSL data",
+@@ -37,6 +38,8 @@ parser.add_argument("-o", "--no-openssl", action="store_false", dest="openssl",
+                     help="do not show OpenSSL calls.")
+ parser.add_argument("-g", "--no-gnutls", action="store_false", dest="gnutls",
+                     help="do not show GnuTLS calls.")
++parser.add_argument("-n", "--no-nss", action="store_false", dest="nss",
++                    help="do not show NSS calls.")
+ parser.add_argument('-d', '--debug', dest='debug', action='count', default=0,
+                     help='debug mode.')
+ parser.add_argument("--ebpf", action="store_true",
+@@ -149,6 +152,20 @@ b = BPF(text=prog)
+     b.attach_uretprobe(name="gnutls", sym="gnutls_record_recv",
+                        fn_name="probe_SSL_read_exit", pid=args.pid or -1)
+ 
++if args.nss:
++    b.attach_uprobe(name="nspr4", sym="PR_Write", fn_name="probe_SSL_write",
++                    pid=args.pid or -1)
++    b.attach_uprobe(name="nspr4", sym="PR_Send", fn_name="probe_SSL_write",
++                    pid=args.pid or -1)
++    b.attach_uprobe(name="nspr4", sym="PR_Read", fn_name="probe_SSL_read_enter",
++                    pid=args.pid or -1)
++    b.attach_uretprobe(name="nspr4", sym="PR_Read",
++                       fn_name="probe_SSL_read_exit", pid=args.pid or -1)
++    b.attach_uprobe(name="nspr4", sym="PR_Recv", fn_name="probe_SSL_read_enter",
++                    pid=args.pid or -1)
++    b.attach_uretprobe(name="nspr4", sym="PR_Recv",
++                       fn_name="probe_SSL_read_exit", pid=args.pid or -1)
++
+ # define output data structure in Python
+ TASK_COMM_LEN = 16  # linux/sched.h
+ MAX_BUF_SIZE = 464  # Limited by the BPF stack
+diff --git a/tools/sslsniff_example.txt b/tools/sslsniff_example.txt
+index c16b572..8c51722 100644
+--- a/tools/sslsniff_example.txt
++++ b/tools/sslsniff_example.txt
+@@ -1,16 +1,16 @@
+ Demonstrations of sslsniff.py
+ 
+ 
+-This tool traces the OpenSSL functions SSL_READ and SSL_WRITE.
+-Data passed to this functions is printed as plain text.
+-Useful, for example, to sniff HTTP before encrypted with SSL.
++This tool traces the write/send and read/recv functions of OpenSSL,
++GnuTLS and NSS.  Data passed to this functions is printed as plain
++text.  Useful, for example, to sniff HTTP before encrypted with SSL.
+ 
+ 
+ Output of tool executing in other shell "curl https://example.com"
+ 
+ % sudo python sslsniff.py
+ FUNC         TIME(s)            COMM             PID    LEN   
+-SSL_WRITE    0.000000000        curl             12915  75    
++WRITE/SEND   0.000000000        curl             12915  75    
+ ----- DATA -----
+ GET / HTTP/1.1
+ Host: example.com
+@@ -20,7 +20,7 @@ Accept: */*
+ 
+ ----- END DATA -----
+ 
+-SSL_READ     0.127144585        curl             12915  333   
++READ/RECV    0.127144585        curl             12915  333   
+ ----- DATA -----
+ HTTP/1.1 200 OK
+ Cache-Control: max-age=604800
+@@ -38,7 +38,7 @@ Content-Length: 1270
+ 
+ ----- END DATA -----
+ 
+-SSL_READ     0.129967972        curl             12915  1270  
++READ/RECV    0.129967972        curl             12915  1270  
+ ----- DATA -----
+ <!doctype html>
+ <html>
+@@ -65,7 +65,7 @@ SSL_READ     0.129967972        curl             12915  1270
+ 
+ USAGE message:
+ 
+-usage: sslsniff.py [-h] [-p PID] [-c COMM] [-o] [-g] [-d]
++usage: sslsniff.py [-h] [-p PID] [-c COMM] [-o] [-g] [-n] [-d]
+ 
+ Sniff SSL data
+ 
+@@ -75,6 +75,7 @@ Sniff SSL data
+   -c COMM, --comm COMM  sniff only commands matching string.
+   -o, --no-openssl      do not show OpenSSL calls.
+   -g, --no-gnutls       do not show GnuTLS calls.
++  -n, --no-nss          do not show NSS calls.
+   -d, --debug           debug mode.
+ 
+ examples:
+@@ -83,3 +84,4 @@ Sniff SSL data
+     ./sslsniff -c curl      # sniff curl command only
+     ./sslsniff --no-openssl # don't show OpenSSL calls
+     ./sslsniff --no-gnutls  # don't show GnuTLS calls
++    ./sslsniff --no-nss     # don't show NSS calls
+-- 
+2.17.1
+
diff --git a/SPECS/bcc.spec b/SPECS/bcc.spec
new file mode 100644
index 0000000..885c385
--- /dev/null
+++ b/SPECS/bcc.spec
@@ -0,0 +1,262 @@
+# luajit is not available for some architectures and not at all on RHEL7
+%if 0%{?rhel} <= 7
+%bcond_with lua
+%else
+%ifarch ppc64 ppc64le s390x
+%bcond_with lua
+%else
+%bcond_without lua
+%endif
+%endif
+
+Name:           bcc
+Version:        0.6.1
+Release:        2%{?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:         link-against-libLLVM.so-instead-of-static-libs.patch
+Patch1:         Fix-tools-for-RHEL-7.patch
+Patch2:         sslsniff-add-NSS-support-1908.patch
+Patch3:         llcstat-print-a-nicer-error-message-when-hardware-ev.patch
+Patch4:         Miscellaneous-fixes-1914.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 ppc s390
+
+BuildRequires:  bison, cmake >= 2.8.7, flex, libxml2-devel
+BuildRequires:  python-devel
+BuildRequires:  elfutils-libelf-devel
+BuildRequires:  ncurses-devel
+%if %{with lua}
+BuildRequires: pkgconfig(luajit)
+%endif
+BuildRequires: llvm-private-devel >= 6.0.1-0.3
+
+Requires:       %{name}-tools = %{version}-%{release}
+Requires:       llvm-private >= 6.0.1-0.3
+
+%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)
+BuildArch:      noarch
+
+%description doc
+Examples for BPF Compiler Collection (BCC)
+
+
+%package -n python-%{name}
+Summary:        Python bindings for BPF Compiler Collection (BCC)
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+%{?python_provide:%python_provide python-%{srcname}}
+
+%description -n python-%{name}
+Python 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:       python-%{name} = %{version}-%{release}
+Requires:       python-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
+
+%ifarch s390x
+%patch10 -p1
+%endif
+
+%build
+%cmake . \
+        -DCMAKE_BUILD_TYPE=RelWithDebInfo\
+        -DCMAKE_CXX_FLAGS='-std=c++11 -I/usr/include/llvm-private/'\
+        -DREVISION_LAST=%{version} -DREVISION=%{version}\
+        -DCMAKE_LIBRARY_PATH=/usr/lib64/clang-private/\
+	-DCMAKE_INSTALL_RPATH=/usr/lib64/clang-private/
+%make_build
+
+%install
+%make_install
+
+# 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
+mkdir -p %{buildroot}%{_docdir}/%{name}
+mv %{buildroot}%{_datadir}/%{name}/examples %{buildroot}%{_docdir}/%{name}/
+
+# We cannot run the test suit since it requires root and it makes changes to
+# the machine (e.g, IP address)
+#%check
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+%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 python-%{name}
+%{python_sitelib}/%{name}*
+
+%files doc
+%dir %{_docdir}/%{name}
+%doc %{_docdir}/%{name}/examples/
+
+%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 absent on RHEL 7
+%exclude %{_datadir}/%{name}/tools/inject
+# ZFS isn't available on RHEL
+%exclude %{_datadir}/%{name}/tools/zfs*
+%{_mandir}/man8/*
+
+%if %{with lua}
+%files lua
+%{_bindir}/bcc-lua
+%endif
+
+
+%changelog
+* Fri Sep 21 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.1-2
+- Set a minimal version for llvm-private(-devel)
+
+* Thu Aug 16 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.1-1
+- Rebase on v0.6.1
+- Fix tcpsubnet
+- Reinstate llcstat tool
+- Remove inject tool
+- Add NSS support to sslsniff
+- Fixes miscellaneous error uncovered by covscan
+
+* Wed Jul 04 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-3
+- Fix tools on RHEL 7
+- Remove llcstat and ZFS tools.
+
+* Tue Jun 26 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-2
+- Add llvm-private requirement
+- Fix manpages symlinks
+
+* Tue Jun 19 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-1
+- Rebase on bcc-0.6.0
+
+* Thu Jun 07 2018 Jerome Marchand <jmarchan@redhat.com> - 0.5.0-6
+- Enables build on RHEL 7
+
+* 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