diff --git a/.bpftrace.metadata b/.bpftrace.metadata
index ceead33..2b446c6 100644
--- a/.bpftrace.metadata
+++ b/.bpftrace.metadata
@@ -1 +1 @@
-a6409319efe13b553b05b8343077e2976b03a951 SOURCES/bpftrace-0.9.tar.gz
+f35927be0719e7537e10cab1f4bee28705270ff8 SOURCES/bpftrace-0.9.2.tar.gz
diff --git a/.gitignore b/.gitignore
index 6d7a989..1edb7c1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/bpftrace-0.9.tar.gz
+SOURCES/bpftrace-0.9.2.tar.gz
diff --git a/SOURCES/bpftrace-0.9-Ban-kprobes-that-cause-CPU-deadlocks.patch b/SOURCES/bpftrace-0.9-Ban-kprobes-that-cause-CPU-deadlocks.patch
deleted file mode 100644
index a3d8322..0000000
--- a/SOURCES/bpftrace-0.9-Ban-kprobes-that-cause-CPU-deadlocks.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 40cf19078e0f5aca77bb53a17ab2913d1c58417d Mon Sep 17 00:00:00 2001
-From: Javier Honduvilla Coto <javierhonduco@gmail.com>
-Date: Thu, 11 Apr 2019 18:59:23 +0100
-Subject: [PATCH] Ban kprobes that cause CPU deadlocks
-
----
- src/attached_probe.cpp      | 18 ++++++++++++++++++
- tests/runtime/banned_probes | 19 +++++++++++++++++++
- 2 files changed, 37 insertions(+)
- create mode 100644 tests/runtime/banned_probes
-
-diff --git a/src/attached_probe.cpp b/src/attached_probe.cpp
-index f83634a..073be78 100644
---- a/src/attached_probe.cpp
-+++ b/src/attached_probe.cpp
-@@ -24,6 +24,15 @@
- namespace bpftrace {
- 
- const int BPF_LOG_SIZE = 100 * 1024;
-+/*
-+ * Kernel functions that are unsafe to trace are excluded in the Kernel with
-+ * `notrace`. However, the ones below are not excluded.
-+ */
-+const std::set<std::string> banned_kretprobes = {
-+  "_raw_spin_lock", "_raw_spin_lock_irqsave", "_raw_spin_unlock_irqrestore",
-+  "queued_spin_lock_slowpath",
-+};
-+
- 
- bpf_probe_attach_type attachtype(ProbeType t)
- {
-@@ -60,6 +69,12 @@ bpf_prog_type progtype(ProbeType t)
-   }
- }
- 
-+void check_banned_kretprobes(std::string const& kprobe_name) {
-+  if (banned_kretprobes.find(kprobe_name) != banned_kretprobes.end()) {
-+    std::cerr << "error: kretprobe:" << kprobe_name << " can't be used as it might lock up your system." << std::endl;
-+    exit(1);
-+  }
-+}
- 
- AttachedProbe::AttachedProbe(Probe &probe, std::tuple<uint8_t *, uintptr_t> func)
-   : probe_(probe), func_(func)
-@@ -70,7 +85,10 @@ AttachedProbe::AttachedProbe(Probe &probe, std::tuple<uint8_t *, uintptr_t> func
-   switch (probe_.type)
-   {
-     case ProbeType::kprobe:
-+      attach_kprobe();
-+      break;
-     case ProbeType::kretprobe:
-+      check_banned_kretprobes(probe_.attach_point);
-       attach_kprobe();
-       break;
-     case ProbeType::uprobe:
-diff --git a/tests/runtime/banned_probes b/tests/runtime/banned_probes
-new file mode 100644
-index 0000000..e892bd2
---- /dev/null
-+++ b/tests/runtime/banned_probes
-@@ -0,0 +1,19 @@
-+NAME kretprobe:_raw_spin_lock is banned
-+RUN bpftrace -e 'kretprobe:_raw_spin_lock { exit(); }'
-+EXPECT error: kretprobe:_raw_spin_lock can't be used as it might lock up your system.
-+TIMEOUT 1
-+
-+NAME kretprobe:queued_spin_lock_slowpath is banned
-+RUN bpftrace -e 'kretprobe:queued_spin_lock_slowpath { exit(); }'
-+EXPECT error: kretprobe:queued_spin_lock_slowpath can't be used as it might lock up your system.
-+TIMEOUT 1
-+
-+NAME kretprobe:_raw_spin_unlock_irqrestore is banned
-+RUN bpftrace -e 'kretprobe:_raw_spin_unlock_irqrestore { exit(); }'
-+EXPECT error: kretprobe:_raw_spin_unlock_irqrestore can't be used as it might lock up your system.
-+TIMEOUT 1
-+
-+NAME kretprobe:_raw_spin_lock_irqsave is banned
-+RUN bpftrace -e 'kretprobe:_raw_spin_lock_irqsave { exit(); }'
-+EXPECT error: kretprobe:_raw_spin_lock_irqsave can't be used as it might lock up your system.
-+TIMEOUT 1
--- 
-2.20.1
-
diff --git a/SOURCES/bpftrace-0.9-RHEL-8-fixes.patch b/SOURCES/bpftrace-0.9-RHEL-8-fixes.patch
deleted file mode 100644
index b15f98a..0000000
--- a/SOURCES/bpftrace-0.9-RHEL-8-fixes.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 1dce61acfec57712f84cfdf2a8f4c69d27744b04 Mon Sep 17 00:00:00 2001
-From: Jerome Marchand <jmarchan@redhat.com>
-Date: Tue, 11 Jun 2019 16:41:59 +0200
-Subject: RHEL 8 fixes
-
-Fixes the following RHEL 8 specific issues:
- - library path in gethostlatency
-
----
- tools/gethostlatency.bt | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/tools/gethostlatency.bt b/tools/gethostlatency.bt
-index a1ac1b2..ade1005 100755
---- a/tools/gethostlatency.bt
-+++ b/tools/gethostlatency.bt
-@@ -26,17 +26,17 @@ BEGIN
- 	    "HOST");
- }
- 
--uprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo,
--uprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname,
--uprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname2
-+uprobe:/lib64/libc.so.6:getaddrinfo,
-+uprobe:/lib64/libc.so.6:gethostbyname,
-+uprobe:/lib64/libc.so.6:gethostbyname2
- {
- 	@start[tid] = nsecs;
- 	@name[tid] = arg0;
- }
- 
--uretprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo,
--uretprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname,
--uretprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname2
-+uretprobe:/lib64/libc.so.6:getaddrinfo,
-+uretprobe:/lib64/libc.so.6:gethostbyname,
-+uretprobe:/lib64/libc.so.6:gethostbyname2
- /@start[tid]/
- {
- 	$latms = (nsecs - @start[tid]) / 1000000;
--- 
-2.20.1
-
diff --git a/SOURCES/bpftrace-0.9-clang_parser-fix-clang_parser-for-LLVM-8.patch b/SOURCES/bpftrace-0.9-clang_parser-fix-clang_parser-for-LLVM-8.patch
deleted file mode 100644
index 2b71fda..0000000
--- a/SOURCES/bpftrace-0.9-clang_parser-fix-clang_parser-for-LLVM-8.patch
+++ /dev/null
@@ -1,255 +0,0 @@
-From acb0ee316d5ed776253b6d7bfccfb21e0005919b Mon Sep 17 00:00:00 2001
-From: Jerome Marchand <jmarchan@redhat.com>
-Date: Thu, 16 May 2019 14:56:50 +0200
-Subject: [PATCH] fix clang_parser for LLVM 8+
-
-LLVM changed the behavior of clang_Cursor_isAnonymous in [1]. The old
-behavior would returned false for direct-acccess anonymous structs
-within other structs, whereas LLVM 8 returns true. To circumvent this
-behavior change among LLVM versions, we keep track of all structs
-defined within a struct. We don't parse the substruct recursively (if we
-do it might be parsed multiple times, and since we don't know yet if
-this is a direct or indirect strucutre, we might parse it incorrectly),
-instead we keep the cursor saved in a map. If this substruct is later
-declared as an attribute of the supersctruct, that means we have a
-direct-accessible struct. We remove it from our map, and we parse
-recursively (parsing recursively the cursor pointing to the declaration
-will effectively parse the struct definition).
-
-After the first parse, any struct left in our map is an indirect struct.
-Since we skipped the parsing stage for those, we need to run
-`clang_visitChildren` again for each struct cursor we have saved. We
-repeat this until there's no unvisited structs in the map. Keep in mind
-that while visiting a new struct we might find more indirect structs.
-
-Also add Travis jobs to test against LLVM and clang 8 on Ubuntu.
-
-[1]: llvm/llvm-project@c05e6f4
----
- .travis.yml                    |  4 ++
- docker/Dockerfile.bionic-llvm8 | 36 ++++++++++++++
- src/bpforc.h                   |  9 ++++
- src/clang_parser.cpp           | 87 +++++++++++++++++++++++-----------
- 4 files changed, 108 insertions(+), 28 deletions(-)
- create mode 100644 docker/Dockerfile.bionic-llvm8
-
-diff --git a/.travis.yml b/.travis.yml
-index 7fbff63..b539868 100644
---- a/.travis.yml
-+++ b/.travis.yml
-@@ -20,6 +20,10 @@ sudo: required
-       env: BASE=fedora29 TYPE=Debug
-     - name: "LLVM 7 Release"
-       env: BASE=fedora29 TYPE=Release
-+    - name: "LLVM 8 Debug"
-+      env: BASE=bionic-llvm8 TYPE=Debug
-+    - name: "LLVM 8 Release"
-+      env: BASE=bionic-llvm8 TYPE=Release
-   allow_failures:
-     - name: "Static LLVM 5 Debug"
-       env: BASE=alpine TYPE=Debug STATIC_LINKING=ON TEST_ARGS="--gtest_filter=-codegen.string_equal_comparison:codegen.string_not_equal_comparison"
-diff --git a/docker/Dockerfile.bionic-llvm8 b/docker/Dockerfile.bionic-llvm8
-new file mode 100644
-index 0000000..ebf10d3
---- /dev/null
-+++ b/docker/Dockerfile.bionic-llvm8
-@@ -0,0 +1,36 @@
-+FROM ubuntu:bionic
-+
-+ENV llvmVersion=8
-+
-+RUN apt-get update && apt-get install -y curl gnupg &&\
-+    llvmRepository='\n\
-+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main\n\
-+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic main\n\
-+# 8\n\
-+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main\n\
-+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main' && \
-+    echo $llvmRepository >> /etc/apt/sources.list && \
-+    curl -L https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \
-+    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD && \
-+    echo "deb https://repo.iovisor.org/apt/bionic bionic main" | tee /etc/apt/sources.list.d/iovisor.list
-+
-+RUN apt-get update && apt-get install -y \
-+      bison \
-+      cmake \
-+      flex \
-+      g++ \
-+      git \
-+      libelf-dev \
-+      zlib1g-dev \
-+      libbcc \
-+      clang-${llvmVersion} \
-+      libclang-${llvmVersion}-dev \
-+      libclang-common-${llvmVersion}-dev \
-+      libclang1-${llvmVersion} \
-+      llvm-${llvmVersion} \
-+      llvm-${llvmVersion}-dev \
-+      llvm-${llvmVersion}-runtime \
-+      libllvm${llvmVersion}
-+
-+COPY build.sh /build.sh
-+ENTRYPOINT ["bash", "/build.sh"]
-diff --git a/src/bpforc.h b/src/bpforc.h
-index 1c134d0..8eede31 100644
---- a/src/bpforc.h
-+++ b/src/bpforc.h
-@@ -80,8 +80,13 @@ class BpfOrc
-   ExecutionSession ES;
-   std::unique_ptr<TargetMachine> TM;
-   std::shared_ptr<SymbolResolver> Resolver;
-+#if LLVM_VERSION_MAJOR >= 8
-+  LegacyRTDyldObjectLinkingLayer ObjectLayer;
-+  LegacyIRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
-+#else
-   RTDyldObjectLinkingLayer ObjectLayer;
-   IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
-+#endif
- 
- public:
-   std::map<std::string, std::tuple<uint8_t *, uintptr_t>> sections_;
-@@ -91,7 +96,11 @@ class BpfOrc
-       Resolver(createLegacyLookupResolver(ES,
-         [](const std::string &Name __attribute__((unused))) -> JITSymbol { return nullptr; },
-         [](Error Err) { cantFail(std::move(Err), "lookup failed"); })),
-+#if LLVM_VERSION_MAJOR >= 8
-+      ObjectLayer(ES, [this](VModuleKey) { return LegacyRTDyldObjectLinkingLayer::Resources{std::make_shared<MemoryManager>(sections_), Resolver}; }),
-+#else
-       ObjectLayer(ES, [this](VModuleKey) { return RTDyldObjectLinkingLayer::Resources{std::make_shared<MemoryManager>(sections_), Resolver}; }),
-+#endif
-       CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {}
- 
-   void compileModule(std::unique_ptr<Module> M) {
-diff --git a/src/clang_parser.cpp b/src/clang_parser.cpp
-index 4bb8f87..7bb8d6a 100644
---- a/src/clang_parser.cpp
-+++ b/src/clang_parser.cpp
-@@ -1,5 +1,7 @@
- #include <clang-c/Index.h>
- #include <iostream>
-+#include <unordered_map>
-+#include <unordered_set>
- #include <string.h>
- #include <sys/utsname.h>
- #include <sys/stat.h>
-@@ -13,6 +15,9 @@
- 
- namespace bpftrace {
- 
-+std::unordered_map<std::string, CXCursor> indirect_structs;
-+std::unordered_set<std::string> unvisited_indirect_structs;
-+
- static std::string get_clang_string(CXString string)
- {
-   std::string str = clang_getCString(string);
-@@ -30,8 +35,9 @@ static CXCursor get_indirect_field_parent_struct(CXCursor c)
- {
-   CXCursor parent = clang_getCursorSemanticParent(c);
- 
--  while (!clang_Cursor_isNull(parent) && clang_Cursor_isAnonymous(parent))
--     parent = clang_getCursorSemanticParent(parent);
-+  while (!clang_Cursor_isNull(parent) && indirect_structs.count(get_clang_string(clang_getTypeSpelling(clang_getCanonicalType(clang_getCursorType(parent))))) > 0) {
-+    parent = clang_getCursorSemanticParent(parent);
-+  }
- 
-   return parent;
- }
-@@ -253,44 +259,69 @@ void ClangParser::parse(ast::Program *program, BPFtrace &bpftrace)
-     std::cerr << "Input (" << input.size() << "): " << input << std::endl;
-   }
- 
--  CXCursor cursor = clang_getTranslationUnitCursor(translation_unit);
-+  indirect_structs.clear();
-+  unvisited_indirect_structs.clear();
- 
--  clang_visitChildren(
--      cursor,
--      [](CXCursor c, CXCursor parent, CXClientData client_data)
--      {
-+  CXCursor cursor = clang_getTranslationUnitCursor(translation_unit);
- 
--        if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
--            clang_getCursorKind(parent) != CXCursor_UnionDecl)
--          return CXChildVisit_Recurse;
-+  bool iterate = true;
- 
--        if (clang_getCursorKind(c) == CXCursor_FieldDecl)
-+  do {
-+    clang_visitChildren(
-+        cursor,
-+        [](CXCursor c, CXCursor parent, CXClientData client_data)
-         {
--          auto &structs = static_cast<BPFtrace*>(client_data)->structs_;
--          auto struct_name = get_parent_struct_name(c);
--          auto ident = get_clang_string(clang_getCursorSpelling(c));
--          auto offset = clang_Cursor_getOffsetOfField(c) / 8;
--          auto type = clang_getCanonicalType(clang_getCursorType(c));
-+          if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
-+              clang_getCursorKind(parent) != CXCursor_UnionDecl)
-+            return CXChildVisit_Recurse;
- 
-           auto ptype = clang_getCanonicalType(clang_getCursorType(parent));
-           auto ptypestr = get_clang_string(clang_getTypeSpelling(ptype));
-           auto ptypesize = clang_Type_getSizeOf(ptype);
- 
--          if(clang_Cursor_isAnonymous(parent))
--            offset = get_indirect_field_offset(c);
-+          if (clang_getCursorKind(c) == CXCursor_StructDecl ||
-+              clang_getCursorKind(c) == CXCursor_UnionDecl) {
-+            auto struct_name = get_clang_string(clang_getTypeSpelling(clang_getCanonicalType(clang_getCursorType(c))));
-+            indirect_structs[struct_name] = c;
-+            unvisited_indirect_structs.insert(struct_name);
- 
--          if (struct_name == "")
--            struct_name = ptypestr;
--          remove_struct_prefix(struct_name);
-+            return CXChildVisit_Continue;
-+          }
- 
--          structs[struct_name].fields[ident].offset = offset;
--          structs[struct_name].fields[ident].type = get_sized_type(type);
--          structs[struct_name].size = ptypesize;
--        }
-+          if (clang_getCursorKind(c) == CXCursor_FieldDecl)
-+          {
-+            auto &structs = static_cast<BPFtrace*>(client_data)->structs_;
-+            auto struct_name = get_parent_struct_name(c);
-+            auto ident = get_clang_string(clang_getCursorSpelling(c));
-+            auto offset = clang_Cursor_getOffsetOfField(c) / 8;
-+            auto type = clang_getCanonicalType(clang_getCursorType(c));
-+            auto typestr = get_clang_string(clang_getTypeSpelling(type));
- 
--        return CXChildVisit_Recurse;
--      },
--      &bpftrace);
-+            if (indirect_structs.count(typestr))
-+              indirect_structs.erase(typestr);
-+
-+            if(indirect_structs.count(ptypestr))
-+              offset = get_indirect_field_offset(c);
-+
-+            if (struct_name == "")
-+              struct_name = ptypestr;
-+            remove_struct_prefix(struct_name);
-+
-+            structs[struct_name].fields[ident].offset = offset;
-+            structs[struct_name].fields[ident].type = get_sized_type(type);
-+            structs[struct_name].size = ptypesize;
-+          }
-+
-+          return CXChildVisit_Recurse;
-+        },
-+        &bpftrace);
-+    if (unvisited_indirect_structs.size()) {
-+      cursor = indirect_structs[*unvisited_indirect_structs.begin()];
-+      unvisited_indirect_structs.erase(unvisited_indirect_structs.begin());
-+    } else {
-+      iterate = false;
-+    }
-+  } while (iterate);
- 
-   clang_disposeTranslationUnit(translation_unit);
-   clang_disposeIndex(index);
--- 
-2.20.1
-
diff --git a/SOURCES/bpftrace-0.9-clang_parser-pass-BPFtrace-as-arg-instead-of-StructM.patch b/SOURCES/bpftrace-0.9-clang_parser-pass-BPFtrace-as-arg-instead-of-StructM.patch
deleted file mode 100644
index 387b3d3..0000000
--- a/SOURCES/bpftrace-0.9-clang_parser-pass-BPFtrace-as-arg-instead-of-StructM.patch
+++ /dev/null
@@ -1,356 +0,0 @@
-From 5143209e8744d242431229972d9affa32ba3cc1a Mon Sep 17 00:00:00 2001
-From: Matheus Marchini <mat@mmarchini.me>
-Date: Fri, 12 Apr 2019 16:27:51 -0700
-Subject: [PATCH 1/3] [clang_parser] pass BPFtrace as arg instead of StructMap
-
----
- src/clang_parser.cpp          |  6 +--
- src/clang_parser.h            |  3 +-
- src/main.cpp                  |  2 +-
- tests/clang_parser.cpp        | 71 +++++++++++++++++++++++------------
- tests/codegen/call_kstack.cpp |  4 +-
- tests/codegen/call_ustack.cpp |  4 +-
- tests/codegen/common.h        |  2 +-
- tests/codegen/general.cpp     |  2 +-
- tests/probe.cpp               |  2 +-
- tests/semantic_analyser.cpp   |  2 +-
- 10 files changed, 61 insertions(+), 37 deletions(-)
-
-diff --git a/src/clang_parser.cpp b/src/clang_parser.cpp
-index b1db8ff..4bb8f87 100644
---- a/src/clang_parser.cpp
-+++ b/src/clang_parser.cpp
-@@ -172,7 +172,7 @@ static std::tuple<std::string, std::string> get_kernel_dirs(const struct utsname
-   return std::make_tuple(ksrc, kobj);
- }
- 
--void ClangParser::parse(ast::Program *program, StructMap &structs)
-+void ClangParser::parse(ast::Program *program, BPFtrace &bpftrace)
- {
-   auto input = program->c_definitions;
-   if (input.size() == 0)
-@@ -259,7 +259,6 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
-       cursor,
-       [](CXCursor c, CXCursor parent, CXClientData client_data)
-       {
--        auto &structs = *static_cast<StructMap*>(client_data);
- 
-         if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
-             clang_getCursorKind(parent) != CXCursor_UnionDecl)
-@@ -267,6 +266,7 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
- 
-         if (clang_getCursorKind(c) == CXCursor_FieldDecl)
-         {
-+          auto &structs = static_cast<BPFtrace*>(client_data)->structs_;
-           auto struct_name = get_parent_struct_name(c);
-           auto ident = get_clang_string(clang_getCursorSpelling(c));
-           auto offset = clang_Cursor_getOffsetOfField(c) / 8;
-@@ -290,7 +290,7 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
- 
-         return CXChildVisit_Recurse;
-       },
--      &structs);
-+      &bpftrace);
- 
-   clang_disposeTranslationUnit(translation_unit);
-   clang_disposeIndex(index);
-diff --git a/src/clang_parser.h b/src/clang_parser.h
-index d2ada5d..4289796 100644
---- a/src/clang_parser.h
-+++ b/src/clang_parser.h
-@@ -1,6 +1,7 @@
- #pragma once
- 
- #include "struct.h"
-+#include "bpftrace.h"
- 
- namespace bpftrace {
- 
-@@ -11,7 +12,7 @@ using StructMap = std::map<std::string, Struct>;
- class ClangParser
- {
- public:
--  void parse(ast::Program *program, StructMap &structs);
-+  void parse(ast::Program *program, BPFtrace &bpftrace);
- };
- 
- } // namespace bpftrace
-diff --git a/src/main.cpp b/src/main.cpp
-index ec3882d..f6659bf 100644
---- a/src/main.cpp
-+++ b/src/main.cpp
-@@ -272,7 +272,7 @@ int main(int argc, char *argv[])
-   }
- 
-   ClangParser clang;
--  clang.parse(driver.root_, bpftrace.structs_);
-+  clang.parse(driver.root_, bpftrace);
- 
-   ast::SemanticAnalyser semantics(driver.root_, bpftrace);
-   err = semantics.analyse();
-diff --git a/tests/clang_parser.cpp b/tests/clang_parser.cpp
-index f12a5e4..0c1ca31 100644
---- a/tests/clang_parser.cpp
-+++ b/tests/clang_parser.cpp
-@@ -1,25 +1,28 @@
- #include "gtest/gtest.h"
- #include "clang_parser.h"
- #include "driver.h"
-+#include "bpftrace.h"
- 
- namespace bpftrace {
- namespace test {
- namespace clang_parser {
- 
--void parse(const std::string &input, StructMap &structs)
-+void parse(const std::string &input, BPFtrace &bpftrace)
- {
-   auto extended_input = input + "kprobe:sys_read { 1 }";
-   Driver driver;
-   ASSERT_EQ(driver.parse_str(extended_input), 0);
- 
-   ClangParser clang;
--  clang.parse(driver.root_, structs);
-+  clang.parse(driver.root_, bpftrace);
- }
- 
- TEST(clang_parser, integers)
- {
--  StructMap structs;
--  parse("struct Foo { int x; int y, z; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Foo { int x; int y, z; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.size(), 1U);
-   ASSERT_EQ(structs.count("Foo"), 1U);
-@@ -45,8 +48,10 @@ TEST(clang_parser, integers)
- 
- TEST(clang_parser, c_union)
- {
--  StructMap structs;
--  parse("union Foo { char c; short s; int i; long l; }", structs);
-+  BPFtrace bpftrace;
-+  parse("union Foo { char c; short s; int i; long l; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.size(), 1U);
-   ASSERT_EQ(structs.count("Foo"), 1U);
-@@ -77,8 +82,10 @@ TEST(clang_parser, c_union)
- 
- TEST(clang_parser, integer_ptr)
- {
--  StructMap structs;
--  parse("struct Foo { int *x; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Foo { int *x; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.size(), 1U);
-   ASSERT_EQ(structs.count("Foo"), 1U);
-@@ -96,8 +103,10 @@ TEST(clang_parser, integer_ptr)
- 
- TEST(clang_parser, string_ptr)
- {
--  StructMap structs;
--  parse("struct Foo { char *str; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Foo { char *str; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.size(), 1U);
-   ASSERT_EQ(structs.count("Foo"), 1U);
-@@ -115,8 +124,10 @@ TEST(clang_parser, string_ptr)
- 
- TEST(clang_parser, string_array)
- {
--  StructMap structs;
--  parse("struct Foo { char str[32]; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Foo { char str[32]; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.size(), 1U);
-   ASSERT_EQ(structs.count("Foo"), 1U);
-@@ -132,8 +143,10 @@ TEST(clang_parser, string_array)
- 
- TEST(clang_parser, nested_struct_named)
- {
--  StructMap structs;
--  parse("struct Bar { int x; } struct Foo { struct Bar bar; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Bar { int x; } struct Foo { struct Bar bar; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.size(), 2U);
-   ASSERT_EQ(structs.count("Foo"), 1U);
-@@ -151,8 +164,10 @@ TEST(clang_parser, nested_struct_named)
- 
- TEST(clang_parser, nested_struct_ptr_named)
- {
--  StructMap structs;
--  parse("struct Bar { int x; } struct Foo { struct Bar *bar; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Bar { int x; } struct Foo { struct Bar *bar; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.size(), 2U);
-   ASSERT_EQ(structs.count("Foo"), 1U);
-@@ -172,8 +187,10 @@ TEST(clang_parser, nested_struct_ptr_named)
- 
- TEST(clang_parser, nested_struct_anon)
- {
--  StructMap structs;
--  parse("struct Foo { struct { int x; } bar; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Foo { struct { int x; } bar; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.size(), 2U);
-   ASSERT_EQ(structs.count("Foo"), 1U);
-@@ -190,8 +207,10 @@ TEST(clang_parser, nested_struct_anon)
- 
- TEST(clang_parser, nested_struct_indirect_fields)
- {
--  StructMap structs;
--  parse("struct Foo { struct { int x; int y;}; int a; struct { int z; }; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Foo { struct { int x; int y;}; int a; struct { int z; }; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs["Foo"].fields.size(), 4U);
-   EXPECT_EQ(structs["Foo"].fields["x"].offset, 0);
-@@ -206,8 +225,10 @@ TEST(clang_parser, nested_struct_indirect_fields)
- 
- TEST(clang_parser, nested_struct_anon_union_struct)
- {
--  StructMap structs;
--  parse("struct Foo { union { long long _xy; struct { int x; int y;}; }; int a; struct { int z; }; }", structs);
-+  BPFtrace bpftrace;
-+  parse("struct Foo { union { long long _xy; struct { int x; int y;}; }; int a; struct { int z; }; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs["Foo"].fields.size(), 5U);
-   EXPECT_EQ(structs["Foo"].fields["_xy"].offset, 0);
-@@ -225,8 +246,10 @@ TEST(clang_parser, nested_struct_anon_union_struct)
- TEST(clang_parser, builtin_headers)
- {
-   // size_t is definied in stddef.h
--  StructMap structs;
--  parse("#include <stddef.h>\nstruct Foo { size_t x, y, z; }", structs);
-+  BPFtrace bpftrace;
-+  parse("#include <stddef.h>\nstruct Foo { size_t x, y, z; }", bpftrace);
-+
-+  StructMap &structs = bpftrace.structs_;
- 
-   ASSERT_EQ(structs.count("Foo"), 1U);
- 
-diff --git a/tests/codegen/call_kstack.cpp b/tests/codegen/call_kstack.cpp
-index a184af2..e64d498 100644
---- a/tests/codegen/call_kstack.cpp
-+++ b/tests/codegen/call_kstack.cpp
-@@ -68,7 +68,7 @@ TEST(codegen, call_kstack_mapids)
-   ASSERT_EQ(driver.parse_str("kprobe:f { @x = kstack(5); @y = kstack(6); @z = kstack(6) }"), 0);
- 
-   ClangParser clang;
--  clang.parse(driver.root_, bpftrace.structs_);
-+  clang.parse(driver.root_, bpftrace);
- 
-   ast::SemanticAnalyser semantics(driver.root_, bpftrace);
-   ASSERT_EQ(semantics.analyse(), 0);
-@@ -96,7 +96,7 @@ TEST(codegen, call_kstack_modes_mapids)
-   ASSERT_EQ(driver.parse_str("kprobe:f { @x = kstack(perf); @y = kstack(bpftrace); @z = kstack() }"), 0);
- 
-   ClangParser clang;
--  clang.parse(driver.root_, bpftrace.structs_);
-+  clang.parse(driver.root_, bpftrace);
- 
-   ast::SemanticAnalyser semantics(driver.root_, bpftrace);
-   ASSERT_EQ(semantics.analyse(), 0);
-diff --git a/tests/codegen/call_ustack.cpp b/tests/codegen/call_ustack.cpp
-index 8e80558..1941d36 100644
---- a/tests/codegen/call_ustack.cpp
-+++ b/tests/codegen/call_ustack.cpp
-@@ -74,7 +74,7 @@ TEST(codegen, call_ustack_mapids)
-   ASSERT_EQ(driver.parse_str("kprobe:f { @x = ustack(5); @y = ustack(6); @z = ustack(6) }"), 0);
- 
-   ClangParser clang;
--  clang.parse(driver.root_, bpftrace.structs_);
-+  clang.parse(driver.root_, bpftrace);
- 
-   ast::SemanticAnalyser semantics(driver.root_, bpftrace);
-   ASSERT_EQ(semantics.analyse(), 0);
-@@ -102,7 +102,7 @@ TEST(codegen, call_ustack_modes_mapids)
-   ASSERT_EQ(driver.parse_str("kprobe:f { @x = ustack(perf); @y = ustack(bpftrace); @z = ustack() }"), 0);
- 
-   ClangParser clang;
--  clang.parse(driver.root_, bpftrace.structs_);
-+  clang.parse(driver.root_, bpftrace);
- 
-   ast::SemanticAnalyser semantics(driver.root_, bpftrace);
-   ASSERT_EQ(semantics.analyse(), 0);
-diff --git a/tests/codegen/common.h b/tests/codegen/common.h
-index 32f8bc8..bdf733a 100644
---- a/tests/codegen/common.h
-+++ b/tests/codegen/common.h
-@@ -30,7 +30,7 @@ static void test(const std::string &input, const std::string expected_output)
-   ASSERT_EQ(driver.parse_str(input), 0);
- 
-   ClangParser clang;
--  clang.parse(driver.root_, bpftrace.structs_);
-+  clang.parse(driver.root_, bpftrace);
- 
-   ast::SemanticAnalyser semantics(driver.root_, bpftrace);
-   ASSERT_EQ(semantics.analyse(), 0);
-diff --git a/tests/codegen/general.cpp b/tests/codegen/general.cpp
-index e7e7439..e67ae10 100644
---- a/tests/codegen/general.cpp
-+++ b/tests/codegen/general.cpp
-@@ -45,7 +45,7 @@ TEST(codegen, printf_offsets)
-   // TODO (mmarchini): also test printf with a string argument
-   ASSERT_EQ(driver.parse_str("struct Foo { char c; int i; } kprobe:f { $foo = (Foo*)0; printf(\"%c %u\\n\", $foo->c, $foo->i) }"), 0);
-   ClangParser clang;
--  clang.parse(driver.root_, bpftrace.structs_);
-+  clang.parse(driver.root_, bpftrace);
-   ast::SemanticAnalyser semantics(driver.root_, bpftrace);
-   ASSERT_EQ(semantics.analyse(), 0);
-   ASSERT_EQ(semantics.create_maps(true), 0);
-diff --git a/tests/probe.cpp b/tests/probe.cpp
-index e030830..cb9b765 100644
---- a/tests/probe.cpp
-+++ b/tests/probe.cpp
-@@ -28,7 +28,7 @@ void gen_bytecode(const std::string &input, std::stringstream &out)
- 	ASSERT_EQ(driver.parse_str(input), 0);
- 
- 	ClangParser clang;
--	clang.parse(driver.root_, bpftrace.structs_);
-+	clang.parse(driver.root_, bpftrace);
- 
- 	ast::SemanticAnalyser semantics(driver.root_, bpftrace);
- 	ASSERT_EQ(semantics.analyse(), 0);
-diff --git a/tests/semantic_analyser.cpp b/tests/semantic_analyser.cpp
-index 2067ed9..4e2485b 100644
---- a/tests/semantic_analyser.cpp
-+++ b/tests/semantic_analyser.cpp
-@@ -16,7 +16,7 @@ void test(BPFtrace &bpftrace, Driver &driver, const std::string &input, int expe
-   ASSERT_EQ(driver.parse_str(input), 0);
- 
-   ClangParser clang;
--  clang.parse(driver.root_, bpftrace.structs_);
-+  clang.parse(driver.root_, bpftrace);
- 
-   std::stringstream out;
-   ast::SemanticAnalyser semantics(driver.root_, bpftrace, out);
--- 
-2.20.1
-
diff --git a/SOURCES/bpftrace-0.9-fix-struct-definition-from-headers.patch b/SOURCES/bpftrace-0.9-fix-struct-definition-from-headers.patch
deleted file mode 100644
index 3845c4a..0000000
--- a/SOURCES/bpftrace-0.9-fix-struct-definition-from-headers.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 151351ea22c855e4e605b8fd2058c19dc4ae5ed6 Mon Sep 17 00:00:00 2001
-From: Matheus Marchini <mat@mmarchini.me>
-Date: Tue, 16 Apr 2019 12:06:01 -0700
-Subject: [PATCH 2/2] fix struct definition from headers
-
-Regression caused by iovisor/bpftrace@80ce138c7. With the changes on how
-we identify the parent struct, we ended up with our parent cursor in the
-header file sometimes instead of a valid cursor. This PR checks if the
-parent cursor is a struct, otherwise returns an empty string and let the
-caller handle the situation (which is similar to the previous behavior).
----
- src/clang_parser.cpp | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/clang_parser.cpp b/src/clang_parser.cpp
-index b1db8ff..b787b67 100644
---- a/src/clang_parser.cpp
-+++ b/src/clang_parser.cpp
-@@ -40,6 +40,10 @@ static std::string get_parent_struct_name(CXCursor c)
- {
-   CXCursor parent = get_indirect_field_parent_struct(c);
- 
-+  if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
-+      clang_getCursorKind(parent) != CXCursor_UnionDecl)
-+    return "";
-+
-   return get_clang_string(clang_getCursorSpelling(parent));
- }
- 
--- 
-2.20.1
-
diff --git a/SOURCES/bpftrace-0.9.2-RHEL-8-fixes.patch b/SOURCES/bpftrace-0.9.2-RHEL-8-fixes.patch
new file mode 100644
index 0000000..b15f98a
--- /dev/null
+++ b/SOURCES/bpftrace-0.9.2-RHEL-8-fixes.patch
@@ -0,0 +1,43 @@
+From 1dce61acfec57712f84cfdf2a8f4c69d27744b04 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Tue, 11 Jun 2019 16:41:59 +0200
+Subject: RHEL 8 fixes
+
+Fixes the following RHEL 8 specific issues:
+ - library path in gethostlatency
+
+---
+ tools/gethostlatency.bt | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/tools/gethostlatency.bt b/tools/gethostlatency.bt
+index a1ac1b2..ade1005 100755
+--- a/tools/gethostlatency.bt
++++ b/tools/gethostlatency.bt
+@@ -26,17 +26,17 @@ BEGIN
+ 	    "HOST");
+ }
+ 
+-uprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo,
+-uprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname,
+-uprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname2
++uprobe:/lib64/libc.so.6:getaddrinfo,
++uprobe:/lib64/libc.so.6:gethostbyname,
++uprobe:/lib64/libc.so.6:gethostbyname2
+ {
+ 	@start[tid] = nsecs;
+ 	@name[tid] = arg0;
+ }
+ 
+-uretprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo,
+-uretprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname,
+-uretprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname2
++uretprobe:/lib64/libc.so.6:getaddrinfo,
++uretprobe:/lib64/libc.so.6:gethostbyname,
++uretprobe:/lib64/libc.so.6:gethostbyname2
+ /@start[tid]/
+ {
+ 	$latms = (nsecs - @start[tid]) / 1000000;
+-- 
+2.20.1
+
diff --git a/SPECS/bpftrace.spec b/SPECS/bpftrace.spec
index b9dd088..d1aa05e 100644
--- a/SPECS/bpftrace.spec
+++ b/SPECS/bpftrace.spec
@@ -1,18 +1,14 @@
 %bcond_without llvm_static
 
 Name:           bpftrace
-Version:        0.9
-Release:        3%{?dist}
+Version:        0.9.2
+Release:        1%{?dist}
 Summary:        High-level tracing language for Linux eBPF
 License:        ASL 2.0
 
 URL:            https://github.com/iovisor/bpftrace
 Source0:        %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
-Patch0:         %{name}-%{version}-clang_parser-pass-BPFtrace-as-arg-instead-of-StructM.patch
-Patch1:         %{name}-%{version}-clang_parser-fix-clang_parser-for-LLVM-8.patch
-Patch2:         %{name}-%{version}-fix-struct-definition-from-headers.patch
-Patch3:         %{name}-%{version}-RHEL-8-fixes.patch
-Patch4:         %{name}-%{version}-Ban-kprobes-that-cause-CPU-deadlocks.patch
+Patch0:         %{name}-%{version}-RHEL-8-fixes.patch
 
 # Arches will be included as upstream support is added and dependencies are
 # satisfied in the respective arches
@@ -50,8 +46,8 @@ and predecessor tracers such as DTrace and SystemTap
 %cmake . \
         -DCMAKE_BUILD_TYPE=RelWithDebInfo \
         -DBUILD_TESTING:BOOL=OFF \
-        -DBUILD_SHARED_LIBS:BOOL=OFF \
-        -DLLVM_DIR=/usr/lib64/llvm7.0/lib/cmake/llvm/
+        -DBUILD_SHARED_LIBS:BOOL=OFF
+#        -DLLVM_DIR=/usr/lib64/llvm7.0/lib/cmake/llvm/
 %make_build
 
 
@@ -81,10 +77,13 @@ mv %{buildroot}%{_prefix}/man/* %{buildroot}%{_mandir}/
 
 
 %changelog
-* Tue Jun 18 2019 Jerome Marchand <jmarchan@redhat.com> - 0.9.3
+* Fri Nov 08 2019 Jerome Marchand <jmarchan@redhat.com> - 0.9.2-1
+- Rebase on bpftrace 0.9.2
+
+* Tue Jun 18 2019 Jerome Marchand <jmarchan@redhat.com> - 0.9-3
 - Don't allow to raw_spin_lock* kprobes that can deadlock the kernel.
 
-* Wed Jun 12 2019 Jerome Marchand <jmarchan@redhat.com> - 0.9.2
+* Wed Jun 12 2019 Jerome Marchand <jmarchan@redhat.com> - 0.9-2
 - Fixes gethostlatency
 - Fixes a struct definition issue that made several tools fail
 - Add CI gating