# perf script event handlers, generated by perf script -g python
# Licensed under the terms of the GNU GPL License version 2

# The common_* event handler fields are the most useful fields common to
# all events.  They don't necessarily correspond to the 'common_*' fields
# in the format files.  Those fields not available as handler params can
# be retrieved using Python functions of the form common_*(context).
# See the perf-script-python Documentation for the list of available functions.

# TODO: handlers for filters + postordinate parser fails to get named

from __future__ import print_function

import os
import sys

sys.path.append(os.environ['PERF_EXEC_PATH'] + \
	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')

from perf_trace_context import *
from Core import *

from collections import defaultdict

# NOTE: Parsers are uniquely identified by their address in memory
# The memory use is further split up along different arenas

class Parser:
	#TODO: remove
	_parser_names = {}

	def __init__(self, name, address):
		self.name = name
		self.address = address
		self.bytes_used = {}
	
	def name_parser(self, name):
		#if self.address not in Parser._parser_names:
		#	Parser._parser_names[self.address] = name
		self.name = name

	def get_name_or_placeholder(self):
		if self.name is None:
			return "Wait for it... (if you're reading this, you found a bug)"
		else:
			return self.name

	def add_mem_use(self, state, size):
		if bytes_used.setdefault(state, None) is None:
			bytes_used[state] = size
		else:
			bytes_used[state] += size

	def get_mem_use(self, state=None):
		if state is None:
			return bytes_used
		else:
			return bytes_used.setdefault(state, 0)

class ParserStack:
	def __init__(self, parse_state, arena):
		self.parse_state = parse_state
		self.arena = arena
		self.p_stack = []

	def push(self, parser):
		self.p_stack.append(parser)

	def pop(self):
		return self.p_stack.pop()

	def peek(self):
		return self.p_stack[-1]

	def set_state(self, state):
		self.parse_state = state
	# Shortcut for setting the name property of the parser on the top of stack
	# In terms of tracing, *most* calls to a parser look something like this with the packrat backend:
	# h_do_parse()
	#	parse_foo()
	#		perform_lowlevel_parse()
	
	# perform_lowlevel_parse() is called when the memo table at that position is not filled in yet.
	# it calls the corresponding parse_* virtual function via the vtable, but other than that does not have type information
	# it's probably possible to extract type information, by comparing vtable addresses, but that seems painful
	
	# parse_foo() is the parser's corresponding virtual function in the frontend, which does not have the equivalent of a "this" pointer
	
	# So what we do to keep track of parsers is incrementally filling in the details for both
	
	# h_do_parse() is the backend's "actually run the parser" function, but does not get called for some parsers
	# (my intuition says that it gets called only for higher-order parsers)
	# also contains the decision logic about whether to call perform_lowlevel_parse()
	
	# possible scenarios:
	# h_do_parse()
	#	perform_lowlevel_parse()
	#		parse_foo()
	
	# h_do_parse()
	#	perform_lowlevel_parse()

	# h_do_parse()
	def name_top_parser(self, name):
		self.p_stack[-1].name_parser(name)

	def add_mem_use_each(self, size):
		for p in self.p_stack:
			p.bytes_used += size

	def add_mem_use_top(self, size):
		self.p_stack[-1].bytes_used += size
		
	def show_stack(self):
		print("stack would be printed here. Depth:", len(self.p_stack))
		#print([(p.get_name_or_placeholder(), hex(p.address)) for p in self.p_stack])

	def depth(self):
		return len(self.p_stack)

#parserStack = ParserStack(0,0)

# Class that is responsible for bookkeeping throughout the entire parse
# NB, this is slightly different terminology than the hammer API implicitly uses:
# There, a parse is started by h_parse(), and it is associated with a parse state.
# This corresponds to the ParserStack above.
# Subsequent h_do_parse()s with the same parser state belong to the same parse

# The TopLevelParse class is initialized in trace_begin(), and is used until the end of the trace
class TopLevelParse:
	def __init__(self):
		self.parser_stacks = []
		self.parser_objs = {}

	# Called from h_packrat_parse()'s handler, where the parse state and arena get initialized
	def enter_h_packrat_parse(self, parser):
		# TODO: add a parser stack or something?
		parser_stack = ParserStack(None, None)
		self.parser_stacks.append(parser_stack)
		return 0

	def enter_h_do_parse(self, parse_state, arena, parser):
		parser_stack = self.peek_parserstack()
		if parser_stack.parse_state is None and parser_stack.parse_state != parse_state:
			self.first_h_do_parse_after_packrat_parse(parse_state, arena)

	# Called from h_do_parse()'s handler, at which point we know the addresses of the state and arena
	def first_h_do_parse_after_packrat_parse(self, parse_state, arena):
		parser_stack = self.peek_parserstack()
		parser_stack.set_state(parse_state)

	# Popping the stack of stack of parsers
	def return_from_h_packrat_parse(self):
		old_stack = self.parser_stacks.pop()
		if old_stack.depth() > 0:
			print("Warning: parser stack not empty but parse is successful?")
		# TODO: capture the return value in the probe, so we can tell if the parse was successful

	# Memoize the parser object for this particular address, then push it on the stack
	# Returns the parser object we just initalized (or the one already existing)
	def enter_perform_lowlevel_parse(self, parser_addr):
		try:
			parser_obj = self.parser_objs[parser_addr]
		except KeyError:
			# Create a parser object with no name and the address of the parser
			parser_obj = Parser(None, parser_addr)
			self.parser_objs[parser_addr] = parser_obj

		parser_stack = self.peek_parserstack()
		parser_stack.push(parser_obj)
		return parser_obj

	def return_from_perform_lowlevel_parse(self):
		parser_stack = self.peek_parserstack()
		parser_obj = parser_stack.pop()
		# debug print here

	def parse_virtual(self, parser_name):
		parser_obj = self.peek_parser()
		if parser_obj.name and parser_obj.name != parser_name:
			print("Warning: parser already named! This is a bug. old name: %s, new name: %s" % (parser_obj.name, parser_name))

		parser_obj.name_parser(parser_name)

	def peek_parserstack(self):
		# TODO: handle empty stack
		return self.parser_stacks[-1]

	def peek_parser(self):
		return self.parser_stacks[-1].peek()

#TODO: refactor memory use code into TopLevelParse, as well as using the Parser objects to hold memory use

mem_use = {}
top_level_parse = TopLevelParse()

def get_mem_use(parser, arena):
	global mem_use
	return mem_use[parser].setdefault(arena, 0)

def add_mem_use(parser, arena, size):
	global mem_use
	try:
		mem_use[parser].setdefault(arena, 0)
		mem_use[parser][arena] += size
	except KeyError as e:
		#print("parser: ")
		#print(parser)
		#print("arena: ")
		#print(arena)
		#print("size: ")
		#print(size)
		return

def trace_begin():
	global mem_use
	print("in trace_begin")
	mem_use = defaultdict(dict)

def trace_end():
	global mem_use
	global parserObjs
	print("in trace_end")
	#print(mem_use)
	#print(mem_use.items())
	#for k,v in parserObjs.items():
	#	print("Address: %x, Parser: " % k, v)
	'''for parser,stats in mem_use.items():
		print("Parser:")
		if parser != None:
			print(parsers[parser])
		print("Stats:")
		print(stats)'''

def probe_pdf__init_parser(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, pdf, tail, xr_td,
	dict_p, dict_, dopen, body, header,
	objdef, indobj, obj, array, array_,
	lbrack, rbrack, elemd, elemd_, elemr,
	elemr_, robj, dobj, name, npair,
	string, hexstr, rangle, langle, litstr,
	stream, xrstm, xstream, xrefs, xrsub,
	xrhead, xrent, xrgen, xroff, a85string,
	ahexstream, k_v, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, pdf=%u, tail=%u, " \
		"xr_td=%u, dict=%u, dict_=%u, " \
		"dopen=%u, body=%u, header=%u, " \
		"objdef=%u, indobj=%u, obj=%u, " \
		"array=%u, array_=%u, lbrack=%u, " \
		"rbrack=%u, elemd=%u, elemd_=%u, " \
		"elemr=%u, elemr_=%u, robj=%u, " \
		"dobj=%u, name=%u, npair=%u, " \
		"string=%u, hexstr=%u, rangle=%u, " \
		"langle=%u, litstr=%u, stream=%u, " \
		"xrstm=%u, xstream=%u, xrefs=%u, " \
		"xrsub=%u, xrhead=%u, xrent=%u, " \
		"xrgen=%u, xroff=%u, a85string=%u, " \
		"ahexstream=%u" % \
		(__probe_ip, pdf, tail, xr_td,
		dict_p, dict_, dopen, body, header,
		objdef, indobj, obj, array, array_,
		lbrack, rbrack, elemd, elemd_, elemr,
		elemr_, robj, dobj, name, npair,
		string, hexstr, rangle, langle, litstr,
		stream, xrstm, xstream, xrefs, xrsub,
		xrhead, xrent, xrgen, xroff, a85string,
		ahexstream))

		top_level_parse.parser_objs[pdf] = Parser('pdf', pdf)
		top_level_parse.parser_objs[tail] = Parser('tail', tail)
		top_level_parse.parser_objs[xr_td] = Parser('xr_td', xr_td)
		top_level_parse.parser_objs[dict_p] = Parser('dict', dict_p)
		top_level_parse.parser_objs[dict_] = Parser('dict_', dict_)
		top_level_parse.parser_objs[dopen] = Parser('dopen', dopen)
		top_level_parse.parser_objs[body] = Parser('body', body)
		top_level_parse.parser_objs[header] = Parser('header', header)
		top_level_parse.parser_objs[objdef] = Parser('objdef', objdef)
		top_level_parse.parser_objs[indobj] = Parser('indobj', indobj)
		top_level_parse.parser_objs[obj] = Parser('obj', obj)
		top_level_parse.parser_objs[array] = Parser('array', array)
		top_level_parse.parser_objs[array_] = Parser('array_', array_)
		top_level_parse.parser_objs[lbrack] = Parser('lbrack', lbrack)
		top_level_parse.parser_objs[elemd] = Parser('elemd', elemd)
		top_level_parse.parser_objs[elemd_] = Parser('elemd_', elemd_)
		top_level_parse.parser_objs[elemr] = Parser('elemr', elemr)
		top_level_parse.parser_objs[elemr_] = Parser('elemr_', elemr_)
		top_level_parse.parser_objs[robj] = Parser('robj', robj)
		top_level_parse.parser_objs[dobj] = Parser('dobj', dobj)
		top_level_parse.parser_objs[name] = Parser('name', name)
		top_level_parse.parser_objs[npair] = Parser('npair', npair)
		top_level_parse.parser_objs[string] = Parser('string', string)
		top_level_parse.parser_objs[hexstr] = Parser('hexstr', hexstr)
		top_level_parse.parser_objs[rangle] = Parser('rangle', rangle)
		top_level_parse.parser_objs[langle] = Parser('langle', langle)
		top_level_parse.parser_objs[litstr] = Parser('litstr', litstr)
		top_level_parse.parser_objs[stream] = Parser('stream', stream)
		top_level_parse.parser_objs[xrstm] = Parser('xrstm', xrstm)
		top_level_parse.parser_objs[xstream] = Parser('xstream', xstream)
		top_level_parse.parser_objs[xrefs] = Parser('xrefs', xrefs)
		top_level_parse.parser_objs[xrsub] = Parser('xrsub', xrsub)
		top_level_parse.parser_objs[xrhead] = Parser('stream', stream)
		top_level_parse.parser_objs[xrent] = Parser('xrent', xrent)
		top_level_parse.parser_objs[xrgen] = Parser('xrgen', xrgen)
		top_level_parse.parser_objs[xroff] = Parser('xroff', xroff)
		top_level_parse.parser_objs[a85string] = Parser('a85string', a85string)
		top_level_parse.parser_objs[ahexstream] = Parser('ahexstream', ahexstream)
		top_level_parse.parser_objs[k_v] = Parser('k_v', k_v)

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__h_do_parse(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, parser, state, arena,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		top_level_parse.enter_h_do_parse(state, arena, parser)
		try:
			parsername = top_level_parse.parser_objs[parser].name
		except KeyError:
			parsername = "unknown"

		print("__probe_ip=%u, parser=%s (%u), state=%u, " \
		"arena=%u" % \
		(__probe_ip, parsername, parser, state, arena))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__h_do_parse__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, parser, state, retval,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u, parser=%u, " \
		"state=%u, retval=%u" % \
		(__probe_func, __probe_ret_ip, parser, state, retval))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))
		print()

def probe_libhammer__h_arena_malloc_raw(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, arena, size, need_zero,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, arena=%u, size=%u, " \
		"need_zero=%u" % \
		(__probe_ip, arena, size, need_zero))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		#for node in common_callchain:
		#	if 'sym' in node:
		#		print("\t[%x] %s" % (node['ip'], node['sym']['name']))
		#	else:
		#		print("	[%x]" % (node['ip']))

		#print()
		#add_mem_use(top_level_parse.peek_parser(), arena, size)
		return

def probe_libhammer__parse_choice(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, s,
	i, p_array, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"s=%u, i=%u, p_array=%u" % \
		(__probe_ip, env, state, s,
		i, p_array))
		
		top_level_parse.parse_virtual("(Unnamed choice)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_sequence(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, s,
	p_array, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"s=%u, p_array=%u" % \
		(__probe_ip, env, state, s,
		p_array))

		top_level_parse.parse_virtual("(Unnamed sequence)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_difference(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, parsers,
	p1, p2, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"parsers=%u, p1=%u, p2=%u" % \
		(__probe_ip, env, state, parsers,
		p1, p2))

		top_level_parse.parse_virtual("(Unnamed difference)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_action(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, a,
	p, action, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"a=%u, p=%u, action=%u" % \
		(__probe_ip, env, state, a,
		p, action))

		top_level_parse.parse_virtual("(Unnamed action)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_and(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed and)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_attr_bool(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed attr_bool)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_bind(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, be_, state, p, 
	k, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, be_=%u, state=%u, " \
		"p=%u, k=%u" % \
		(__probe_ip, be_, state, p, 
		k))

		top_level_parse.parse_virtual("(Unnamed bind/h_indirect)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_bits(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed bits)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_butnot(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, parsers, 
	p1, p2, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"parsers=%u, p1=%u, p2=%u" % \
		(__probe_ip, env, state, parsers,
		p1, p2))

		top_level_parse.parse_virtual("(Unnamed butnot)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_charset(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed charset (%x))" % env)
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_ch(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, c, 
		perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"c=%u" % \
		(__probe_ip, env, state, c))
		
		top_level_parse.parse_virtual("(Unnamed ch (%s))" % c)
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_end(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed end)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_endianness(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, endianness, 
		perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"endianness=%d" % \
		(__probe_ip, env, state, endianness))

		top_level_parse.parse_virtual("(Unnamed endianness)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_epsilon(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed epsilon)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_ignore(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))
		
		top_level_parse.parse_virtual("(Unnamed ignore)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_ignoreseq(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed ignoreseq)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_indirect(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed indirect)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_int_range(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, p, 
	lower, upper, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"p=%u, lower=%d, upper=%d" % \
		(__probe_ip, env, state, p,
		lower, upper))

		top_level_parse.parse_virtual("(Unnamed int_range (%u %u))" % (lower,upper))
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_many(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, env_, 
	p, sep, count, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"env_=%u, p=%u, sep=%u, " \
		"count=%u" % \
		(__probe_ip, env, state, env_,
		p, sep, count))

		top_level_parse.parse_virtual("(Unnamed many)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_not(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed not)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_nothing(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, x, y, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, x=%u, y=%u" % \
		(__probe_ip, x, y))

		top_level_parse.parse_virtual("(Unnamed nothing)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_optional(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed optional)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_permutation(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, s, 
	s_len, p_array, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"s=%u, s_len=%u, p_array=%u" % \
		(__probe_ip, env, state, s,
		s_len, p_array))

		top_level_parse.parse_virtual("(Unnamed permutation)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_skip(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, n, 
		perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"n=%u" % \
		(__probe_ip, env, state, n))

		top_level_parse.parse_virtual("(Unnamed skip)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_seek(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, s, 
		perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"s=%u" % \
		(__probe_ip, env, state, s))

		top_level_parse.parse_virtual("(Unnamed seek)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_tell(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed tell)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_token(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed token)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_unimplemented(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed unimplemented)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_put(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed put)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_get(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed get)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_whitespace(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u" % \
		(__probe_ip, env, state))

		top_level_parse.parse_virtual("(Unnamed whitespace)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_xor(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, env, state, parsers, 
	p1, p2, perf_sample_dict):
		print()
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, env=%u, state=%u, " \
		"parsers=%u, p1=%u, p2=%u" % \
		(__probe_ip, env, state, parsers, 
		p1, p2))

		top_level_parse.parse_virtual("(Unnamed xor)")
		new_parser = top_level_parse.peek_parser()


		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_pdf__init_runlengthdecode_parser(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, aux, rldeod, longlength,
	shortlength, shortdata, longdata, shortrun, longrun,
	rldstring, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, aux=%u, rldeod=%u, " \
		"longlength=%u, shortlength=%u, shortdata=%u, " \
		"longdata=%u, shortrun=%u, longrun=%u, " \
		"rldstring=%u" % \
		(__probe_ip, aux, rldeod, longlength,
		shortlength, shortdata, longdata, shortrun, longrun,
		rldstring))

		# TODO: use TopLevelParse() to memoize addresses
		#parsers[rldeod] = 'rldeod'
		#parsers[longlength] = 'longlength'
		#parsers[shortlength] = 'shortdata'
		#parsers[longdata] = 'longdata'
		#parsers[shortrun] = 'shortrun'
		#parsers[longrun] = 'longrun'
		#parsers[rldstring] = 'rldstring'

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_pdf__kstream(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, mm__, x, env,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, mm__=%u, x=%u, " \
		"env=%u" % \
		(__probe_ip, mm__, x, env))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_pdf__kxstream(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, mm__, x, env,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, mm__=%u, x=%u, " \
		"env=%u" % \
		(__probe_ip, mm__, x, env))

		p#rint('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_pdf__FlateDecode(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, parms, b, p,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, parms=%u, b=%u, " \
		"p=%u" % \
		(__probe_ip, parms, b, p))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_pdf__LZWDecode(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, parms, b, p,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, parms=%u, b=%u, " \
		"p=%u" % \
		(__probe_ip, parms, b, p))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_pdf__RunLengthDecode(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, parms, b, p,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, parms=%u, b=%u, " \
		"p=%u" % \
		(__probe_ip, parms, b, p))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_pdf__ASCII85Decode(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, parms, b, p,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, parms=%u, b=%u, " \
		"p=%u" % \
		(__probe_ip, parms, b, p))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_pdf__ASCIIHexDecode(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, parms, b, p,
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, parms=%u, b=%u, " \
		"p=%u" % \
		(__probe_ip, parms, b, p))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

# Currently these are not useful but may become useful later
def probe_libhammer__parse_sequence__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_difference__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_many__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_action__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_and__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_attr_bool__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_bind__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_bits__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_butnot__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_charset__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_ch__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_choice__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_end__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_endianness__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_epsilon__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def probe_libhammer__parse_ignore__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_ignoreseq__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_indirect__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_int_range__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_not__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_nothing__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_optional__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_permutation__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_skip__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_seek__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_tell__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_token__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_unimplemented__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_put__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_get__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_whitespace__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__parse_xor__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u" % \
		(__probe_func, __probe_ret_ip))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__perform_lowlevel_parse(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, state, parser, arena, 
	env, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, state=%u, parser=%u, " \
		"arena=%u, env=%u" % \
		(__probe_ip, state, parser, arena, 
		env))
		
		new_parser = top_level_parse.enter_perform_lowlevel_parse(parser)
		top_level_parse.peek_parserstack().show_stack()

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__perform_lowlevel_parse__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, retval, perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u, retval=%u" % \
		(__probe_func, __probe_ret_ip, retval))

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		top_level_parse.return_from_perform_lowlevel_parse()
		top_level_parse.peek_parserstack().show_stack()

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__h_packrat_parse(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_ip, mm__, parser, input_stream, 
		perf_sample_dict):
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_ip=%u, mm__=%u, parser=%u, " \
		"input_stream=%u" % \
		(__probe_ip, mm__, parser, input_stream))
		
		# We only have partial information here. Specifically, the HParseState
		# gets initialized here
		# Possibly it can be captured by the h_packrat_parse probe, but it needs more testing
		top_level_parse.enter_h_packrat_parse(parser)

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		print()

