diff --git a/.gitignore b/.gitignore
index f9912e2..e7ffaca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/systemtap-2.8.tar.gz
+SOURCES/systemtap-3.0.tar.gz
diff --git a/.systemtap.metadata b/.systemtap.metadata
index ffb86ad..5b324b7 100644
--- a/.systemtap.metadata
+++ b/.systemtap.metadata
@@ -1 +1 @@
-95034e8243e1f9fd33b765afda06546083df1b7f SOURCES/systemtap-2.8.tar.gz
+5ef3a2d9945b0f6bae0061e33811e25e5138f5b7 SOURCES/systemtap-3.0.tar.gz
diff --git a/SOURCES/june-robust.patch b/SOURCES/june-robust.patch
deleted file mode 100644
index 8dead9f..0000000
--- a/SOURCES/june-robust.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-commit 81bde8f873216c116988a98a0804dd79009b3d40
-Author: Mark Wielaard <mjw@redhat.com>
-Date:   Mon Jun 22 16:57:59 2015 +0200
-
-    runtime/unwind.c: Also sanity check DWARF regno for DW_CFA_restore[_extended].
-    
-    When processCFI wanted to restore a register state to its initial value it
-    wasn't checking whether the register was actually interesting (or existing).
-    DWARF_REG_MAP might return a marker (9999) that we don't know or don't care
-    about this register. This was checked in all the set_*_rule functions, but
-    not in the case we reset the rule of the register. Add this check also for
-    DW_CFA_restore[_extended].
-
-diff --git a/runtime/unwind.c b/runtime/unwind.c
-index d38363b..4dbab33 100644
---- a/runtime/unwind.c
-+++ b/runtime/unwind.c
-@@ -426,7 +426,8 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
- 						    value, DWARF_REG_MAP(value));
- 					value = DWARF_REG_MAP(value);
- 				}
--				memcpy(&REG_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
-+				if (value < ARRAY_SIZE(REG_STATE.regs))
-+					memcpy(&REG_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
- 				break;
- 			case DW_CFA_undefined:
- 				value = get_uleb128(&ptr.p8, end);
-@@ -641,7 +642,8 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
- 					    value, DWARF_REG_MAP(value));
- 				value = DWARF_REG_MAP(value);
- 			}
--			memcpy(&REG_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
-+			if (value < ARRAY_SIZE(REG_STATE.regs))
-+				memcpy(&REG_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
- 			break;
- 		}
- 		dbug_unwind(1, "targetLoc=%lx state->loc=%lx\n", targetLoc, state->loc);
-
-commit db6670607f9ba837a7a7af8a0ea076595e9eca1d
-Author: David Smith <dsmith@redhat.com>
-Date:   Tue Jun 30 15:24:54 2015 -0500
-
-    Two small stat code fixes found by source analysis.
-    
-    * runtime/stat-common.c (_stp_stat_print_histogram_buf): Fixed small
-      potential overflow problem by widening values.
-    * runtime/stat.c (_stp_stat_init): Fixed missing 'va_end' call in an error
-      situation.
-
-diff --git a/runtime/stat-common.c b/runtime/stat-common.c
-index f8372ac..4491b27 100644
---- a/runtime/stat-common.c
-+++ b/runtime/stat-common.c
-@@ -261,10 +261,10 @@ static void _stp_stat_print_histogram_buf(char *buf, size_t size, Hist st,
- 				val_prefix = "<";
- 			} else if (i == st->buckets-1) {
- 				/* overflow */
--				val = st->start + (i - 2) * st->interval;
-+				val = st->start + (int64_t)(i - 2) * st->interval;
- 				val_prefix = ">";
- 			} else
--				val = st->start + (i - 1) * st->interval;
-+				val = st->start + (int64_t)(i - 1) * st->interval;
- 		} else
- 			val = _stp_bucket_to_val(i);
- 
-diff --git a/runtime/stat.c b/runtime/stat.c
-index 63ffccc..fa5939b 100644
---- a/runtime/stat.c
-+++ b/runtime/stat.c
-@@ -71,8 +71,10 @@ static Stat _stp_stat_init (int type, ...)
- 			interval = va_arg(ap, int);
- 
- 			buckets = _stp_stat_calc_buckets(stop, start, interval);
--			if (!buckets)
-+			if (!buckets) {
-+				va_end (ap);
- 				return NULL;
-+			}
- 		}
- 		va_end (ap);
- 	}
-
-commit 39c6af0c27dfd5cdd71ee60e1667d40d101ff8ac
-Author: Mark Wielaard <mjw@redhat.com>
-Date:   Tue Jun 30 21:54:28 2015 +0200
-
-    unwind.c (compute_expr): Don't fallthrough after div/mod/shr.
-    
-    When processing DW_OP_div, DW_OP_mod or DW_OP_shr compute_expr
-    would accidentially fallthrough to the next case statement causing
-    the DWARF value stack to contain wrong values.
-
-diff --git a/runtime/unwind.c b/runtime/unwind.c
-index 4dbab33..b5c8f6f 100644
---- a/runtime/unwind.c
-+++ b/runtime/unwind.c
-@@ -1036,6 +1036,7 @@ static int compute_expr(const u8 *expr, struct unwind_frame_info *frame,
- 			if (b == 0)
- 				goto divzero;
- 			PUSH (a % b);
-+			break;
- 		}
- 
- 		case DW_OP_div: {
-@@ -1044,12 +1045,14 @@ static int compute_expr(const u8 *expr, struct unwind_frame_info *frame,
- 			if (b == 0)
- 				goto divzero;
- 			PUSH (a / b);
-+			break;
- 		}
- 
- 		case DW_OP_shr: {
- 			unsigned long b = POP;
- 			unsigned long a = POP;
- 			PUSH (a >> b);
-+			break;
- 		}
- 
- 		case DW_OP_not:
-diff --git a/runtime/unwind/unwind.h b/runtime/unwind/unwind.h
-index e81e741..d72f68d 100644
---- a/runtime/unwind/unwind.h
-+++ b/runtime/unwind/unwind.h
-@@ -157,6 +157,7 @@ static unsigned long read_ptr_sect(const u8 **pLoc, const void *end,
- #else
- 		BUILD_BUG_ON(sizeof(u32) != sizeof(value));
- #endif
-+	/* fallthrough, see above. */
- 	case DW_EH_PE_absptr:
- 		if (compat_task)
- 		{
diff --git a/SOURCES/rhbz1237098.patch b/SOURCES/rhbz1237098.patch
deleted file mode 100644
index eea1698..0000000
--- a/SOURCES/rhbz1237098.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-commit 6121861509bf5862b2869c71c7d1bbf618f45d46
-Author: Josh Stone <jistone@redhat.com>
-Date:   Mon Jul 6 11:35:51 2015 -0700
-
-    PR18555: prefer linkage_name to match the symtab
-    
-    DW_AT_name is usually only the same as the symbol table for C.  C++
-    names are mangled, which may be given by DW_AT_linkage_name.  So if we
-    want to compare a DWARF subprogram to the symbol table by name, we
-    should prefer the linkage name when it's available.
-    
-    This mattered especially for ppc64le, where query_dwarf_func was trying
-    to apply the global/local symbol offset.  When we took a DWARF C++
-    function and tried to find that name in the symbol table for its offset,
-    there was no match, so the function wouldn't be resolved at all.
-    
-    Now that lookup uses the linkage name.  If there's still no match, like
-    with a stripped symbol table, then it falls through to just use DWARF's
-    entrypc as usual.
-    
-    This patch also maintains the raw "addr" and offset "entrypc" separately
-    for symbol table functions, so for instance update_symtab can still
-    compare the original address.
-
-diff --git a/tapsets.cxx b/tapsets.cxx
-index fed4166..54f9d3d 100644
---- a/tapsets.cxx
-+++ b/tapsets.cxx
-@@ -415,7 +415,7 @@ symbol_table
-   // Set to SHN_UNDEF if there is no such section.
-   GElf_Word opd_section;
-   void add_symbol(const char *name, bool weak, bool descriptor,
--                  Dwarf_Addr addr, Dwarf_Addr *high_addr);
-+                  Dwarf_Addr addr, Dwarf_Addr entrypc);
-   enum info_status get_from_elf();
-   void prepare_section_rejection(Dwfl_Module *mod);
-   bool reject_section(GElf_Word section);
-@@ -1068,19 +1068,19 @@ query_symtab_func_info (func_info & fi, dwarf_query * q)
- {
-   assert(null_die(&fi.die));
- 
--  Dwarf_Addr addr = fi.addr;
-+  Dwarf_Addr entrypc = fi.entrypc;
- 
-   // Now compensate for the dw bias because the addresses come
--  // from dwfl_module_symtab, so fi->addr is NOT a normal dw address.
-+  // from dwfl_module_symtab, so fi->entrypc is NOT a normal dw address.
-   q->dw.get_module_dwarf(false, false);
--  addr -= q->dw.module_bias;
-+  entrypc -= q->dw.module_bias;
- 
-   // If there are already probes in this module, lets not duplicate.
-   // This can come from other weak symbols/aliases or existing
--  // matches from Dwarf DIE functions.  Try to add this addr to the
-+  // matches from Dwarf DIE functions.  Try to add this entrypc to the
-   // collection, and only continue if it was new.
--  if (q->alias_dupes.insert(addr).second)
--    query_func_info(addr, fi, q);
-+  if (q->alias_dupes.insert(entrypc).second)
-+    query_func_info(entrypc, fi, q);
- }
- 
- void
-@@ -2059,7 +2059,7 @@ query_dwarf_inline_instance (Dwarf_Die * die, dwarf_query * q)
- }
- 
- static bool
--is_filtered_func_exists (func_info_map_t filtered, func_info *fi)
-+is_filtered_func_exists (func_info_map_t const& filtered, func_info *fi)
- {
-   for (unsigned i = 0; i < filtered.size(); i++)
-     {
-@@ -2135,16 +2135,22 @@ query_dwarf_func (Dwarf_Die * func, dwarf_query * q)
-           if ((em->e_machine == EM_PPC64) && ((em->e_flags & EF_PPC64_ABI) == 2)
-               && (q->dw.mod_info->sym_table))
-             {
--              set<func_info *> fis = q->dw.mod_info->sym_table->lookup_symbol(func.name);
-+              /* The linkage name is the best match for the symbol table. */
-+              const string& linkage_name = dwarf_linkage_name(&func.die)
-+                ?: dwarf_diename(&func.die) ?: func.name;
-+
-+              set<func_info *> fis = q->dw.mod_info->sym_table->lookup_symbol(linkage_name);
-               for (set<func_info*>::iterator it=fis.begin(); it!=fis.end() ; ++it)
-                 {
--                  func.entrypc = (*it)->addr;
-+                  func.entrypc = (*it)->entrypc;
-                   if (is_filtered_func_exists(q->filtered_functions, &func))
-                     continue;
-                   q->filtered_functions.push_back(func);
-                 }
-             }
--          else if (!func.entrypc && q->dw.function_entrypc (&entrypc))
-+
-+          /* If not ppc64 or not found in sym_table, try it directly. */
-+          if (!func.entrypc && q->dw.function_entrypc (&entrypc))
-             {
-               func.entrypc = entrypc;
-               q->filtered_functions.push_back (func);
-@@ -8201,7 +8207,7 @@ symbol_table::~symbol_table()
- 
- void
- symbol_table::add_symbol(const char *name, bool weak, bool descriptor,
--                         Dwarf_Addr addr, Dwarf_Addr* /*high_addr*/)
-+                         Dwarf_Addr addr, Dwarf_Addr entrypc)
- {
-   /* Does the target architecture have function descriptors?
-      Then we want to filter them out. When seeing a symbol with a name
-@@ -8224,6 +8230,7 @@ symbol_table::add_symbol(const char *name, bool weak, bool descriptor,
-     }
- 
-   func_info *fi = new func_info();
-+  fi->entrypc = entrypc;
-   fi->addr = addr;
-   fi->name = name;
-   fi->weak = weak;
-@@ -8288,7 +8295,6 @@ symbol_table::reject_section(GElf_Word section)
- enum info_status
- symbol_table::get_from_elf()
- {
--  Dwarf_Addr high_addr = 0;
-   Dwfl_Module *mod = mod_info->mod;
-   int syments = dwfl_module_getsymtab(mod);
-   assert(syments);
-@@ -8336,13 +8342,14 @@ symbol_table::get_from_elf()
-       *
-       * st_other field is currently only used with ABIv2 on ppc64
-       */
-+      Dwarf_Addr entrypc = addr;
-       if ((em->e_machine == EM_PPC64) && ((em->e_flags & EF_PPC64_ABI) == 2)
-           && (GELF_ST_TYPE(sym.st_info) == STT_FUNC) && sym.st_other)
--        addr += PPC64_LOCAL_ENTRY_OFFSET(sym.st_other);
-+        entrypc += PPC64_LOCAL_ENTRY_OFFSET(sym.st_other);
- 
-       if (name && GELF_ST_TYPE(sym.st_info) == STT_FUNC)
-         add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
--                   reject, addr, &high_addr);
-+                   reject, addr, entrypc);
-       if (name && GELF_ST_TYPE(sym.st_info) == STT_OBJECT
-                && GELF_ST_BIND(sym.st_info) == STB_GLOBAL)
-         globals[name] = addr;
-@@ -8486,12 +8493,13 @@ module_info::update_symtab(cu_function_cache_t *funcs)
-           continue;
-         }
- 
--      // XXX We may want to make additional efforts to match mangled elf names
--      // to dwarf too.  MIPS_linkage_name can help, but that's sometimes
-+      // We need to make additional efforts to match mangled elf names to dwarf
-+      // too.  DW_AT_linkage_name (or w/ MIPS) can help, but that's sometimes
-       // missing, so we may also need to try matching by address.  See also the
-       // notes about _Z in dwflpp::iterate_over_functions().
-+      const string& name = dwarf_linkage_name(&func->second) ?: func->first;
- 
--      set<func_info*> fis = sym_table->lookup_symbol(func->first);
-+      set<func_info*> fis = sym_table->lookup_symbol(name);
-       if (fis.empty())
-         continue;
- 
diff --git a/SOURCES/rhbz1242368.patch b/SOURCES/rhbz1242368.patch
new file mode 100644
index 0000000..2ec1be8
--- /dev/null
+++ b/SOURCES/rhbz1242368.patch
@@ -0,0 +1,338 @@
+commit 03b9fdf4ce26b4e39a3e755fc717fe4e5ab773dd
+Author: David Smith <dsmith@redhat.com>
+Date:   Thu Apr 28 10:20:47 2016 -0500
+
+    Fix PR19954 by avoiding "suspicious RCU usage" message.
+    
+    * runtime/transport/symbols.c (_stp_module_update_self): Properly handle
+      RCU locking when retrieving the 'kallsyms' member of the module
+      structure.
+
+diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
+index cb7964f..98b0239 100644
+--- a/runtime/transport/symbols.c
++++ b/runtime/transport/symbols.c
+@@ -249,7 +249,12 @@ static int _stp_module_update_self (void)
+ 		}
+ 		else if (!strcmp(".symtab", attr->name)) {
+ #ifdef STAPCONF_MOD_KALLSYMS
+-			struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
++			struct mod_kallsyms *kallsyms;
++
++			rcu_read_lock_sched();
++			kallsyms = rcu_dereference_sched(mod->kallsyms);
++			rcu_read_unlock_sched();
++
+ 			if (attr->address == (unsigned long) kallsyms->symtab)
+ 				_stp_module_self.sections[0].size =
+ 					kallsyms->num_symtab * sizeof(kallsyms->symtab[0]);
+commit c8db32343c9b8012fa348cf4f8f104617960f793
+Author: David Smith <dsmith@redhat.com>
+Date:   Thu Apr 28 10:59:50 2016 -0500
+
+    Improved fake utrace locking.
+    
+    * runtime/stp_utrace.c: Fixed potential locking issues by changing the
+      'task_work_added' and 'report_work_added' members of 'struct
+      utrace' to be atomic variables. In the process, I also renamed
+      'task_work_added' to 'resume_work_added'. As atomice variables, they can
+      be modified without locking the utrace struct. Also renamed the 'work'
+      member of 'struct utrace' to 'resume_work' (to match up with
+      'resume_work_added').
+
+diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c
+index a8afc0d..bb2d663 100644
+--- a/runtime/stp_utrace.c
++++ b/runtime/stp_utrace.c
+@@ -66,17 +66,23 @@ struct utrace {
+ 	unsigned int vfork_stop:1; /* need utrace_stop() before vfork wait */
+ 	unsigned int death:1;	/* in utrace_report_death() now */
+ 	unsigned int reap:1;	/* release_task() has run */
+-	unsigned int pending_attach:1; /* need splice_attaching() */
+-	unsigned int task_work_added:1; /* called task_work_add() on 'work' */
+-	unsigned int report_work_added:1; /* called task_work_add()
+-					   * on 'report_work' */
++	unsigned int pending_attach:1;	/* need splice_attaching() */
++
++	/* We need the '*_work_added' variables to be atomic so they
++	 * can be modified without locking the utrace struct. This is
++	 * typically done in atomic context where we can't grab the
++	 * lock. */
++	atomic_t resume_work_added;	/* called task_work_add() on
++					 * 'resume_work' */
++	atomic_t report_work_added;	/* called task_work_add() on
++					 * 'report_work' */
+ 
+ 	unsigned long utrace_flags;
+ 
+ 	struct hlist_node hlist;       /* task_utrace_table linkage */
+ 	struct task_struct *task;
+ 
+-	struct task_work work;
++	struct task_work resume_work;
+ 	struct task_work report_work;
+ };
+ 
+@@ -349,17 +355,20 @@ static int utrace_exit(void)
+ static void
+ stp_task_notify_resume(struct task_struct *target, struct utrace *utrace)
+ {
+-	if (! utrace->task_work_added) {
+-		int rc = stp_task_work_add(target, &utrace->work);
+-		if (rc == 0) {
+-			utrace->task_work_added = 1;
+-		}
+-		/* stp_task_work_add() returns -ESRCH if the task has
+-		 * already passed exit_task_work(). Just ignore this
+-		 * error. */
+-		else if (rc != -ESRCH) {
+-			printk(KERN_ERR "%s:%d - task_work_add() returned %d\n",
+-			       __FUNCTION__, __LINE__, rc);
++	if (atomic_add_unless(&utrace->resume_work_added, 1, 1)) {
++		int rc = stp_task_work_add(target, &utrace->resume_work);
++		if (rc != 0) {
++			atomic_set(&utrace->report_work_added, 0);
++
++			/* stp_task_work_add() returns -ESRCH if the
++			 * task has already passed
++			 * exit_task_work(). Just ignore this
++			 * error. */
++			if (rc != -ESRCH) {
++				printk(KERN_ERR
++				       "%s:%d - task_work_add() returned %d\n",
++				       __FUNCTION__, __LINE__, rc);
++			}
+ 		}
+ 	}
+ }
+@@ -394,8 +403,9 @@ static void utrace_cleanup(struct utrace *utrace)
+ 	    list_del(&engine->entry);
+ 	    kmem_cache_free(utrace_engine_cachep, engine);
+ 	}
++	stp_spin_unlock(&utrace->lock);
+ 
+-	if (utrace->task_work_added) {
++	if (atomic_add_unless(&utrace->resume_work_added, -1, 0)) {
+ #ifdef STP_TF_DEBUG
+ 		if (stp_task_work_cancel(utrace->task, &utrace_resume) == NULL)
+ 			printk(KERN_ERR "%s:%d - task_work_cancel() failed? task %p, %d, %s\n",
+@@ -406,9 +416,8 @@ static void utrace_cleanup(struct utrace *utrace)
+ #else
+ 		stp_task_work_cancel(utrace->task, &utrace_resume);
+ #endif
+-		utrace->task_work_added = 0;
+ 	}
+-	if (utrace->report_work_added) {
++	if (atomic_add_unless(&utrace->report_work_added, -1, 0)) {
+ #ifdef STP_TF_DEBUG
+ 		if (stp_task_work_cancel(utrace->task, &utrace_report_work) == NULL)
+ 			printk(KERN_ERR "%s:%d - task_work_cancel() failed? task %p, %d, %s\n",
+@@ -419,9 +428,7 @@ static void utrace_cleanup(struct utrace *utrace)
+ #else
+ 		stp_task_work_cancel(utrace->task, &utrace_report_work);
+ #endif
+-		utrace->report_work_added = 0;
+ 	}
+-	stp_spin_unlock(&utrace->lock);
+ 
+ 	/* Free the struct utrace itself. */
+ 	kmem_cache_free(utrace_cachep, utrace);
+@@ -522,8 +529,10 @@ static bool utrace_task_alloc(struct task_struct *task)
+ 	INIT_LIST_HEAD(&utrace->attaching);
+ 	utrace->resume = UTRACE_RESUME;
+ 	utrace->task = task;
+-	stp_init_task_work(&utrace->work, &utrace_resume);
++	stp_init_task_work(&utrace->resume_work, &utrace_resume);
+ 	stp_init_task_work(&utrace->report_work, &utrace_report_work);
++	atomic_set(&utrace->resume_work_added, 0);
++	atomic_set(&utrace->report_work_added, 0);
+ 
+ 	stp_spin_lock(&task_utrace_lock);
+ 	u = __task_utrace_struct(task);
+@@ -558,8 +567,8 @@ static void utrace_free(struct utrace *utrace)
+ 	stp_spin_unlock(&task_utrace_lock);
+ 
+ 	/* Free the utrace struct. */
+-	stp_spin_lock(&utrace->lock);
+ #ifdef STP_TF_DEBUG
++	stp_spin_lock(&utrace->lock);
+ 	if (unlikely(utrace->reporting)
+ 	    || unlikely(!list_empty(&utrace->attached))
+ 	    || unlikely(!list_empty(&utrace->attaching)))
+@@ -567,27 +576,31 @@ static void utrace_free(struct utrace *utrace)
+ 		       __FUNCTION__, __LINE__, utrace->reporting,
+ 		       list_empty(&utrace->attached),
+ 		       list_empty(&utrace->attaching));
++	stp_spin_unlock(&utrace->lock);
+ #endif
+ 
+-	if (utrace->task_work_added) {
+-		if (stp_task_work_cancel(utrace->task, &utrace_resume) == NULL)
+-			printk(KERN_ERR "%s:%d - task_work_cancel() failed? task %p, %d, %s\n",
++	if (atomic_add_unless(&utrace->resume_work_added, -1, 0)) {
++		if ((stp_task_work_cancel(utrace->task, &utrace_resume)
++		     == NULL)
++		    && (utrace->task->flags & ~PF_EXITING)
++		    && (utrace->task->exit_state == 0))
++			printk(KERN_ERR "%s:%d * task_work_cancel() failed? task %p, %d, %s, 0x%lx 0x%x\n",
+ 			       __FUNCTION__, __LINE__, utrace->task,
+ 			       utrace->task->tgid,
+ 			       (utrace->task->comm ? utrace->task->comm
+-				: "UNKNOWN"));
+-		utrace->task_work_added = 0;
+-	}
+-	if (utrace->report_work_added) {
+-		if (stp_task_work_cancel(utrace->task, &utrace_report_work) == NULL)
+-			printk(KERN_ERR "%s:%d - task_work_cancel() failed? task %p, %d, %s\n",
++				: "UNKNOWN"), utrace->task->state, utrace->task->exit_state);
++	}
++	if (atomic_add_unless(&utrace->report_work_added, -1, 0)) {
++		if ((stp_task_work_cancel(utrace->task, &utrace_report_work)
++		     == NULL)
++		    && (utrace->task->flags & ~PF_EXITING)
++		    && (utrace->task->exit_state == 0))
++			printk(KERN_ERR "%s:%d ** task_work_cancel() failed? task %p, %d, %s, 0x%lx, 0x%x\n",
+ 			       __FUNCTION__, __LINE__, utrace->task,
+ 			       utrace->task->tgid,
+ 			       (utrace->task->comm ? utrace->task->comm
+-				: "UNKNOWN"));
+-		utrace->report_work_added = 0;
++				: "UNKNOWN"), utrace->task->state, utrace->task->exit_state);
+ 	}
+-	stp_spin_unlock(&utrace->lock);
+ 
+ 	kmem_cache_free(utrace_cachep, utrace);
+ }
+@@ -2257,7 +2270,7 @@ static void utrace_report_death(void *cb_data __attribute__ ((unused)),
+ 	 * of detach bookkeeping.
+ 	 */
+ 	if (in_atomic() || irqs_disabled()) {
+-		if (! utrace->report_work_added) {
++		if (atomic_add_unless(&utrace->report_work_added, 1, 1)) {
+ 			int rc;
+ #ifdef STP_TF_DEBUG
+ 			printk(KERN_ERR "%s:%d - adding task_work\n",
+@@ -2265,17 +2278,17 @@ static void utrace_report_death(void *cb_data __attribute__ ((unused)),
+ #endif
+ 			rc = stp_task_work_add(task,
+ 					       &utrace->report_work);
+-			if (rc == 0) {
+-				utrace->report_work_added = 1;
+-			}
+-			/* stp_task_work_add() returns -ESRCH if the
+-			 * task has already passed
+-			 * exit_task_work(). Just ignore this
+-			 * error. */
+-			else if (rc != -ESRCH) {
+-				printk(KERN_ERR
+-				       "%s:%d - task_work_add() returned %d\n",
+-				       __FUNCTION__, __LINE__, rc);
++			if (rc != 0) {
++				atomic_set(&utrace->report_work_added, 0);
++				/* stp_task_work_add() returns -ESRCH
++				 * if the task has already passed
++				 * exit_task_work(). Just ignore this
++				 * error. */
++				if (rc != -ESRCH) {
++					printk(KERN_ERR
++					       "%s:%d - task_work_add() returned %d\n",
++					       __FUNCTION__, __LINE__, rc);
++				}
+ 			}
+ 		}
+ 	}
+@@ -2337,13 +2350,13 @@ static void utrace_resume(struct task_work *work)
+ 	 * instantaneous (where 'task_utrace_struct()' has to do a
+ 	 * hash lookup).
+ 	 */
+-	struct utrace *utrace = container_of(work, struct utrace, work);
++	struct utrace *utrace = container_of(work, struct utrace, resume_work);
+ 	struct task_struct *task = current;
+ 	INIT_REPORT(report);
+ 	struct utrace_engine *engine;
+ 
+ 	might_sleep();
+-	utrace->task_work_added = 0;
++	atomic_set(&utrace->resume_work_added, 0);
+ 
+ 	/* Make sure the task isn't exiting. */
+ 	if (task->flags & PF_EXITING) {
+@@ -2436,8 +2449,8 @@ static void utrace_report_work(struct task_work *work)
+ 	       __FUNCTION__, __LINE__, in_atomic(), irqs_disabled());
+ #endif
+ 	might_sleep();
+-	utrace->report_work_added = 0;
+ 
++	atomic_set(&utrace->report_work_added, 0);
+ 	stp_spin_lock(&utrace->lock);
+ 	BUG_ON(utrace->death);
+ 	utrace->death = 1;
+commit 0859b50e3ac4782e53c4c10b82c6e24174378bd4
+Author: Mateusz Guzik <mguzik@redhat.com>
+Date:   Mon May 2 12:28:55 2016 -0500
+
+    Plug preempt leak in _stp_runtime_entryfn_put/get_context.
+    
+    If _stp_runtime_entryfn_get_context returns a context, preemption
+    counter is always incremented. On the other hand
+    _stp_runtime_entryfn_put_context only decrements the counter if the
+    passed context matches the one currently set on the cpu.
+    
+    The context can be set to NULL by _stp_runtime_contexts_free, making the
+    comparison false and in effect leading to a leak, e.g.:
+    timer: _stp_ctl_work_callback+0x0/0x1e0[stap_af8544c7eb51251ef8c
+     377abff659b05_25070] preempt leak: 00000101 -> 00000102
+
+diff --git a/runtime/linux/runtime_context.h b/runtime/linux/runtime_context.h
+index c9ffe18..9d325da 100644
+--- a/runtime/linux/runtime_context.h
++++ b/runtime/linux/runtime_context.h
+@@ -80,11 +80,12 @@ static struct context * _stp_runtime_entryfn_get_context(void)
+ 
+ static inline void _stp_runtime_entryfn_put_context(struct context *c)
+ {
+-	if (c && c == _stp_runtime_get_context()) {
+-		atomic_dec(&c->busy);
++	if (c) {
++		if (c == _stp_runtime_get_context())
++			atomic_dec(&c->busy);
++		/* else, warn about bad state? */
+ 		preempt_enable_no_resched();
+ 	}
+-	/* else, warn about bad state? */
+ 	return;
+ }
+ 
+commit 0beafcec9a2971d466419d430d13fdb2c4f50d94
+Author: David Smith <dsmith@redhat.com>
+Date:   Tue May 3 13:23:58 2016 -0500
+
+    Fix PR20040 by keeping the task_exe_file function from sleeping.
+    
+    * tapset/linux/task.stp: No longer call get_task_mm()/mmput(), so that the
+      function won't sleep and cause kernel bugs.
+
+diff --git a/tapset/linux/task.stp b/tapset/linux/task.stp
+index 9b204f5..774cf58 100644
+--- a/tapset/linux/task.stp
++++ b/tapset/linux/task.stp
+@@ -795,13 +795,14 @@ function task_exe_file:long(task:long)
+ 		STAP_ERROR ("invalid task struct pointer");
+ 	}
+ 
++	// We'd like to call get_task_mm()/mmput() here, but they can
++	// sleep. So, let's hope incrementing the task's usage (by
++	// calling get_task_struct) is enough to keep the mm around.
+ 	get_task_struct(task);
+-	mm = get_task_mm(task);
+-	put_task_struct(task);
+-	if (mm) {
++	mm = task->mm;
++	if (mm)
+ 		exe_file = stap_find_exe_file(mm);
+-		mmput(mm);
+-	}
++	put_task_struct(task);
+ 
+ 	if (exe_file) {
+ 		STAP_RETURN((unsigned long)exe_file);
diff --git a/SOURCES/rhbz1242992.patch b/SOURCES/rhbz1242992.patch
deleted file mode 100644
index d01e26b..0000000
--- a/SOURCES/rhbz1242992.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-commit 00ddbc6920530ed042260719e4faf690c2d38541
-Author: Lukas Berk <lberk@redhat.com>
-Date:   Wed Jul 15 10:46:27 2015 -0400
-
-    Add ppc64le to java/Makefile.*
-    
-    java/Makefile.am - add JAVA_ARCH override for ppc64le
-    java/Makefile.in - add JAVA_ARCH override for ppc64le
-
-diff --git a/java/Makefile.am b/java/Makefile.am
-index bd1efe8..2d5bba0 100644
---- a/java/Makefile.am
-+++ b/java/Makefile.am
-@@ -10,6 +10,7 @@ override JAVA_ARCH:=$(JAVA_ARCH:i%86=i386)
- override JAVA_ARCH:=$(JAVA_ARCH:sparcv9=sparc)
- override JAVA_ARCH:=$(JAVA_ARCH:sparc64=sparcv9)
- override JAVA_ARCH:=$(JAVA_ARCH:arm%=arm)
-+override JAVA_ARCH:=$(JAVA_ARCH:powerpc64le%=ppc64le)
- override JAVA_ARCH:=$(JAVA_ARCH:powerpc64%=ppc64)
- 
- # XXX: perhaps autoconfigure the following?
-diff --git a/java/Makefile.in b/java/Makefile.in
-index 5e9f5a7..f98c79b 100644
---- a/java/Makefile.in
-+++ b/java/Makefile.in
-@@ -725,6 +725,7 @@ override JAVA_ARCH:=$(JAVA_ARCH:i%86=i386)
- override JAVA_ARCH:=$(JAVA_ARCH:sparcv9=sparc)
- override JAVA_ARCH:=$(JAVA_ARCH:sparc64=sparcv9)
- override JAVA_ARCH:=$(JAVA_ARCH:arm%=arm)
-+override JAVA_ARCH:=$(JAVA_ARCH:powerpc64le%=ppc64le)
- override JAVA_ARCH:=$(JAVA_ARCH:powerpc64%=ppc64)
- @HAVE_JAVA_TRUE@$(HELPERSDT).class: $(srcdir)/$(HELPERSDT).java
- @HAVE_JAVA_TRUE@	$(JAVAC) -d . $(srcdir)/$(HELPERSDT).java
-
-commit 5e5ec35cf1470bd52aca1bb73e76d205dcce01fc
-Author: Lukas Berk <lberk@redhat.com>
-Date:   Wed Jul 15 11:22:17 2015 -0400
-
-    systemtap.spec changes for ppc64{be,le} java helper library symlinking
-    
-    systemtap.spec - remove special clauses ppc64{be,le} linking
-
-diff --git a/systemtap.spec b/systemtap.spec
-index 39f2130..23d1173 100644
---- a/systemtap.spec
-+++ b/systemtap.spec
-@@ -775,12 +775,8 @@ exit 0
- 
- %triggerin runtime-java -- java-1.7.0-openjdk, java-1.6.0-openjdk
- for f in %{_libexecdir}/systemtap/libHelperSDT_*.so; do
--    %ifarch %{ix86} ppc64 ppc64le
--        %ifarch ppc64 ppc64le
--            arch=ppc64
--	%else
--	    arch=i386
--	%endif
-+    %ifarch %{ix86}
-+	arch=i386
-     %else
-         arch=`basename $f | cut -f2 -d_ | cut -f1 -d.`
-     %endif
-@@ -794,12 +790,8 @@ done
- 
- %triggerun runtime-java -- java-1.7.0-openjdk, java-1.6.0-openjdk
- for f in %{_libexecdir}/systemtap/libHelperSDT_*.so; do
--    %ifarch %{ix86} ppc64 ppc64le
--        %ifarch ppc64 ppc64le
--            arch=ppc64
--	%else
--	    arch=i386
--	%endif
-+    %ifarch %{ix86}
-+	arch=i386
-     %else
-         arch=`basename $f | cut -f2 -d_ | cut -f1 -d.`
-     %endif
-@@ -812,12 +804,8 @@ done
- %triggerpostun runtime-java -- java-1.7.0-openjdk, java-1.6.0-openjdk
- # Restore links for any JDKs remaining after a package removal:
- for f in %{_libexecdir}/systemtap/libHelperSDT_*.so; do
--    %ifarch %{ix86} ppc64 ppc64le
--        %ifarch ppc64 ppc64le
--            arch=ppc64
--	%else
--	    arch=i386
--	%endif
-+    %ifarch %{ix86}
-+	arch=i386
-     %else
-         arch=`basename $f | cut -f2 -d_ | cut -f1 -d.`
-     %endif
diff --git a/SOURCES/rhbz1248159.patch b/SOURCES/rhbz1248159.patch
deleted file mode 100644
index 57a3b0e..0000000
--- a/SOURCES/rhbz1248159.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-commit 7cfb10eca050964b22bc8f25dd4682b409434078
-Author: Martin Cermak <mcermak@redhat.com>
-Date:   Fri Jul 31 17:40:18 2015 +0200
-
-    Fix PR18711 by updating the netfilter code for new rhel-7.2 kernels.
-    
-    * buildrun.cxx (compile_pass): Add new netfilter autoconf test.
-    * runtime/linux/autoconf-netfilter-313b.c: New autoconf test.
-    * tapset-netfilter.cxx: (emit_module_decls): Add support for new
-      netfilter code backported to kernel-3.10.0-284.el7.
-
-diff --git a/buildrun.cxx b/buildrun.cxx
-index e4b2697..d7a431d 100644
---- a/buildrun.cxx
-+++ b/buildrun.cxx
-@@ -385,6 +385,7 @@ compile_pass (systemtap_session& s)
-   output_autoconf(s, o, "autoconf-fs_supers-hlist.c", "STAPCONF_FS_SUPERS_HLIST", NULL);
-   output_autoconf(s, o, "autoconf-compat_sigaction.c", "STAPCONF_COMPAT_SIGACTION", NULL);
-   output_autoconf(s, o, "autoconf-netfilter.c", "STAPCONF_NETFILTER_V313", NULL);
-+  output_autoconf(s, o, "autoconf-netfilter-313b.c", "STAPCONF_NETFILTER_V313B", NULL);
-   output_autoconf(s, o, "autoconf-netfilter-4_1.c", "STAPCONF_NETFILTER_V41", NULL);
-   output_autoconf(s, o, "autoconf-smpcall-5args.c", "STAPCONF_SMPCALL_5ARGS", NULL);
-   output_autoconf(s, o, "autoconf-smpcall-4args.c", "STAPCONF_SMPCALL_4ARGS", NULL);
-diff --git a/runtime/linux/autoconf-netfilter-313b.c b/runtime/linux/autoconf-netfilter-313b.c
-new file mode 100644
-index 0000000..3b18830
---- /dev/null
-+++ b/runtime/linux/autoconf-netfilter-313b.c
-@@ -0,0 +1,22 @@
-+#include <linux/netfilter.h>
-+
-+// Similarly to autoconf-netfilter-4_1.c, this autoconf test covers
-+// backport of kernel patch 238e54c9cb9385a1ba99e92801f3615a2fb398b6
-+// to kernel-3.10.0-284.el7 per rhbz1230935#c4 as patch no 119478.
-+// This fixes PR18711.
-+
-+unsigned int
-+new_style_hook(const struct nf_hook_ops *ops,
-+		 struct sk_buff *skb,
-+		 const struct net_device *nf_in,
-+		 const struct net_device *nf_out,
-+		 const struct nf_hook_state *state)
-+{
-+  (void) ops; (void) skb; (void) nf_in; (void) nf_out; (void) state;
-+  return 0;
-+}
-+
-+struct nf_hook_ops netfilter_ops = {
-+  .hook = new_style_hook
-+};
-+
-diff --git a/tapset-netfilter.cxx b/tapset-netfilter.cxx
-index 12df8d7..a820b8d 100644
---- a/tapset-netfilter.cxx
-+++ b/tapset-netfilter.cxx
-@@ -277,6 +277,11 @@ netfilter_derived_probe_group::emit_module_decls (systemtap_session& s)
-       s.op->newline() << "(const struct nf_hook_ops *nf_ops, struct sk_buff *nf_skb, const struct net_device *nf_in, const struct net_device *nf_out, int (*nf_okfn)(struct sk_buff *))";
-       s.op->newline() << "{";
- 
-+      s.op->newline() << "#elif defined(STAPCONF_NETFILTER_V313B)";
-+
-+      s.op->newline() << "(const struct nf_hook_ops *nf_ops, struct sk_buff *nf_skb, const struct net_device *nf_in, const struct net_device *nf_out, const struct nf_hook_state *nf_state)";
-+      s.op->newline() << "{";
-+
-       s.op->newline() << "#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)";
- 
-       s.op->newline() << "(unsigned int nf_hooknum, struct sk_buff *nf_skb, const struct net_device *nf_in, const struct net_device *nf_out, int (*nf_okfn)(struct sk_buff *))";
-@@ -291,7 +296,7 @@ netfilter_derived_probe_group::emit_module_decls (systemtap_session& s)
-       s.op->newline(-1) << "#endif";
-       s.op->newline(1) << "const struct stap_probe * const stp = & stap_probes[" << np->session_index << "];";
-       s.op->newline() << "int nf_verdict = NF_ACCEPT;"; // default NF_ACCEPT, to be used by $verdict context var
--      s.op->newline() << "#if defined(STAPCONF_NETFILTER_V313) || defined(STAPCONF_NETFILTER_V41)";
-+      s.op->newline() << "#if defined(STAPCONF_NETFILTER_V313) || defined(STAPCONF_NETFILTER_V313B) || defined(STAPCONF_NETFILTER_V41)";
-       s.op->newline() << "unsigned int nf_hooknum = nf_ops->hooknum;";
-       s.op->newline() << "#endif";
-       s.op->newline() << "#ifdef STAPCONF_NETFILTER_V41";
diff --git a/SOURCES/rhbz1252436.patch b/SOURCES/rhbz1252436.patch
deleted file mode 100644
index 4c6a4bb..0000000
--- a/SOURCES/rhbz1252436.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-commit 86f726b7785a035a2d6bc9ec2642c46621587d23
-Author: David Smith <dsmith@redhat.com>
-Date:   Tue Jul 7 14:01:27 2015 -0500
-
-    Fixed PR18634 by getting timer probes to compile on rawhide.
-    
-    * runtime/linux/timer.c (_stp_hrtimer_init): If STAPCONF_HRTIMER_GET_RES
-      isn't defined, meaning hrtimer_get_res() doesn't exist, just use the
-      'hrtimer_resolution' variable.
-    * buildrun.cxx (compile_pass): Add an export test for hrtimer_get_res().
-    * translate.cxx (emit_common_header): Remove generated inclusion of
-      linux/hrtimer.h.
-    * runtime/linux/timer.h: Add inclusion of linux/hrtimer.h.
-
-diff --git a/buildrun.cxx b/buildrun.cxx
-index 37b989f..e4b2697 100644
---- a/buildrun.cxx
-+++ b/buildrun.cxx
-@@ -310,6 +310,7 @@ compile_pass (systemtap_session& s)
-   o << "$(STAPCONF_HEADER):" << endl;
-   o << "\t@echo -n > $@" << endl;
-   output_autoconf(s, o, "autoconf-hrtimer-rel.c", "STAPCONF_HRTIMER_REL", NULL);
-+  output_exportconf(s, o, "hrtimer_get_res", "STAPCONF_HRTIMER_GET_RES");
-   output_autoconf(s, o, "autoconf-generated-compile.c", "STAPCONF_GENERATED_COMPILE", NULL);
-   output_autoconf(s, o, "autoconf-hrtimer-getset-expires.c", "STAPCONF_HRTIMER_GETSET_EXPIRES", NULL);
-   output_autoconf(s, o, "autoconf-inode-private.c", "STAPCONF_INODE_PRIVATE", NULL);
-diff --git a/runtime/linux/timer.c b/runtime/linux/timer.c
-index 03d8f3f..f24a5ee 100644
---- a/runtime/linux/timer.c
-+++ b/runtime/linux/timer.c
-@@ -15,9 +15,13 @@
- 
- static void _stp_hrtimer_init(void)
- {
-+#if defined(STAPCONF_HRTIMER_GET_RES)
- 	struct timespec res;
- 	hrtimer_get_res (CLOCK_MONOTONIC, &res);
- 	stap_hrtimer_resolution = timespec_to_ns(&res);
-+#else
-+	stap_hrtimer_resolution = hrtimer_resolution;
-+#endif
- }
- 
- 
-diff --git a/runtime/linux/timer.h b/runtime/linux/timer.h
-index e9a5271..e7e0bb6 100644
---- a/runtime/linux/timer.h
-+++ b/runtime/linux/timer.h
-@@ -15,6 +15,7 @@
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
- #error "hrtimers not implemented"
- #else /* kernel version >= 2.6.17 */
-+#include <linux/hrtimer.h>
- 
- static unsigned long stap_hrtimer_resolution = 0;
- 
-diff --git a/translate.cxx b/translate.cxx
-index 390a73e..6e335b2 100644
---- a/translate.cxx
-+++ b/translate.cxx
-@@ -1177,7 +1177,6 @@ c_unparser::emit_common_header ()
-       o->newline(-1)  << "}";
- 
-       o->newline( 0)  << "#ifdef STP_ON_THE_FLY_TIMER_ENABLE";
--      o->newline( 0)  << "#include <linux/hrtimer.h>";
-       o->newline( 0)  << "#include \"timer.h\"";
-       o->newline( 0)  << "static struct hrtimer module_refresh_timer;";
- 
diff --git a/SOURCES/rhbz1254856.patch b/SOURCES/rhbz1254856.patch
deleted file mode 100644
index 2e38e1f..0000000
--- a/SOURCES/rhbz1254856.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-commit 3fc11ed07bad37dfefc866e24d92682d7ef1d819
-Author: David Smith <dsmith@redhat.com>
-Date:   Thu Aug 20 11:27:53 2015 -0500
-
-    Fix PR18856 by making nfsd.close optional.
-    
-    * tapset/linux/nfsd.stp: Make nfsd.close optional in nfsd.entries (and add
-      it optionally to nfsd.return), since the underlying probe point no
-      longer exists in kernels 4.2+. Also add nfsd.proc.commit.return to
-      nfsd.proc.return (to match nfsd.proc).
-    * testsuite/buildok/nfsd-detailed.stp: Make nfsd.close tests optional.
-
-diff --git a/tapset/linux/nfsd.stp b/tapset/linux/nfsd.stp
-index 7aebb9c..71956a1 100644
---- a/tapset/linux/nfsd.stp
-+++ b/tapset/linux/nfsd.stp
-@@ -211,6 +211,7 @@ probe nfsd.proc.entries = nfsd.proc.lookup,
- probe nfsd.proc.return = nfsd.proc.lookup.return,
-                          nfsd.proc.read.return,
-                          nfsd.proc.write.return,
-+                         nfsd.proc.commit.return,
-                          nfsd.proc.remove.return,
-                          nfsd.proc.rename.return,
-                          nfsd.proc.create.return
-@@ -1064,7 +1065,7 @@ probe nfsd.entries = nfsd.open,
-                      nfsd.createv3,
-                      nfsd.unlink,
-                      nfsd.rename,
--                     nfsd.close
-+                     nfsd.close ?
- {}
- 
- probe nfsd.return = nfsd.open.return,
-@@ -1075,7 +1076,8 @@ probe nfsd.return = nfsd.open.return,
-                     nfsd.create.return,
-                     nfsd.createv3.return,
-                     nfsd.unlink.return,
--                    nfsd.rename.return
-+                    nfsd.rename.return,
-+		    nfsd.close.return ?
- {}
- 
- /**
-@@ -1113,6 +1115,8 @@ probe nfsd.open.return = kernel.function("nfsd_open").return !,
-  * probe nfsd.close - NFS server closing a file for client
-  *
-  * @filename: file name
-+ *
-+ * This probe point does not exist in kernels starting with 4.2.
-  */
- probe nfsd.close = __nfsd.call_close ?, __nfsd.inlined_close ?
- {
-diff --git a/testsuite/buildok/nfsd-detailed.stp b/testsuite/buildok/nfsd-detailed.stp
-index 627f3a2..f862079 100755
---- a/testsuite/buildok/nfsd-detailed.stp
-+++ b/testsuite/buildok/nfsd-detailed.stp
-@@ -229,12 +229,12 @@ probe nfsd.open.return
- # nfsd.close tests
- #
- 
--probe nfsd.close
-+probe nfsd.close ?
- {
- 	printf("%s(%s)\n", name, argstr)
- 	printf("%s\n", client_ip)
- }
--probe nfsd.close.return
-+probe nfsd.close.return ?
- {
- 	printf("%s(%s)\n", name, retstr)
- }
diff --git a/SOURCES/rhbz1257399.patch b/SOURCES/rhbz1257399.patch
deleted file mode 100644
index 7d8d815..0000000
--- a/SOURCES/rhbz1257399.patch
+++ /dev/null
@@ -1,530 +0,0 @@
-commit 0caa975190e4d2b19e7b65a0b23a7700522aa5d7
-Author: Frank Ch. Eigler <fche@redhat.com>
-Date:   Mon Aug 31 11:17:33 2015 -0400
-
-    PR18889 part: improve module-notification related debug tracing
-    
-    -DDEBUG_KPROBES -DDEBUG_SYMBOLS -DDEBUG_STP_ON_THE_FLY recommended.
-
-diff --git a/runtime/linux/kprobes.c b/runtime/linux/kprobes.c
-index 47eb29a..54c224e 100644
---- a/runtime/linux/kprobes.c
-+++ b/runtime/linux/kprobes.c
-@@ -567,6 +567,8 @@ stapkp_refresh(const char *modname,
- {
-    size_t i;
- 
-+   dbug_stapkp("refresh %lu probes with module %s\n", nprobes, modname ?: "?");
-+
-    for (i = 0; i < nprobes; i++) {
- 
-       struct stap_dwarf_probe *sdp = &probes[i];
-diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
-index fe576c1..9ea2b5b 100644
---- a/runtime/transport/symbols.c
-+++ b/runtime/transport/symbols.c
-@@ -1,7 +1,7 @@
--/* -*- linux-c -*- 
-+/* -*- linux-c -*-
-  * symbols.c - stp symbol and module functions
-  *
-- * Copyright (C) Red Hat Inc, 2006-2012
-+ * Copyright (C) Red Hat Inc, 2006-2015
-  *
-  * This file is part of systemtap, and is free software.  You can
-  * redistribute it and/or modify it under the terms of the GNU General
-@@ -121,10 +121,26 @@ static unsigned _stp_module_nsections (struct module_sect_attrs *attrs)
- static int _stp_module_notifier (struct notifier_block * nb,
-                                  unsigned long val, void *data)
- {
-+        struct module *mod = data;
-+        struct module_sect_attrs *attrs;
-+        unsigned i, nsections;
-+
-+        (void) attrs;
-+        (void) i;
-+        (void) nsections;
-+
-+        if (!mod) { // so as to avoid null pointer checks later
-+                WARN_ON (!mod);
-+                return NOTIFY_DONE;
-+        }
-+
-+        dbug_sym(1, "module notify %lu %s attrs %p\n",
-+                 val, mod->name, mod->sect_attrs);
-+
-         /* Prior to 2.6.11, struct module contained a module_sections
-            attribute vector rather than module_sect_attrs.  Prior to
-            2.6.19, module_sect_attrs lacked a number-of-sections
--           field.  Past 3.8, MODULE_STATE_COMING is sent too early to 
-+           field.  Past 3.8, MODULE_STATE_COMING is sent too early to
-            let us probe module init functions.
- 
-            Without CONFIG_KALLSYMS, we don't get any of the
-@@ -132,11 +148,6 @@ static int _stp_module_notifier (struct notifier_block * nb,
-            that directly? */
- 
- #if defined(CONFIG_KALLSYMS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
--        struct module *mod = data;
--        struct module_sect_attrs *attrs;
--        unsigned i, nsections;
--        WARN_ON (!mod);
--
-         if (val == MODULE_STATE_COMING ||
-             val == MODULE_STATE_LIVE) {
-                 /* A module is arriving or has arrived.  Register all
-@@ -145,6 +156,7 @@ static int _stp_module_notifier (struct notifier_block * nb,
-                    did the fishie go? */
- 
-                 attrs = mod->sect_attrs;
-+                dbug_sym(1, "module_sect_attrs: %p\n", attrs);
-                 if (attrs == NULL) // until add_sect_attrs(), may be zero
-                         return NOTIFY_DONE; // remain ignorant
- 
-@@ -153,7 +165,7 @@ static int _stp_module_notifier (struct notifier_block * nb,
-                         int init_p = (strstr(attrs->attrs[i].name, "init.") != NULL);
-                         int init_gone_p = (val == MODULE_STATE_LIVE); // likely already unloaded
- 
--                        _stp_kmodule_update_address(mod->name, 
-+                        _stp_kmodule_update_address(mod->name,
-                                                     attrs->attrs[i].name,
-                                                     ((init_p && init_gone_p) ? 0 : attrs->attrs[i].address));
-                 }
-@@ -161,7 +173,7 @@ static int _stp_module_notifier (struct notifier_block * nb,
-                 /* Verify build-id. */
-                 if (_stp_kmodule_check (mod->name))
-                    _stp_kmodule_update_address(mod->name, NULL, 0); /* Pretend it was never here. */
--        }        
-+        }
-         else if (val == MODULE_STATE_GOING) {
-                 /* Unregister all sections. */
-                 _stp_kmodule_update_address(mod->name, NULL, 0);
-
-commit 2278079efc01124dd509241f6c6eadbd6e19cb2a
-Author: Frank Ch. Eigler <fche@redhat.com>
-Date:   Mon Aug 31 17:46:43 2015 -0400
-
-    PR18889 part: module-init notification via module_{load,free} tracepoints
-    
-    Investigating RHBZ1257399 et al., we found that module_notifier is
-    being called too early after kernel commit #4982223e51.  This
-    precludes normal module section-address computation and thus kprobe
-    emplacement.  This patch adds hooking into the module_{load,free}
-    tracepoints in parallel, because on some kernels (RHEL7.1.Z+) they
-    occur at just the right time.
-    
-    On the downside, on recent LKML kernels, attaching to those
-    tracepoints requires EXPORT_TRACEPOINT_SYMBOL_GPL's, so until that is
-    done (or another workaround made), LKML kernels will still miss out on
-    module-init probing.
-
-diff --git a/buildrun.cxx b/buildrun.cxx
-index d7a431d..6d66b5a 100644
---- a/buildrun.cxx
-+++ b/buildrun.cxx
-@@ -1,5 +1,5 @@
- // build/run probes
--// Copyright (C) 2005-2014 Red Hat Inc.
-+// Copyright (C) 2005-2015 Red Hat Inc.
- //
- // This file is part of systemtap, and is free software.  You can
- // redistribute it and/or modify it under the terms of the GNU General
-@@ -377,8 +377,10 @@ compile_pass (systemtap_session& s)
-   output_exportconf(s, o, "proc_create_data", "STAPCONF_PROC_CREATE_DATA");
-   output_exportconf(s, o, "PDE_DATA", "STAPCONF_PDE_DATA");
-   output_autoconf(s, o, "autoconf-module-sect-attrs.c", "STAPCONF_MODULE_SECT_ATTRS", NULL);
--
-   output_autoconf(s, o, "autoconf-utrace-via-tracepoints.c", "STAPCONF_UTRACE_VIA_TRACEPOINTS", NULL);
-+  output_autoconf(s, o, "autoconf-module-tracepoints.c", "STAPCONF_MODULE_TRACEPOINT", NULL);
-+  output_exportconf(s, o, "__tracepoint_module_load", "STAPCONF_MODULE_TRACEPOINT_EXPORT_LOAD");
-+  output_exportconf(s, o, "__tracepoint_module_free", "STAPCONF_MODULE_TRACEPOINT_EXPORT_FREE");
-   output_autoconf(s, o, "autoconf-task_work-struct.c", "STAPCONF_TASK_WORK_STRUCT", NULL);
-   output_autoconf(s, o, "autoconf-vm-area-pte.c", "STAPCONF_VM_AREA_PTE", NULL);
-   output_autoconf(s, o, "autoconf-relay-umode_t.c", "STAPCONF_RELAY_UMODE_T", NULL);
-diff --git a/runtime/linux/autoconf-module-tracepoints.c b/runtime/linux/autoconf-module-tracepoints.c
-new file mode 100644
-index 0000000..77b938e
---- /dev/null
-+++ b/runtime/linux/autoconf-module-tracepoints.c
-@@ -0,0 +1,31 @@
-+#include <linux/module.h>
-+#include <trace/events/module.h>
-+
-+// NB: in kernels which do have the requisite pieces, just unconfigured, then
-+// everything below will compile just fine, only returning ENOSYS at runtime.
-+// To get the compile-time error that autoconf needs, check it directly:
-+#ifndef CONFIG_TRACEPOINTS
-+#error "CONFIG_TRACEPOINTS is not enabled"
-+#endif
-+
-+// presuming void *data-parametrized tracepoint callback api
-+
-+void __module_load(void *cb_data, struct module* mod)
-+{
-+        (void) cb_data;
-+        (void) mod;
-+	return;
-+}
-+
-+void __module_free(void *cb_data, struct module* mod)
-+{
-+        (void) cb_data;
-+        (void) mod;
-+	return;
-+}
-+
-+void __autoconf_func(void)
-+{
-+	(void) register_trace_module_load(__module_load, NULL);
-+        (void) register_trace_module_free(__module_free, NULL);
-+}
-diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
-index 9ea2b5b..4266e5d 100644
---- a/runtime/transport/symbols.c
-+++ b/runtime/transport/symbols.c
-@@ -125,6 +125,7 @@ static int _stp_module_notifier (struct notifier_block * nb,
-         struct module_sect_attrs *attrs;
-         unsigned i, nsections;
- 
-+        (void) nb;
-         (void) attrs;
-         (void) i;
-         (void) nsections;
-@@ -191,6 +192,21 @@ static int _stp_module_notifier (struct notifier_block * nb,
-         return NOTIFY_DONE;
- }
- 
-+
-+#ifdef STAPCONF_MODULE_TRACEPOINT
-+/* We just delegate to the canonical notifier function */
-+static void _stp_module_load_tp(void *data, struct module* mod)
-+{
-+        (void) _stp_module_notifier (NULL, MODULE_STATE_COMING, mod);
-+        
-+}
-+static void _stp_module_free_tp(void *data, struct module* mod)
-+{
-+        (void) _stp_module_notifier (NULL, MODULE_STATE_GOING, mod);
-+}
-+#endif
-+
-+
- static int _stp_module_update_self (void)
- {
- 	/* Only bother if we need unwinding and have module_sect_attrs.  */
-diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
-index 54e9b41..e069a3d 100644
---- a/runtime/transport/transport.c
-+++ b/runtime/transport/transport.c
-@@ -21,6 +21,23 @@
- #include <linux/delay.h>
- #include <linux/mutex.h>
- #include "../uidgid_compatibility.h"
-+#ifdef STAPCONF_MODULE_TRACEPOINT
-+#include <trace/events/module.h>
-+#endif
-+
-+/* PR18889: After 3.17, commit #de7b2973903c6, tracepoints are
-+   attached by symbol-address rather than by name string.  That means
-+   they must be EXPORT_TRACEPOINT_SYMBOL_GPL'd for a tracepoint
-+   [un]register operation.  On RHEL7 kernels with out that commit
-+   backported, we can do a tracepoint attach even without the exports.  */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
-+#if defined(STAPCONF_MODULE_TRACEPOINT) && defined(STAPCONF_MODULE_TRACEPOINT_EXPORT_LOAD) && defined(STAPCONF_MODULE_TRACEPOINT_EXPORT_FREE)
-+#define STAP_USE_MODULE_TRACEPOINTS
-+#endif
-+#elif defined(STAPCONF_MODULE_TRACEPOINT)
-+#define STAP_USE_MODULE_TRACEPOINTS
-+#endif
-+
- 
- static int _stp_exit_flag = 0;
- 
-@@ -83,6 +100,11 @@ static void systemtap_module_exit(void);
- static int systemtap_module_init(void);
- 
- static int _stp_module_notifier_active = 0;
-+#ifdef STAPCONF_MODULE_TRACEPOINT
-+/* callbacks in runtime/transport/symbols.c */
-+static void _stp_module_load_tp(void *data, struct module* mod);
-+static void _stp_module_free_tp(void *data, struct module* mod);
-+#endif
- static int _stp_module_notifier (struct notifier_block * nb,
-                                  unsigned long val, void *data);
- static struct notifier_block _stp_module_notifier_nb = {
-@@ -158,11 +180,30 @@ static void _stp_handle_start(struct _stp_msg_start *st)
-                            failed: something nasty has happened, and
-                            we want no further probing started.  PR16766 */
-                         if (!_stp_module_notifier_active) {
--                                int rc = register_module_notifier(& _stp_module_notifier_nb);
--                                if (rc == 0)
--                                        _stp_module_notifier_active = 1;
--                                else
--                                        _stp_warn ("Cannot register module notifier (%d)\n", rc);
-+#ifdef STAP_USE_MODULE_TRACEPOINTS
-+                                int rc0 = register_trace_module_load (& _stp_module_load_tp, NULL);
-+                                if (rc0)
-+                                        _stp_warn ("Cannot register module load tracepoint (%d)\n", rc0);
-+                                else {
-+                                        int rc1 = register_trace_module_free (& _stp_module_free_tp, NULL);
-+                                        if (rc1) {
-+                                                _stp_warn ("Cannot register module free tracepoint (%d)\n", rc1);
-+                                                unregister_trace_module_load(& _stp_module_load_tp, NULL);
-+                                        } else {
-+#endif
-+                                                int rc = register_module_notifier(& _stp_module_notifier_nb);
-+                                                if (rc == 0)
-+                                                        _stp_module_notifier_active = 1;
-+                                                else {
-+                                                        _stp_warn ("Cannot register module notifier (%d)\n", rc);
-+#ifdef STAP_USE_MODULE_TRACEPOINTS
-+                                                        unregister_trace_module_load(& _stp_module_load_tp, NULL);
-+                                                        unregister_trace_module_free(& _stp_module_free_tp, NULL);
-+                                                        
-+                                                }
-+                                        }
-+#endif
-+                                }
-                         }
-                 }
- 
-@@ -198,7 +239,12 @@ static void _stp_cleanup_and_exit(int send_exit)
- 
- 	        /* Unregister the module notifier. */
- 	        if (_stp_module_notifier_active) {
--                        int rc = unregister_module_notifier(& _stp_module_notifier_nb);
-+                        int rc;
-+#ifdef STAP_USE_MODULE_TRACEPOINTS
-+                        unregister_trace_module_load(& _stp_module_load_tp, NULL);
-+                        unregister_trace_module_free(& _stp_module_free_tp, NULL);
-+#endif
-+                        rc = unregister_module_notifier(& _stp_module_notifier_nb);
-                         if (rc)
-                                 _stp_warn("module_notifier unregister error %d", rc);
- 	                _stp_module_notifier_active = 0;
-
-commit 2e67c14dad1c661d2ce0b0ed218b371c1af218ba
-Author: Frank Ch. Eigler <fche@redhat.com>
-Date:   Wed Sep 2 11:16:46 2015 -0400
-
-    PR18889: switch to STP_TRACEPOINT* frontend for kernel tracepoint registration
-    
-    jistone kindly reminded that the runtime/stp_tracepoint.[ch] machinery
-    allows us to attach to kernel tracepoints, whether on string- or
-    tp*-based kernel APIs, and whether or not the tp* objects are
-    EXPORT_TRACEPOINT_SYMBOL_GPL'd.  Let's use those; presto we get
-    module-init probing back on kernels oldish and newish.
-
-diff --git a/buildrun.cxx b/buildrun.cxx
-index 6d66b5a..2ca5933 100644
---- a/buildrun.cxx
-+++ b/buildrun.cxx
-@@ -379,8 +379,6 @@ compile_pass (systemtap_session& s)
-   output_autoconf(s, o, "autoconf-module-sect-attrs.c", "STAPCONF_MODULE_SECT_ATTRS", NULL);
-   output_autoconf(s, o, "autoconf-utrace-via-tracepoints.c", "STAPCONF_UTRACE_VIA_TRACEPOINTS", NULL);
-   output_autoconf(s, o, "autoconf-module-tracepoints.c", "STAPCONF_MODULE_TRACEPOINT", NULL);
--  output_exportconf(s, o, "__tracepoint_module_load", "STAPCONF_MODULE_TRACEPOINT_EXPORT_LOAD");
--  output_exportconf(s, o, "__tracepoint_module_free", "STAPCONF_MODULE_TRACEPOINT_EXPORT_FREE");
-   output_autoconf(s, o, "autoconf-task_work-struct.c", "STAPCONF_TASK_WORK_STRUCT", NULL);
-   output_autoconf(s, o, "autoconf-vm-area-pte.c", "STAPCONF_VM_AREA_PTE", NULL);
-   output_autoconf(s, o, "autoconf-relay-umode_t.c", "STAPCONF_RELAY_UMODE_T", NULL);
-diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
-index e069a3d..db7de46 100644
---- a/runtime/transport/transport.c
-+++ b/runtime/transport/transport.c
-@@ -1,8 +1,8 @@
--/* -*- linux-c -*- 
-+/* -*- linux-c -*-
-  * transport.c - stp transport functions
-  *
-  * Copyright (C) IBM Corporation, 2005
-- * Copyright (C) Red Hat Inc, 2005-2014
-+ * Copyright (C) Red Hat Inc, 2005-2015
-  * Copyright (C) Intel Corporation, 2006
-  *
-  * This file is part of systemtap, and is free software.  You can
-@@ -23,19 +23,7 @@
- #include "../uidgid_compatibility.h"
- #ifdef STAPCONF_MODULE_TRACEPOINT
- #include <trace/events/module.h>
--#endif
--
--/* PR18889: After 3.17, commit #de7b2973903c6, tracepoints are
--   attached by symbol-address rather than by name string.  That means
--   they must be EXPORT_TRACEPOINT_SYMBOL_GPL'd for a tracepoint
--   [un]register operation.  On RHEL7 kernels with out that commit
--   backported, we can do a tracepoint attach even without the exports.  */
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
--#if defined(STAPCONF_MODULE_TRACEPOINT) && defined(STAPCONF_MODULE_TRACEPOINT_EXPORT_LOAD) && defined(STAPCONF_MODULE_TRACEPOINT_EXPORT_FREE)
--#define STAP_USE_MODULE_TRACEPOINTS
--#endif
--#elif defined(STAPCONF_MODULE_TRACEPOINT)
--#define STAP_USE_MODULE_TRACEPOINTS
-+#include "../linux/stp_tracepoint.h"
- #endif
- 
- 
-@@ -149,7 +137,7 @@ static void _stp_handle_start(struct _stp_msg_start *st)
-         // protect against excessive or premature startup
- 	handle_startup = (! _stp_start_called && ! _stp_exit_called);
- 	_stp_start_called = 1;
--	
-+
- 	if (handle_startup) {
- 		dbug_trans(1, "stp_handle_start\n");
- 
-@@ -180,15 +168,15 @@ static void _stp_handle_start(struct _stp_msg_start *st)
-                            failed: something nasty has happened, and
-                            we want no further probing started.  PR16766 */
-                         if (!_stp_module_notifier_active) {
--#ifdef STAP_USE_MODULE_TRACEPOINTS
--                                int rc0 = register_trace_module_load (& _stp_module_load_tp, NULL);
-+#ifdef STAPCONF_MODULE_TRACEPOINT
-+                                int rc0 = STP_TRACE_REGISTER(module_load, & _stp_module_load_tp);
-                                 if (rc0)
-                                         _stp_warn ("Cannot register module load tracepoint (%d)\n", rc0);
-                                 else {
--                                        int rc1 = register_trace_module_free (& _stp_module_free_tp, NULL);
-+                                        int rc1 = STP_TRACE_REGISTER(module_free, & _stp_module_free_tp);
-                                         if (rc1) {
-                                                 _stp_warn ("Cannot register module free tracepoint (%d)\n", rc1);
--                                                unregister_trace_module_load(& _stp_module_load_tp, NULL);
-+                                                STP_TRACE_UNREGISTER(module_load, & _stp_module_load_tp);
-                                         } else {
- #endif
-                                                 int rc = register_module_notifier(& _stp_module_notifier_nb);
-@@ -196,10 +184,9 @@ static void _stp_handle_start(struct _stp_msg_start *st)
-                                                         _stp_module_notifier_active = 1;
-                                                 else {
-                                                         _stp_warn ("Cannot register module notifier (%d)\n", rc);
--#ifdef STAP_USE_MODULE_TRACEPOINTS
--                                                        unregister_trace_module_load(& _stp_module_load_tp, NULL);
--                                                        unregister_trace_module_free(& _stp_module_free_tp, NULL);
--                                                        
-+#ifdef STAPCONF_MODULE_TRACEPOINT
-+                                                        STP_TRACE_UNREGISTER(module_load, & _stp_module_load_tp);
-+                                                        STP_TRACE_UNREGISTER(module_free, & _stp_module_free_tp);
-                                                 }
-                                         }
- #endif
-@@ -240,9 +227,9 @@ static void _stp_cleanup_and_exit(int send_exit)
- 	        /* Unregister the module notifier. */
- 	        if (_stp_module_notifier_active) {
-                         int rc;
--#ifdef STAP_USE_MODULE_TRACEPOINTS
--                        unregister_trace_module_load(& _stp_module_load_tp, NULL);
--                        unregister_trace_module_free(& _stp_module_free_tp, NULL);
-+#ifdef STAPCONF_MODULE_TRACEPOINT
-+                        STP_TRACE_UNREGISTER(module_load, & _stp_module_load_tp);
-+                        STP_TRACE_UNREGISTER(module_free, & _stp_module_free_tp);
- #endif
-                         rc = unregister_module_notifier(& _stp_module_notifier_nb);
-                         if (rc)
-@@ -380,7 +367,7 @@ static void _stp_ctl_work_callback(unsigned long val)
-  *	_stp_transport_close - close ctl and relayfs channels
-  *
-  *	This is called automatically when the module is unloaded.
-- *     
-+ *
-  */
- static void _stp_transport_close(void)
- {
-@@ -397,7 +384,7 @@ static void _stp_transport_close(void)
- 
- /**
-  * _stp_transport_init() is called from the module initialization.
-- *   It does the bare minimum to exchange commands with staprun 
-+ *   It does the bare minimum to exchange commands with staprun
-  */
- static int _stp_transport_init(void)
- {
-@@ -657,7 +644,7 @@ static struct dentry *_stp_get_module_dir(void)
- static int _stp_transport_fs_init(const char *module_name)
- {
- 	struct dentry *root_dir;
--    
-+
- 	dbug_trans(1, "entry\n");
- 	if (module_name == NULL)
- 		return -1;
-
-commit 578f5f6f6792fc92d74539a927cd85de5bcbb4dd
-Author: Frank Ch. Eigler <fche@redhat.com>
-Date:   Wed Sep 2 11:52:31 2015 -0400
-
-    PR18889 testing: already done by modules_out_of_tree.exp
-    
-    Ditch bz6503, given that it wasn't reliable.
-
-diff --git a/testsuite/systemtap.base/bz6503.exp b/testsuite/systemtap.base/bz6503.exp
-deleted file mode 100644
-index 5d4d2d0..0000000
---- a/testsuite/systemtap.base/bz6503.exp
-+++ /dev/null
-@@ -1,55 +0,0 @@
--# Note that this test is *really* testing the bug fix for pr6503:
--#   permit probes on module .init and __exit functions
--#   <http://sourceware.org/bugzilla/show_bug.cgi?id=6503>
--#
--# Not BZ6503:
--#   ypserve does not work
--#   <https://bugzilla.redhat.com/show_bug.cgi?id=6503>
--#
--# Unfortunately, PR17249 indicates that module-init probes
--# have subsequently broken (due to kernel notification timing
--# changes).
--#
--
--set test bz6503
--
--if {! [installtest_p]} {
--    untested "$test"
--    return
--}
--
--# If we aren't root, make sure the test still succeeds.
--set effective_pid [exec /usr/bin/id -u]
--if {$effective_pid != 0} {
--    set root_cmd "sudo "
--} else {
--    set root_cmd ""
--}
--
--
--# jffs2/ext2/fat/vfat should cover a span of kernels.
--#
--# Note that this test might fail if there is a filesystem of one of
--# these types already mounted.  The filesystem mount will be
--# unaffected (since the module can't be removed).
--spawn stap -t $srcdir/$subdir/bz6503.stp -c "( ($root_cmd /sbin/modprobe jffs2; $root_cmd /sbin/modprobe ext2; $root_cmd /sbin/modprobe fat; $root_cmd /sbin/modprobe vfat); wait; ($root_cmd /sbin/rmmod jffs2; $root_cmd /sbin/rmmod ext2; $root_cmd /sbin/rmmod vfat; $root_cmd /sbin/rmmod fat); wait) 2>/dev/null"
--
--set ok 0
--set ko 0
--expect {
--    -timeout 60
--    timeout { fail "$test (timeout)" }
--    -re {^-----[^\r\n]*\r\n} { exp_continue }
--    -re {^module[^\r\n]*hits:[^\r\n]*\r\n} { incr ok; exp_continue }
--    -re {^WARNING:[\r\n]*\r\n} { incr ko; exp_continue }
--    -re {^ERROR:[\r\n]*\r\n} { incr ko; exp_continue }
--    eof { }
--}
--catch { close} ; catch { wait }
--
--# Mark kernels without module refresh support as xfail
--if {![module_refresh_p]} { setup_xfail *-*-* }
--
--if {$ok > 0 && $ko == 0} then { pass "$test $ok" } else { fail "$test $ok $ko"}
--
--
-diff --git a/testsuite/systemtap.base/bz6503.stp b/testsuite/systemtap.base/bz6503.stp
-deleted file mode 100644
-index 409149f..0000000
---- a/testsuite/systemtap.base/bz6503.stp
-+++ /dev/null
-@@ -1,5 +0,0 @@
--probe module("jffs2").function("*").call ?,
--      module("ext2").function("*").call ?,
--      module("fat").function("*").call ?,
--      module("vfat").function("*").call ?,
--      never { }
diff --git a/SOURCES/rhbz1269062.patch b/SOURCES/rhbz1269062.patch
new file mode 100644
index 0000000..40fc02a
--- /dev/null
+++ b/SOURCES/rhbz1269062.patch
@@ -0,0 +1,22 @@
+commit a32189c495cf4dbb71fa497adcaa2ab31aad7021
+Author: Martin Cermak <mcermak@redhat.com>
+Date:   Wed Jun 29 19:03:11 2016 +0200
+
+    Avoid null pointer exception in the ioscheduler.elv_add_request probe.
+    
+    This update makes the ioscheduler.elv_add_request probe gracefully handle
+    situation where $q->elevator is NULL (RHBZ1269062).
+
+diff --git a/tapset/linux/ioscheduler.stp b/tapset/linux/ioscheduler.stp
+index 00d75a5..121fde8 100644
+--- a/tapset/linux/ioscheduler.stp
++++ b/tapset/linux/ioscheduler.stp
+@@ -149,7 +149,7 @@ probe ioscheduler.elv_add_request.tp = kernel.trace("block_rq_insert") ?
+ {
+ 	name = "elv_add_request"
+ 	q =  $q
+-	elevator_name = kernel_string(
++	elevator_name = ($q->elevator == 0) ? "" : kernel_string(
+ 		@choose_defined($q->elevator->type->elevator_name,
+ 			@choose_defined($q->elevator->elevator_type->elevator_name,
+                                         $q->elevator->elevator_name)), "")
diff --git a/SOURCES/rhbz1312169.patch b/SOURCES/rhbz1312169.patch
new file mode 100644
index 0000000..e758265
--- /dev/null
+++ b/SOURCES/rhbz1312169.patch
@@ -0,0 +1,33 @@
+commit 63a758b4890e729195fde868e34d0015cda8b065
+Author: Frank Ch. Eigler <fche@redhat.com>
+Date:   Thu Aug 11 13:40:55 2016 -0400
+
+    RHBZ1312169: make stap-prep fall back to debuginfo-install
+    
+    On some fedora / rhel boxes and their repo selections,
+    "debuginfo-install" can sometimes fetch the right files
+    even if "yum install" cannot.
+
+diff --git a/stap-prep b/stap-prep
+index 5c233bf..ca9adff 100755
+--- a/stap-prep
++++ b/stap-prep
+@@ -26,13 +26,17 @@ KERN_ARCH=`uname -m`
+ KERN_REV=`echo $UNAME | sed s/.$KERN_ARCH//` # strip arch from uname
+ CANDIDATES="$KERNEL-$KERN_REV.$KERN_ARCH \
+   $KERNEL-devel-$KERN_REV.$KERN_ARCH \
++  yum-utils \
+   $KERNEL-debuginfo-$KERN_REV.$KERN_ARCH"
+ NEEDED=`rpm --qf "%{name}-%{version}-%{release}.%{arch}\n" \
+     -q $CANDIDATES | grep "is not installed" | awk '{print $2}'`
+ if [ "$NEEDED" != "" ]; then
+     echo -e "Need to install the following packages:\n$NEEDED"
+     if [ `id -u` = "0" ]; then #attempt to install
+-        yum install -y --enablerepo=\* $NEEDED
++        yum install -y --enablerepo=\* $NEEDED ||
++	    (if expr "$NEEDED" : ".*debuginfo.*" >/dev/null;
++             then debuginfo-install -y $KERNEL-$KERN_REV.$KERN_ARCH;
++             fi)
+         rpm -q $NEEDED
+         check_error $? "problem installing rpm(s) $NEEDED"
+     fi
diff --git a/SOURCES/rhbz1337416.patch b/SOURCES/rhbz1337416.patch
new file mode 100644
index 0000000..f278c90
--- /dev/null
+++ b/SOURCES/rhbz1337416.patch
@@ -0,0 +1,578 @@
+commit 056cb27baac1ce3ab4d675dbbe4881afde801ca3
+Author: Frank Ch. Eigler <fche@redhat.com>
+Date:   Wed Jun 22 11:43:33 2016 -0400
+
+    PR18079: support nested autocast / @defined
+    
+    We now perform const-folding & dead-code-elision during the type
+    resolution loop, whenever an autocast expression gets evaluated.  This
+    way, @defined(foo()->mm) type expressions can work as nature intended.
+    
+    This requires @defined() not to be short-circuit evaluated to 0 during
+    a random const_folding process, so a flag is introduced to control its
+    preservation or collapsing.  For the last (assert_resolvability) pass
+    in the type resolution loop, this flag is set to true, so that
+    genuinely unresolvable @defined($expressions) do get mapped to 0 in
+    time for a last elision.
+
+diff --git a/elaborate.cxx b/elaborate.cxx
+index 4a375d9..a1088a1 100644
+--- a/elaborate.cxx
++++ b/elaborate.cxx
+@@ -3984,9 +3984,10 @@ struct const_folder: public update_visitor
+ {
+   systemtap_session& session;
+   bool& relaxed_p;
+-
+-  const_folder(systemtap_session& s, bool& r):
+-    session(s), relaxed_p(r), last_number(0), last_string(0) {}
++  bool collapse_defines_p;
++  
++  const_folder(systemtap_session& s, bool& r, bool collapse_defines = false):
++    session(s), relaxed_p(r), collapse_defines_p(collapse_defines), last_number(0), last_string(0) {}
+ 
+   literal_number* last_number;
+   literal_number* get_number(expression*& e);
+@@ -4506,15 +4507,26 @@ const_folder::visit_ternary_expression (ternary_expression* e)
+ void
+ const_folder::visit_defined_op (defined_op* e)
+ {
+-  // If a @defined makes it this far, then it is, de facto, undefined.
+-
+-  if (session.verbose>2)
+-    clog << _("Collapsing untouched @defined check ") << *e->tok << endl;
+-  relaxed_p = false;
++  // If a @defined makes it this far, then it was not resolved by
++  // previous efforts.  We could assume that therefore it is a big fat
++  // zero, but for the @defined(autocast) case PR18079, this just
++  // means that we didn't know yet.
+ 
+-  literal_number* n = new literal_number (0);
+-  n->tok = e->tok;
+-  n->visit (this);
++  if (collapse_defines_p)
++    {
++      if (session.verbose>2)
++        clog << _("Collapsing untouched @defined check ") << *e->tok << endl;
++       relaxed_p = false;
++       literal_number* n = new literal_number (0);
++       n->tok = e->tok;
++       n->visit (this);
++    }
++  else
++    {
++      if (session.verbose>2)
++        clog << _("Preserving unresolved @defined check ") << *e->tok << endl;
++      provide (e);
++    }
+ }
+ 
+ void
+@@ -5387,6 +5399,21 @@ semantic_pass_types (systemtap_session& s)
+             ti.current_probe = 0;
+             ti.current_function = fd;
+             ti.t = pe_unknown;
++
++            if (ti.assert_resolvability)
++              {
++                // PR18079, rerun the const-folder / dead-block-remover
++                // one last time, in case an unresolvable
++                // @defined($foobar) still persists.  This should map
++                // those to 0.
++                bool relaxed_p;
++                const_folder cf (s, relaxed_p, true); // NB: true
++                cf.replace (fd->body);
++                dead_control_remover dc (s, relaxed_p);
++                fd->body->visit (&dc);
++                (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
++              }
++              
+             fd->body->visit (& ti);
+             // NB: we don't have to assert a known type for
+             // functions here, to permit a "void" function.
+@@ -5402,6 +5429,16 @@ semantic_pass_types (systemtap_session& s)
+               {
+                 autocast_expanding_visitor aev (ti);
+                 aev.replace (fd->body);
++
++                // PR18079, rerun the const-folder / dead-block-remover
++                // in case autocast evaluation enabled a @defined()
++                bool relaxed_p;
++                const_folder cf (s, relaxed_p);
++                cf.replace (fd->body);
++                dead_control_remover dc (s, relaxed_p);
++                fd->body->visit (&dc);
++                (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
++
+                 ti.num_available_autocasts = 0;
+               }
+           }
+@@ -5420,6 +5457,21 @@ semantic_pass_types (systemtap_session& s)
+             ti.current_function = 0;
+             ti.current_probe = pn;
+             ti.t = pe_unknown;
++
++            if (ti.assert_resolvability)
++              {
++                // PR18079, rerun the const-folder / dead-block-remover
++                // one last time, in case an unresolvable
++                // @defined($foobar) still persists.  This should map
++                // those to 0.
++                bool relaxed_p;
++                const_folder cf (s, relaxed_p, true); // NB: true
++                cf.replace (pn->body);
++                dead_control_remover dc (s, relaxed_p);
++                pn->body->visit (&dc);
++                (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
++              }
++            
+             pn->body->visit (& ti);
+             for (unsigned i=0; i < pn->locals.size(); ++i)
+               ti.check_local (pn->locals[i]);
+@@ -5429,6 +5481,16 @@ semantic_pass_types (systemtap_session& s)
+               {
+                 autocast_expanding_visitor aev (ti);
+                 aev.replace (pn->body);
++
++                // PR18079, rerun the const-folder / dead-block-remover
++                // in case autocast evaluation enabled a @defined()
++                bool relaxed_p;
++                const_folder cf (s, relaxed_p);
++                cf.replace (pn->body);
++                dead_control_remover dc (s, relaxed_p);
++                pn->body->visit (&dc);
++                (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
++
+                 ti.num_available_autocasts = 0;
+               }
+             
+@@ -5907,7 +5969,15 @@ typeresolution_info::visit_target_symbol (target_symbol* e)
+   // later unused-expression-elimination pass didn't get rid of it
+   // either.  So we have a target symbol that is believed to be of
+   // genuine use, yet unresolved by the provider.
+-
++  //
++  // PR18079, or it can happen if a $target expression is nested within
++  // a @defined() test that has not yet been resolved (but can be soon).
++  if (! assert_resolvability)
++    {
++      num_still_unresolved ++;
++      return;
++    }
++  
+   if (session.verbose > 2)
+     {
+       clog << _("Resolution problem with ");
+@@ -5974,7 +6044,15 @@ typeresolution_info::visit_atvar_op (atvar_op* e)
+ void
+ typeresolution_info::visit_defined_op (defined_op* e)
+ {
+-  throw SEMANTIC_ERROR(_("unexpected @defined"), e->tok);
++  // PR18079: if a @defined is still around, it may have a parameter that
++  // wasn't resolvable one way or another earlier.  Maybe an autocast_op.
++  // Let's give it a visit just in case. 
++  e->operand->visit(this);
++
++  if (assert_resolvability)
++    throw SEMANTIC_ERROR(_("unexpected @defined"), e->tok);
++  else
++    num_still_unresolved ++;
+ }
+ 
+ 
+diff --git a/testsuite/semok/autocast14.stp b/testsuite/semok/autocast14.stp
+index 55c06c4..1b32d80 100755
+--- a/testsuite/semok/autocast14.stp
++++ b/testsuite/semok/autocast14.stp
+@@ -1,7 +1,7 @@
+ #! stap -p2
+ 
+-probe oneshot
+-{
++
++@define STUFF %(
+     // precheck, it should work with @cast
+     if (!@defined(@task(0)->mm)) {
+         println($cast_failed_mm)
+@@ -17,4 +17,16 @@ probe oneshot
+     if (@defined(task_current()->systemtap)) {
+         println($autocast_succeeded_systemtap)
+     }
++%)
++
++
++probe oneshot
++{
++  @STUFF
++  foo() // from a function too, to test PR18079 function processing
+ }
++
++function foo ()
++{
++  @STUFF
++}
+\ No newline at end of file
+
+commit 0eda9cd7c9fe3cf7622f6bcf5e9cfba9fdf537dd
+Author: Josh Stone <jistone@redhat.com>
+Date:   Wed Jun 22 12:09:05 2016 -0700
+
+    Increase the difficulty of semok/autocast14.stp
+
+diff --git a/testsuite/semok/autocast14.stp b/testsuite/semok/autocast14.stp
+index 1b32d80..b9488d7 100755
+--- a/testsuite/semok/autocast14.stp
++++ b/testsuite/semok/autocast14.stp
+@@ -17,6 +17,19 @@
+     if (@defined(task_current()->systemtap)) {
+         println($autocast_succeeded_systemtap)
+     }
++
++    // Test that autocast can resolve on the results of @defined
++    mm1 = @choose_defined($nonsense, task_current())->mm;
++    mm2 = @choose_defined(task_current(), $nonsense)->mm;
++    println(mm1 == mm2)
++
++    // Test an even deeper level of @defined
++    if (!@defined(mm1->mmap) || !@defined(mm2->mmap)) {
++        println($autocast_failed_mm_mmap)
++    }
++    if (@defined(mm1->systemtap) || @defined(mm2->systemtap)) {
++        println($autocast_succeeded_mm_systemtap)
++    }
+ %)
+ 
+ 
+@@ -29,4 +42,4 @@ probe oneshot
+ function foo ()
+ {
+   @STUFF
+-}
+\ No newline at end of file
++}
+
+commit 048b546d5645abb6e6ef5148c4ddbd170600e1d3
+Author: Josh Stone <jistone@redhat.com>
+Date:   Fri Jul 8 18:21:49 2016 -0700
+
+    Tweak autocast-defined interactions further
+    
+    - collapse basic @defined($foo) right away.
+    - last-ditch collapse other @defined(expr) to 1 or 0 depending on pe_unknown.
+    - run that last-ditch effort *before* turning on assert_resolvability.
+    - only run extra dead_control_remover for optimized runs
+    - in var_expanding_visitor, pass *any* unchanged expr through, so they
+      may be decided later.  (e.g. for @choose_defined ternaries)
+
+diff --git a/elaborate.cxx b/elaborate.cxx
+index a1088a1..fd6ccce 100644
+--- a/elaborate.cxx
++++ b/elaborate.cxx
+@@ -3987,7 +3987,8 @@ struct const_folder: public update_visitor
+   bool collapse_defines_p;
+   
+   const_folder(systemtap_session& s, bool& r, bool collapse_defines = false):
+-    session(s), relaxed_p(r), collapse_defines_p(collapse_defines), last_number(0), last_string(0) {}
++    session(s), relaxed_p(r), collapse_defines_p(collapse_defines),
++    last_number(0), last_string(0), last_target_symbol(0) {}
+ 
+   literal_number* last_number;
+   literal_number* get_number(expression*& e);
+@@ -4011,6 +4012,9 @@ struct const_folder: public update_visitor
+   void visit_concatenation (concatenation* e);
+   void visit_ternary_expression (ternary_expression* e);
+   void visit_defined_op (defined_op* e);
++
++  target_symbol* last_target_symbol;
++  target_symbol* get_target_symbol(expression*& e);
+   void visit_target_symbol (target_symbol* e);
+ };
+ 
+@@ -4511,15 +4515,35 @@ const_folder::visit_defined_op (defined_op* e)
+   // previous efforts.  We could assume that therefore it is a big fat
+   // zero, but for the @defined(autocast) case PR18079, this just
+   // means that we didn't know yet.
++  int64_t value = 0;
++  bool collapse_this = false;
+ 
+-  if (collapse_defines_p)
++  // We do know that plain target_symbols aren't going anywhere though.
++  if (get_target_symbol (e->operand))
++    {
++      if (session.verbose>2)
++        clog << _("Collapsing target_symbol @defined check ") << *e->tok << endl;
++      collapse_this = true;
++    }
++  else if (collapse_defines_p && relaxed_p)
+     {
+       if (session.verbose>2)
+         clog << _("Collapsing untouched @defined check ") << *e->tok << endl;
+-       relaxed_p = false;
+-       literal_number* n = new literal_number (0);
+-       n->tok = e->tok;
+-       n->visit (this);
++
++      // If we got to an expression with a known type, call it defined.
++      if (e->operand->type != pe_unknown)
++        value = 1;
++      collapse_this = true;
++    }
++
++  if (collapse_this)
++    {
++      // Don't be greedy... we'll only collapse one at a time so type
++      // resolution can have another go at it.
++      relaxed_p = false;
++      literal_number* n = new literal_number (value);
++      n->tok = e->tok;
++      n->visit (this);
+     }
+   else
+     {
+@@ -4529,6 +4553,13 @@ const_folder::visit_defined_op (defined_op* e)
+     }
+ }
+ 
++target_symbol*
++const_folder::get_target_symbol(expression*& e)
++{
++  replace (e);
++  return (e == last_target_symbol) ? last_target_symbol : NULL;
++}
++
+ void
+ const_folder::visit_target_symbol (target_symbol* e)
+ {
+@@ -4545,7 +4576,10 @@ const_folder::visit_target_symbol (target_symbol* e)
+       relaxed_p = false;
+     }
+   else
+-    update_visitor::visit_target_symbol (e);
++    {
++      update_visitor::visit_target_symbol (e);
++      last_target_symbol = e;
++    }
+ }
+ 
+ static int initial_typeres_pass(systemtap_session& s);
+@@ -5400,20 +5434,6 @@ semantic_pass_types (systemtap_session& s)
+             ti.current_function = fd;
+             ti.t = pe_unknown;
+ 
+-            if (ti.assert_resolvability)
+-              {
+-                // PR18079, rerun the const-folder / dead-block-remover
+-                // one last time, in case an unresolvable
+-                // @defined($foobar) still persists.  This should map
+-                // those to 0.
+-                bool relaxed_p;
+-                const_folder cf (s, relaxed_p, true); // NB: true
+-                cf.replace (fd->body);
+-                dead_control_remover dc (s, relaxed_p);
+-                fd->body->visit (&dc);
+-                (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
+-              }
+-              
+             fd->body->visit (& ti);
+             // NB: we don't have to assert a known type for
+             // functions here, to permit a "void" function.
+@@ -5431,13 +5451,19 @@ semantic_pass_types (systemtap_session& s)
+                 aev.replace (fd->body);
+ 
+                 // PR18079, rerun the const-folder / dead-block-remover
+-                // in case autocast evaluation enabled a @defined()
+-                bool relaxed_p;
+-                const_folder cf (s, relaxed_p);
+-                cf.replace (fd->body);
+-                dead_control_remover dc (s, relaxed_p);
+-                fd->body->visit (&dc);
+-                (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
++                // if autocast evaluation enabled a @defined()
++                if (aev.count_replaced_defined_ops() > 0)
++                  {
++                    bool relaxed_p = true;
++                    const_folder cf (s, relaxed_p);
++                    cf.replace (fd->body);
++                    if (! s.unoptimized)
++                      {
++                        dead_control_remover dc (s, relaxed_p);
++                        fd->body->visit (&dc);
++                      }
++                    (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
++                  }
+ 
+                 ti.num_available_autocasts = 0;
+               }
+@@ -5458,20 +5484,6 @@ semantic_pass_types (systemtap_session& s)
+             ti.current_probe = pn;
+             ti.t = pe_unknown;
+ 
+-            if (ti.assert_resolvability)
+-              {
+-                // PR18079, rerun the const-folder / dead-block-remover
+-                // one last time, in case an unresolvable
+-                // @defined($foobar) still persists.  This should map
+-                // those to 0.
+-                bool relaxed_p;
+-                const_folder cf (s, relaxed_p, true); // NB: true
+-                cf.replace (pn->body);
+-                dead_control_remover dc (s, relaxed_p);
+-                pn->body->visit (&dc);
+-                (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
+-              }
+-            
+             pn->body->visit (& ti);
+             for (unsigned i=0; i < pn->locals.size(); ++i)
+               ti.check_local (pn->locals[i]);
+@@ -5483,13 +5495,19 @@ semantic_pass_types (systemtap_session& s)
+                 aev.replace (pn->body);
+ 
+                 // PR18079, rerun the const-folder / dead-block-remover
+-                // in case autocast evaluation enabled a @defined()
+-                bool relaxed_p;
+-                const_folder cf (s, relaxed_p);
+-                cf.replace (pn->body);
+-                dead_control_remover dc (s, relaxed_p);
+-                pn->body->visit (&dc);
+-                (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
++                // if autocast evaluation enabled a @defined()
++                if (aev.count_replaced_defined_ops() > 0)
++                  {
++                    bool relaxed_p = true;
++                    const_folder cf (s, relaxed_p);
++                    cf.replace (pn->body);
++                    if (! s.unoptimized)
++                      {
++                        dead_control_remover dc (s, relaxed_p);
++                        pn->body->visit (&dc);
++                      }
++                    (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
++                  }
+ 
+                 ti.num_available_autocasts = 0;
+               }
+@@ -5526,9 +5544,27 @@ semantic_pass_types (systemtap_session& s)
+             break; // successfully
+           else if (! ti.assert_resolvability)
+             {
+-              ti.assert_resolvability = true; // last pass, with error msgs
+-              if (s.verbose > 0)
+-                ti.mismatch_complexity = 0; // print every kind of mismatch
++              // PR18079, before we go asserting anything, try to nullify any
++              // still-unresolved @defined ops.
++              bool relaxed_p = true;
++              const_folder cf (s, relaxed_p, true); // NB: true
++
++              for (auto it = s.probes.begin(); it != s.probes.end(); ++it)
++                cf.replace ((*it)->body);
++              for (auto it = s.functions.begin(); it != s.functions.end(); ++it)
++                cf.replace (it->second->body);
++
++              if (! s.unoptimized)
++                semantic_pass_dead_control (s, relaxed_p);
++
++              if (! relaxed_p)
++                ti.mismatch_complexity = 0; // reset for next pass
++              else
++                {
++                  ti.assert_resolvability = true; // last pass, with error msgs
++                  if (s.verbose > 0)
++                    ti.mismatch_complexity = 0; // print every kind of mismatch
++                }
+             }
+           else
+             { // unsuccessful conclusion
+diff --git a/tapsets.cxx b/tapsets.cxx
+index 069966b..6d82069 100644
+--- a/tapsets.cxx
++++ b/tapsets.cxx
+@@ -2835,7 +2835,8 @@ private:
+ unsigned var_expanding_visitor::tick = 0;
+ 
+ 
+-var_expanding_visitor::var_expanding_visitor (): op()
++var_expanding_visitor::var_expanding_visitor ():
++  replaced_defined_ops(0), op()
+ {
+   // FIXME: for the time being, by default we only support plain '$foo
+   // = bar', not '+=' or any other op= variant. This is fixable, but a
+@@ -2964,6 +2965,7 @@ var_expanding_visitor::visit_delete_statement (delete_statement* s)
+ void
+ var_expanding_visitor::visit_defined_op (defined_op* e)
+ {
++  expression * const old_operand = e->operand;
+   bool resolved = true;
+ 
+   defined_ops.push (e);
+@@ -2999,11 +3001,12 @@ var_expanding_visitor::visit_defined_op (defined_op* e)
+     target_symbol* tsym = dynamic_cast<target_symbol*> (e->operand);
+     if (tsym && tsym->saved_conversion_error) // failing
+       resolved = false;
+-    else if (tsym) // unresolved but not marked failing
++    else if (e->operand == old_operand) // unresolved but not marked failing
+       {
+         // There are some visitors that won't touch certain target_symbols,
+         // e.g. dwarf_var_expanding_visitor won't resolve @cast.  We should
+         // leave it for now so some other visitor can have a chance.
++        defined_ops.pop ();
+         provide (e);
+         return;
+       }
+@@ -3017,6 +3020,7 @@ var_expanding_visitor::visit_defined_op (defined_op* e)
+   literal_number* ln = new literal_number (resolved ? 1 : 0);
+   ln->tok = e->tok;
+   provide (ln);
++  ++replaced_defined_ops;
+ }
+ 
+ 
+diff --git a/tapsets.h b/tapsets.h
+index d630dbb..cb73a7e 100644
+--- a/tapsets.h
++++ b/tapsets.h
+@@ -61,11 +61,6 @@ public:
+ 
+ struct var_expanding_visitor: public update_visitor
+ {
+-  static unsigned tick;
+-  std::stack<defined_op*> defined_ops;
+-  std::set<std::string> valid_ops;
+-  interned_string* op;
+-
+   var_expanding_visitor ();
+   void visit_assignment (assignment* e);
+   void visit_pre_crement (pre_crement* e);
+@@ -73,6 +68,15 @@ struct var_expanding_visitor: public update_visitor
+   void visit_delete_statement (delete_statement* s);
+   void visit_defined_op (defined_op* e);
+ 
++  unsigned count_replaced_defined_ops () { return replaced_defined_ops; }
++
++protected:
++  static unsigned tick;
++  unsigned replaced_defined_ops;
++  std::stack<defined_op*> defined_ops;
++  std::set<std::string> valid_ops;
++  interned_string* op;
++
+   void provide_lvalue_call(functioncall* fcall);
+ 
+ private:
+diff --git a/testsuite/semok/autocast14.stp b/testsuite/semok/autocast14.stp
+index b9488d7..18028e8 100755
+--- a/testsuite/semok/autocast14.stp
++++ b/testsuite/semok/autocast14.stp
+@@ -30,6 +30,13 @@
+     if (@defined(mm1->systemtap) || @defined(mm2->systemtap)) {
+         println($autocast_succeeded_mm_systemtap)
+     }
++
++    // Test that autocast can resolve through nested @defined
++    // (especially that the ternary isn't automatically "defined")
++    mm3 = @choose_defined(@choose_defined($nonsense, $wut), task_current())->mm;
++    mm4 = @choose_defined(@choose_defined($nonsense, task_current()), $wut)->mm;
++    mm5 = @choose_defined(@choose_defined(task_current(), $nonsense), $wut)->mm;
++    println(mm3 == mm4 && mm4 == mm5)
+ %)
+ 
+ 
diff --git a/SOURCES/rhbz1346112.patch b/SOURCES/rhbz1346112.patch
new file mode 100644
index 0000000..8a74218
--- /dev/null
+++ b/SOURCES/rhbz1346112.patch
@@ -0,0 +1,62 @@
+commit be665e77eb7cd88a3d15676945bec7def3eb73d5
+Author: Frank Ch. Eigler <fche@redhat.com>
+Date:   Wed Jun 15 10:58:01 2016 -0400
+
+    RHBZ1346112: let stap-server create ssl-cert  on first run rather than install
+    
+    This way different container-images get different certs.
+
+diff --git a/stap-server b/stap-server
+index 939c503..c39ae49 100644
+--- a/stap-server
++++ b/stap-server
+@@ -500,6 +500,19 @@ prepare_stat_dir () {
+   return 0
+ }
+ 
++prepare_certs () {
++    if [ "$USER" != "`id -un`" ]; then
++        if ! runuser -s /bin/bash - $USER -c 'test -f $HOME/.systemtap/ssl/server/stap.cert'; then
++            runuser -s /bin/bash - $USER -c %{_libexecdir}/systemtap/stap-gen-cert >/dev/null
++        fi
++    else
++        if ! test -f $HOME/.systemtap/ssl/server/stap.cert; then
++            ${PKGLIBEXECDIR}stap-gen-cert
++        fi
++    fi
++}
++
++
+ prepare_log_dir () {
+   local log_path=`dirname "$1"`
+   if [ ! -d "$log_path" ]; then
+@@ -859,6 +872,13 @@ start_server () {
+ 	fi
+     fi
+ 
++    # Create certificates for this server
++    prepare_certs
++    if [ $? -ne 0 ]; then
++	echo $"Failed to make certificates ($USER .systemtap/ssl/server/stap.cert)" >&2
++	exit 1
++    fi
++
+     # Create the log directory for this server
+     prepare_log_dir "$LOG"
+     if [ $? -ne 0 ]; then
+diff --git a/systemtap.spec b/systemtap.spec
+index 1630fba..84bf041 100644
+--- a/systemtap.spec
++++ b/systemtap.spec
+@@ -658,11 +658,6 @@ test -e %{_localstatedir}/log/stap-server/log || {
+      chmod 644 %{_localstatedir}/log/stap-server/log
+      chown stap-server:stap-server %{_localstatedir}/log/stap-server/log
+ }
+-# If it does not already exist, as stap-server, generate the certificate
+-# used for signing and for ssl.
+-if test ! -e ~stap-server/.systemtap/ssl/server/stap.cert; then
+-   runuser -s /bin/sh - stap-server -c %{_libexecdir}/systemtap/stap-gen-cert >/dev/null
+-fi
+ # Prepare the service
+ %if %{with_systemd}
+      # Note, Fedora policy doesn't allow network services enabled by default
diff --git a/SOURCES/rhbz1365550.patch b/SOURCES/rhbz1365550.patch
new file mode 100644
index 0000000..15052ec
--- /dev/null
+++ b/SOURCES/rhbz1365550.patch
@@ -0,0 +1,52 @@
+commit 10c48d46fa482b8cc762592aaee6c7cc178356e7
+Author: Frank Ch. Eigler <fche@redhat.com>
+Date:   Mon Mar 28 08:54:11 2016 -0400
+
+    PR19874: reset 60s alarm for "stap -c CMD"
+    
+    Brown paper bag bug.  Test case included.
+
+diff --git a/staprun/mainloop.c b/staprun/mainloop.c
+index 82c0c74..874fbd8 100644
+--- a/staprun/mainloop.c
++++ b/staprun/mainloop.c
+@@ -281,6 +281,7 @@ void start_cmd(void)
+     raise (SIGCONT); /* Harmless; just passes control to parent. */
+ #endif /* !WORKAROUND_BZ467568 */
+ 
++    alarm(0); /* clear alarms */
+     dbug(1, "execing target_cmd %s\n", target_cmd);
+ 
+     /* Note that execvp() is not a direct system call; it does a $PATH
+diff --git a/testsuite/systemtap.base/staprunwait.exp b/testsuite/systemtap.base/staprunwait.exp
+new file mode 100644
+index 0000000..fc71973
+--- /dev/null
++++ b/testsuite/systemtap.base/staprunwait.exp
+@@ -0,0 +1,17 @@
++set test staprunwait
++
++if {! [installtest_p]} { untested $test; return }
++    
++foreach runtime [get_runtime_list] {
++    if {$runtime != ""} {
++        set ok [catch {exec stap $srcdir/$subdir/$test.stp --runtime=$runtime -c "sleep 120"} foo]
++    } else {
++        set ok [catch {exec stap $srcdir/$subdir/$test.stp -c "sleep 120"} foo]
++    }
++    verbose -log "$ok $foo"
++    if {$ok != 0} {
++        fail "$test $runtime"
++    } else {
++        pass "$test $runtime"
++    }
++}
+diff --git a/testsuite/systemtap.base/staprunwait.stp b/testsuite/systemtap.base/staprunwait.stp
+new file mode 100644
+index 0000000..91cbc92
+--- /dev/null
++++ b/testsuite/systemtap.base/staprunwait.stp
+@@ -0,0 +1,3 @@
++#! /usr/bin/env stap
++
++probe timer.s(10) { println(ctime()) }
diff --git a/SOURCES/rhbz1376515.patch b/SOURCES/rhbz1376515.patch
new file mode 100644
index 0000000..bbe92e6
--- /dev/null
+++ b/SOURCES/rhbz1376515.patch
@@ -0,0 +1,281 @@
+From fced4ba337a4eddb4163994834a122e62c6efdfb Mon Sep 17 00:00:00 2001
+From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
+Date: Wed, 14 Sep 2016 13:32:51 +0530
+Subject: [PATCH 1/2] ppc64le: Store correct function entry address in
+ symbol_table
+
+PPC64 ELF ABI v2 has a Global Entry Point and a Local Entry Point for
+the functions. Debuginfo of ELF contains GEP which is same as entrypc
+while symbol table contains GEP and offset, from which we can calculate
+LEP. LEP is used to call function within single CU, when TOC pointer
+update is not required. Placing a probe on LEP catches call from both
+the GEP and the LEP but, by default, systemtap probes on GEP.
+
+For ppc64le, Systemtap stores LEP in symbol table and prioritize symbol
+table over debuginfo. But, storing LEP in symbol table has couple of
+regression effect. As LEP is only required at a time of adding a probe,
+don't store it in symbol table.
+
+No need to prioritize symbol table as well because debuginfo and symbol
+table both will contain Global Entry Point.
+
+Revert commit b4c6a4b1cd00 ("Prioritize symbol table lookup for ppc64le")
+partially.
+
+Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
+---
+ tapsets.cxx | 62 +------------------------------------------------------------
+ 1 file changed, 1 insertion(+), 61 deletions(-)
+
+diff --git a/tapsets.cxx b/tapsets.cxx
+index 4167678..a887e1f 100644
+--- a/tapsets.cxx
++++ b/tapsets.cxx
+@@ -2134,18 +2134,6 @@ query_dwarf_inline_instance (Dwarf_Die * die, dwarf_query * q)
+     }
+ }
+ 
+-static bool
+-is_filtered_func_exists (func_info_map_t const& filtered, func_info *fi)
+-{
+-  for (unsigned i = 0; i < filtered.size(); i++)
+-    {
+-      if ((filtered[i].entrypc == fi->entrypc) && (filtered[i].name == fi->name))
+-        return true;
+-    }
+-
+-  return false;
+-}
+-
+ static int
+ query_dwarf_func (Dwarf_Die * func, dwarf_query * q)
+ {
+@@ -2198,37 +2186,7 @@ query_dwarf_func (Dwarf_Die * func, dwarf_query * q)
+           q->dw.function_line (&func.decl_line);
+ 
+           Dwarf_Addr entrypc;
+-
+-          func.entrypc = 0;
+-          Dwarf_Addr bias;
+-          Dwfl_Module *mod = q->dw.module;
+-          Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
+-                     ?: dwfl_module_getelf (mod, &bias));
+-
+-          GElf_Ehdr ehdr_mem;
+-          GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
+-          if (em == NULL) throw SEMANTIC_ERROR (_("Couldn't get elf header"));
+-
+-          /* Giving priority to sym_table for ppc64*/
+-          if ((em->e_machine == EM_PPC64) && ((em->e_flags & EF_PPC64_ABI) == 2)
+-              && (q->dw.mod_info->sym_table))
+-            {
+-              /* The linkage name is the best match for the symbol table. */
+-              const string& linkage_name = dwarf_linkage_name(&func.die)
+-                ?: dwarf_diename(&func.die) ?: (string)func.name;
+-
+-              set<func_info *> fis = q->dw.mod_info->sym_table->lookup_symbol(linkage_name);
+-              for (set<func_info*>::iterator it=fis.begin(); it!=fis.end() ; ++it)
+-                {
+-                  func.entrypc = (*it)->entrypc;
+-                  if (is_filtered_func_exists(q->filtered_functions, &func))
+-                    continue;
+-                  q->filtered_functions.push_back(func);
+-                }
+-            }
+-
+-          /* If not ppc64 or not found in sym_table, try it directly. */
+-          if (!func.entrypc && q->dw.function_entrypc (&entrypc))
++          if (q->dw.function_entrypc (&entrypc))
+             {
+               func.entrypc = entrypc;
+               q->filtered_functions.push_back (func);
+@@ -8448,13 +8406,6 @@ symbol_table::get_from_elf()
+   int syments = dwfl_module_getsymtab(mod);
+   assert(syments);
+   prepare_section_rejection(mod);
+-  Dwarf_Addr bias;
+-  Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
+-              ?: dwfl_module_getelf (mod, &bias));
+-
+-  GElf_Ehdr ehdr_mem;
+-  GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
+-  if (em == NULL) throw SEMANTIC_ERROR (_("Couldn't get elf header"));
+ 
+   for (int i = 1; i < syments; ++i)
+     {
+@@ -8487,18 +8438,7 @@ symbol_table::get_from_elf()
+         continue;
+       interned_string name = n;
+ 
+-     /*
+-      * For ELF ABI v2 on PPC64 LE, we need to adjust sym.st_value corresponding
+-      * to the bits of sym.st_other. These bits will tell us what's the offset
+-      * of the local entry point from the global entry point.
+-      *
+-      * st_other field is currently only used with ABIv2 on ppc64
+-      */
+       Dwarf_Addr entrypc = addr;
+-      if ((em->e_machine == EM_PPC64) && ((em->e_flags & EF_PPC64_ABI) == 2)
+-          && (GELF_ST_TYPE(sym.st_info) == STT_FUNC) && sym.st_other)
+-        entrypc += PPC64_LOCAL_ENTRY_OFFSET(sym.st_other);
+-
+       if (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
+         add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
+                    reject, addr, entrypc);
+-- 
+1.8.3.1
+
+From 1b83a55a0272f2eb0bdcd5809fb630e1f369d400 Mon Sep 17 00:00:00 2001
+From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
+Date: Wed, 14 Sep 2016 13:36:00 +0530
+Subject: [PATCH 2/2] ppc64le: Fix LEP usage for probing
+
+PPC64 ELF ABI v2 has a Global Entry Point and a Local Entry Point for
+the functions. Debuginfo of ELF contains GEP which is same as entrypc
+while symbol table contains GEP and offset, from which we can calculate
+LEP. LEP is used to call function within single CU, when TOC pointer
+update is not required. Placing a probe on LEP catches call from both
+the GEP and the LEP but, by default, systemtap probes on GEP.
+
+Commit b4c6a4b1cd00 ("Prioritize symbol table lookup for ppc64le") solve
+this issue by storing LEP in symbol table and prioritizing symbol table
+over debuginfo for ppc64le.
+
+But there are few regression effect of this patch. Couple of examples
+are given below.
+
+1. If target program is compiled without optimization and user is
+interested in function parameter, systemtap should probe after function
+prologue. But above patch forces probe on LEP and which result in garbage
+value of function parameter will get recorded.
+
+  $ make verbose=1 installcheck RUNTESTFLAGS='at_var.exp -v --debug'
+    ...
+    # of expected passes        1
+    # of unexpected failures    1
+
+2. Probe on shared library function with parameter is failing at Pass 2.
+
+  $ make verbose=1 installcheck RUNTESTFLAGS='exelib.exp -v --debug'
+    ...
+    # of expected passes        10
+    # of unexpected failures    64
+
+3. When symbol_name with offset is used to register kprobe, kernel itself
+will find LEP and adds offset to it. Systemtap using LEP to find offset
+is resulting in offset being added two times.
+  GEP + lep_offset (by systemtap) + lep_offset (by kernel)
+
+This can be solved by calculating LEP only at a time of adding a probe.
+That will make effect of LEP local to that area and won't have any
+regression effect.
+
+After applying patch:
+
+  $ make verbose=1 installcheck RUNTESTFLAGS='at_var.exp -v --debug'
+    ...
+    # of expected passes        2
+
+  $ make verbose=1 installcheck RUNTESTFLAGS='exelib.exp -v --debug'
+    ...
+    # of expected passes        74
+
+Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
+---
+ tapsets.cxx | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 59 insertions(+), 1 deletion(-)
+
+diff --git a/tapsets.cxx b/tapsets.cxx
+index a887e1f..30aebb9 100644
+--- a/tapsets.cxx
++++ b/tapsets.cxx
+@@ -1376,6 +1376,59 @@ string path_remove_sysroot(const systemtap_session& sess, const string& path)
+   return retval;
+ }
+ 
++/*
++ * Convert 'Global Entry Point' to 'Local Entry Point'.
++ *
++ * if @gep contains next address after prologue, don't change it.
++ *
++ * For ELF ABI v2 on PPC64 LE, we need to adjust sym.st_value corresponding
++ * to the bits of sym.st_other. These bits will tell us what's the offset
++ * of the local entry point from the global entry point.
++ *
++ * st_other field is currently only used with ABIv2 on ppc64
++ */
++static Dwarf_Addr
++get_lep(dwarf_query *q, Dwarf_Addr gep)
++{
++  Dwarf_Addr bias;
++  Dwfl_Module *mod = q->dw.module;
++  Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
++             ?: dwfl_module_getelf (mod, &bias));
++
++  GElf_Ehdr ehdr_mem;
++  GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
++  if (em == NULL)
++    throw SEMANTIC_ERROR (_("Couldn't get elf header"));
++
++  if (!(em->e_machine == EM_PPC64) || !((em->e_flags & EF_PPC64_ABI) == 2))
++    return gep;
++
++  int syments = dwfl_module_getsymtab(mod);
++  for (int i = 1; i < syments; ++i)
++    {
++      GElf_Sym sym;
++      GElf_Word section;
++      GElf_Addr addr;
++
++#if _ELFUTILS_PREREQ (0, 158)
++      dwfl_module_getsym_info (mod, i, &sym, &addr, &section, NULL, NULL);
++#else
++      dwfl_module_getsym (mod, i, &sym, &section);
++      addr = sym.st_value;
++#endif
++
++      /*
++       * Symbol table contains module_bias + offset. Substract module_bias
++       * to compare offset with gep.
++       */
++      if ((addr - bias) == gep && (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
++          && sym.st_other)
++        return gep + PPC64_LOCAL_ENTRY_OFFSET(sym.st_other);
++    }
++
++  return gep;
++}
++
+ void
+ dwarf_query::add_probe_point(interned_string dw_funcname,
+ 			     interned_string filename,
+@@ -1384,12 +1437,14 @@ dwarf_query::add_probe_point(interned_string dw_funcname,
+ 			     Dwarf_Addr addr)
+ {
+   interned_string reloc_section; // base section for relocation purposes
++  Dwarf_Addr orig_addr = addr;
+   Dwarf_Addr reloc_addr; // relocated
+   interned_string module = dw.module_name; // "kernel" or other
+   interned_string funcname = dw_funcname;
+ 
+   assert (! has_absolute); // already handled in dwarf_builder::build()
+ 
++  addr = get_lep(this, addr);
+   reloc_addr = dw.relocate_address(addr, reloc_section);
+ 
+   // If we originally used the linkage name, then let's call it that way
+@@ -1455,7 +1510,10 @@ dwarf_query::add_probe_point(interned_string dw_funcname,
+ 
+ 	      symbol_table *sym_table = mi->sym_table;
+ 	      func_info *symbol = sym_table->get_func_containing_address(addr);
+-	      Dwarf_Addr offset = addr - symbol->addr;
++
++	      // Do not use LEP to find offset here. When 'symbol_name'
++	      // is used to register probe, kernel itself will find LEP.
++	      Dwarf_Addr offset = orig_addr - symbol->addr;
+ 	      results.push_back (new dwarf_derived_probe(funcname, filename,
+ 							 line, module,
+ 							 reloc_section, addr,
+-- 
+1.8.3.1
+
diff --git a/SPECS/systemtap.spec b/SPECS/systemtap.spec
index 034da44..01f3a55 100644
--- a/SPECS/systemtap.spec
+++ b/SPECS/systemtap.spec
@@ -1,9 +1,12 @@
 %{!?with_sqlite: %global with_sqlite 1}
 %ifarch ppc64le
+# rhbz1252103 = rhbz1243784
 %{!?with_docs: %global with_docs 0}
 %else
 %{!?with_docs: %global with_docs 1}
 %endif
+%{!?with_htmldocs: %global with_htmldocs 0}
+%{!?with_monitor: %global with_monitor 1}
 # crash is not available
 %ifarch ppc ppc64 %{sparc} aarch64 ppc64le
 %{!?with_crash: %global with_crash 0}
@@ -34,6 +37,7 @@
 %{!?with_openssl: %global with_openssl 0}
 %endif
 %{!?with_pyparsing: %global with_pyparsing 0%{?fedora} >= 18 || 0%{?rhel} >= 7}
+%{!?with_python3: %global with_python3 0%{?fedora} >= 23}
 
 %ifarch ppc64le aarch64
 %global with_virthost 0
@@ -60,8 +64,8 @@
 %define dracutstap %{_prefix}/lib/dracut/modules.d/99stap
 
 Name: systemtap
-Version: 2.8
-Release: 10%{?dist}
+Version: 3.0
+Release: 7%{?dist}
 # for version, see also configure.ac
 
 
@@ -108,6 +112,9 @@ BuildRequires: libselinux-devel
 %if %{with_sqlite}
 BuildRequires: sqlite-devel
 %endif
+%if %{with_monitor}
+BuildRequires: json-c-devel ncurses-devel
+%endif
 # Needed for libstd++ < 4.0, without <tr1/memory>
 %if %{with_boost}
 BuildRequires: boost-devel
@@ -127,15 +134,20 @@ BuildRequires: m4
 BuildRequires: elfutils-devel >= %{elfutils_version}
 %endif
 %if %{with_docs}
-BuildRequires: /usr/bin/latex /usr/bin/dvips /usr/bin/ps2pdf latex2html
+BuildRequires: /usr/bin/latex /usr/bin/dvips /usr/bin/ps2pdf
 %if 0%{?fedora} >= 18 || 0%{?rhel} >= 7
-BuildRequires: tex(fullpage.sty) tex(fancybox.sty) tex(bchr7t.tfm)
+BuildRequires: tex(fullpage.sty) tex(fancybox.sty) tex(bchr7t.tfm) tex(graphicx.sty)
 %endif
+# For the html.sty mentioned in the .tex files, even though latex2html is
+# not run during the build, only during manual scripts/update-docs runs:
+BuildRequires: latex2html
+%if %{with_htmldocs}
 # On F10, xmlto's pdf support was broken off into a sub-package,
 # called 'xmlto-tex'.  To avoid a specific F10 BuildReq, we'll do a
 # file-based buildreq on '/usr/share/xmlto/format/fo/pdf'.
 BuildRequires: xmlto /usr/share/xmlto/format/fo/pdf
 %endif
+%endif
 %if %{with_emacsvim}
 BuildRequires: emacs
 %endif
@@ -146,14 +158,18 @@ BuildRequires: jpackage-utils java-devel
 BuildRequires: libvirt-devel >= 1.0.2
 BuildRequires: libxml2-devel
 %endif
+BuildRequires: readline-devel
+%if 0%{?rhel} <= 5
+BuildRequires: ncurses-devel
+%endif
 
-Patch1: rhbz1237098.patch
-Patch2: june-robust.patch
-Patch3: rhbz1242992.patch
-Patch4: rhbz1248159.patch
-Patch5: rhbz1252436.patch
-Patch6: rhbz1254856.patch
-Patch7: rhbz1257399.patch
+Patch10: rhbz1242368.patch
+Patch11: rhbz1346112.patch
+Patch12: rhbz1269062.patch
+Patch13: rhbz1337416.patch
+Patch14: rhbz1365550.patch
+Patch15: rhbz1312169.patch
+Patch16: rhbz1376515.patch
 
 # Install requirements
 Requires: systemtap-client = %{version}-%{release}
@@ -272,8 +288,12 @@ Group: Development/System
 License: GPLv2+ and Public Domain
 URL: http://sourceware.org/systemtap/
 %if %{with_pyparsing}
+%if %{with_python3}
+Requires: python3-pyparsing
+%else
 Requires: pyparsing
 %endif
+%endif
 
 %description sdt-devel
 This package includes the <sys/sdt.h> header file used for static
@@ -299,8 +319,12 @@ Requires: strace
 # 'nmap-ncat'). So, we'll do a file-based require.
 Requires: /usr/bin/nc
 %ifnarch ia64 ppc64le aarch64
+%if 0%{?fedora} >= 21 || 0%{?rhel} >= 8
+# no prelink
+%else
 Requires: prelink
 %endif
+%endif
 # testsuite/systemtap.server/client.exp needs avahi
 Requires: avahi
 %if %{with_crash}
@@ -318,6 +342,10 @@ Requires: /usr/lib/libc.so
 %if 0%{?fedora} >= 18
 Requires: stress
 %endif
+# The following "meta" files for the systemtap examples run "perf":
+#   testsuite/systemtap.examples/hw_watch_addr.meta
+#   testsuite/systemtap.examples/memory/hw_watch_sym.meta
+Requires: perf
 
 %description testsuite
 This package includes the dejagnu-based systemtap stress self-testing
@@ -382,13 +410,6 @@ systemtap-runtime-virthost machine to execute systemtap scripts.
 
 %prep
 %setup -q %{?setup_elfutils}
-%patch1 -p1
-%patch2 -p1
-%patch3 -p1
-%patch4 -p1
-%patch5 -p1
-%patch6 -p1
-%patch7 -p1
 
 %if %{with_bundled_elfutils}
 cd elfutils-%{elfutils_version}
@@ -400,6 +421,14 @@ find . \( -name configure -o -name config.h.in \) -print | xargs touch
 cd ..
 %endif
 
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+
 %build
 
 %if %{with_bundled_elfutils}
@@ -446,7 +475,11 @@ cd ..
 %endif
 
 %if %{with_docs}
-%global docs_config --enable-docs
+%if %{with_htmldocs}
+%global docs_config --enable-docs --enable-htmldocs
+%else
+%global docs_config --enable-docs --disable-htmldocs
+%endif
 %else
 %global docs_config --disable-docs
 %endif
@@ -474,10 +507,18 @@ cd ..
 %if %{with_dracut}
 %global dracut_config --with-dracutstap=%{dracutstap}
 %else
-%global dracut_config
+%global dracut_config %{nil}
+%endif
+
+%if %{with_python3}
+%global python3_config --with-python3
+%else
+%global python3_config --without-python3
 %endif
+# We don't ship compileworthy python code, just oddball samples
+%global py_auto_byte_compile 0
 
-%configure %{?elfutils_config} %{dyninst_config} %{sqlite_config} %{crash_config} %{docs_config} %{pie_config} %{rpm_config} %{java_config} %{virt_config} %{dracut_config} --disable-silent-rules --with-extra-version="rpm %{version}-%{release}"
+%configure %{?elfutils_config} %{dyninst_config} %{sqlite_config} %{crash_config} %{docs_config} %{pie_config} %{rpm_config} %{java_config} %{virt_config} %{dracut_config} %{python3_config} --disable-silent-rules --with-extra-version="rpm %{version}-%{release}"
 make %{?_smp_mflags}
 
 %if %{with_emacsvim}
@@ -488,6 +529,11 @@ make %{?_smp_mflags}
 rm -rf ${RPM_BUILD_ROOT}
 make DESTDIR=$RPM_BUILD_ROOT install
 %find_lang %{name}
+for dir in $(ls -1d $RPM_BUILD_ROOT%{_mandir}/{??,??_??}) ; do
+    dir=$(echo $dir | sed -e "s|^$RPM_BUILD_ROOT||")
+    lang=$(basename $dir)
+    echo "%%lang($lang) $dir/man*/*" >> %{name}.lang
+done
 
 # We want the examples in the special doc dir, not the build install dir.
 # We build it in place and then move it away so it doesn't get installed
@@ -495,8 +541,8 @@ make DESTDIR=$RPM_BUILD_ROOT install
 # %doc directive.
 mv $RPM_BUILD_ROOT%{_datadir}/doc/systemtap/examples examples
 
-# Fix paths in the example & testsuite scripts
-find examples testsuite -type f -name '*.stp' -print0 | xargs -0 sed -i -r -e '1s@^#!.+stap@#!%{_bindir}/stap@'
+# Fix paths in the example scripts.
+find examples -type f -name '*.stp' -print0 | xargs -0 sed -i -r -e '1s@^#!.+stap@#!%{_bindir}/stap@'
 
 # To make rpmlint happy, remove any .gitignore files in the testsuite.
 find testsuite -type f -name '.gitignore' -print0 | xargs -0 rm -f
@@ -520,9 +566,11 @@ cp -rp testsuite $RPM_BUILD_ROOT%{_datadir}/systemtap
 # %doc directive.
 mkdir docs.installed
 mv $RPM_BUILD_ROOT%{_datadir}/doc/systemtap/*.pdf docs.installed/
+%if %{with_htmldocs}
 mv $RPM_BUILD_ROOT%{_datadir}/doc/systemtap/tapsets docs.installed/
 mv $RPM_BUILD_ROOT%{_datadir}/doc/systemtap/SystemTap_Beginners_Guide docs.installed/
 %endif
+%endif
 
 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/stap-server
 mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/stap-server
@@ -631,11 +679,6 @@ test -e %{_localstatedir}/log/stap-server/log || {
      chmod 644 %{_localstatedir}/log/stap-server/log
      chown stap-server:stap-server %{_localstatedir}/log/stap-server/log
 }
-# If it does not already exist, as stap-server, generate the certificate
-# used for signing and for ssl.
-if test ! -e ~stap-server/.systemtap/ssl/server/stap.cert; then
-   runuser -s /bin/sh - stap-server -c %{_libexecdir}/systemtap/stap-gen-cert >/dev/null
-fi
 # Prepare the service
 %if %{with_systemd}
      # Note, Fedora policy doesn't allow network services enabled by default
@@ -780,7 +823,7 @@ exit 0
 %triggerin runtime-java -- java-1.8.0-openjdk, java-1.7.0-openjdk, java-1.6.0-openjdk
 for f in %{_libexecdir}/systemtap/libHelperSDT_*.so; do
     %ifarch %{ix86}
-        arch=i386
+	arch=i386
     %else
         arch=`basename $f | cut -f2 -d_ | cut -f1 -d.`
     %endif
@@ -795,7 +838,7 @@ done
 %triggerun runtime-java -- java-1.8.0-openjdk, java-1.7.0-openjdk, java-1.6.0-openjdk
 for f in %{_libexecdir}/systemtap/libHelperSDT_*.so; do
     %ifarch %{ix86}
-        arch=i386
+	arch=i386
     %else
         arch=`basename $f | cut -f2 -d_ | cut -f1 -d.`
     %endif
@@ -809,7 +852,7 @@ done
 # Restore links for any JDKs remaining after a package removal:
 for f in %{_libexecdir}/systemtap/libHelperSDT_*.so; do
     %ifarch %{ix86}
-    	arch=i386
+	arch=i386
     %else
         arch=`basename $f | cut -f2 -d_ | cut -f1 -d.`
     %endif
@@ -933,9 +976,11 @@ done
 %license COPYING
 %if %{with_docs}
 %doc docs.installed/*.pdf
+%if %{with_htmldocs}
 %doc docs.installed/tapsets/*.html
 %doc docs.installed/SystemTap_Beginners_Guide
 %endif
+%endif
 %{_bindir}/stap
 %{_bindir}/stap-prep
 %{_bindir}/stap-report
@@ -1022,6 +1067,29 @@ done
 #   http://sourceware.org/systemtap/wiki/SystemTapReleases
 
 %changelog
+* Mon Sep 19 2016 Frank Ch. Eigler <fche@redhat.com> - 3.0-7
+- rhbz1376515 ppc64le probe point / parameter value fix
+
+* Wed Aug 24 2016 Frank Ch. Eigler <fche@redhat.com> - 3.0-6
+- rhbz1346112 delay tls cert creation redux
+
+* Thu Aug 11 2016 Frank Ch. Eigler <fche@redhat.com> - 3.0-5
+- rhbz1312169 stap-prep debuginfo-install improvement
+
+* Tue Aug 09 2016 Frank Ch. Eigler <fche@redhat.com> - 3.0-4
+- rhbz1365550 PR19874 alarm(60) in staprun system()
+
+* Thu Jul 21 2016 Frank Ch. Eigler <fche@redhat.com> - 3.0-3
+- rhbz1346112 delay tls cert creation
+- rhbz1269062 null elevator
+- rhbz1337416 'count' tapset variable - autocast/@defined
+
+* Wed May 04 2016 Frank Ch. Eigler <fche@redhat.com> - 3.0-2
+- 4 upstream patches for kernel lockdep hygiene, bz1242368
+
+* Tue May 03 2016 Frank Ch. Eigler <fche@redhat.com> - 3.0-1
+- Upstream release.
+
 * Wed Sep 02 2015 Frank Ch. Eigler <fche@redhat.com> - 2.8-10
 - rhbz1257399: module-init probes