def probe_libhammer__h_packrat_parse__return(event_name, context, common_cpu,
	common_secs, common_nsecs, common_pid, common_comm,
	common_callchain, __probe_func, __probe_ret_ip, retval, perf_sample_dict):
		global parserStateStack
		global parserStack
		print_header(event_name, common_cpu, common_secs, common_nsecs,
			common_pid, common_comm)

		print("__probe_func=%u, __probe_ret_ip=%u, retval=%u" % \
		(__probe_func, __probe_ret_ip, retval))
		
		# TODO: suspended parsers also need tracepoints (h_parse_start), but packrat doesn't support them
		# so it's out of scope for now

		#oldParserStacks.append(parserStack)
		top_level_parse.return_from_h_packrat_parse()
		#print(parserStateStack)
		#print(parserStack)
		#parserStateStack.pop()
		#if len(parserStateStack) > 0:
			#parserStack = parserStateStack[-1]
		#print([(ps, ps.parse_state) for ps in parserStateStack])

		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

		for node in common_callchain:
			if 'sym' in node:
				print("\t[%x] %s" % (node['ip'], node['sym']['name']))
			else:
				print("	[%x]" % (node['ip']))

		#print()

def trace_unhandled(event_name, context, event_fields_dict, perf_sample_dict):
		dummyvaar = event_name
		#print(event_name)
		print(get_dict_as_string(event_fields_dict))
		#print('Sample: {'+get_dict_as_string(perf_sample_dict['sample'], ', ')+'}')

def print_header(event_name, cpu, secs, nsecs, pid, comm):
	print("%-20s %5u %05u.%09u %8u %-20s " % \
	(event_name, cpu, secs, nsecs, pid, comm), end="")

def get_dict_as_string(a_dict, delimiter=' '):
	return delimiter.join(['%s=%s'%(k,str(v))for k,v in sorted(a_dict.items())])