#!/usr/bin/python

#
#  Copyright (c) 2014, ARM Limited. All rights reserved.
#
#  This program and the accompanying materials
#  are licensed and made available under the terms and conditions of the BSD License
#  which accompanies this distribution.  The full text of the license may be found at
#  http://opensource.org/licenses/bsd-license.php
#
#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

import getopt
import operator
import os
import pickle
import sys
from sys import argv
from cStringIO import StringIO

modules = {}
functions = {}
functions_addr = {}

def usage():
	print "-t,--trace: Location of the Trace file"
	print "-s,--symbols: Location of the symbols and modules"

def get_address_from_string(address):
	return int(address.strip("S:").strip("N:").strip("EL2:").strip("EL1:"), 16)

def get_module_from_addr(modules, addr):
	for key,value in modules.items():
		if (value['start'] <= addr) and (addr <= value['end']):
			return key
	return None

def add_cycles_to_function(functions, func_name, addr, cycles):
	if func_name != "<Unknown>":
		# Check if we are still in the previous function
		if add_cycles_to_function.prev_func_name == func_name:
			add_cycles_to_function.prev_entry['cycles'] += cycles
			return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)

		if func_name in functions.keys():
			for module_name, module_value in functions[func_name].iteritems():
				if (module_value['start'] <= addr) and (addr < module_value['end']):
					module_value['cycles'] += cycles

					add_cycles_to_function.prev_func_name   = func_name
					add_cycles_to_function.prev_module_name = module_name
					add_cycles_to_function.prev_entry       = module_value
					return (func_name, module_name)
				elif (module_value['end'] == 0):
					module_value['cycles'] += cycles

					add_cycles_to_function.prev_func_name   = func_name
					add_cycles_to_function.prev_module_name = module_name
					add_cycles_to_function.prev_entry       = module_value
					return (func_name, module_name)

		# Workaround to fix the 'info func' limitation that does not expose the 'static' function
		module_name = get_module_from_addr(modules, addr)
		functions[func_name] = {}
		functions[func_name][module_name] = {}
		functions[func_name][module_name]['start']  = 0
		functions[func_name][module_name]['end']    = 0
		functions[func_name][module_name]['cycles'] = cycles
		functions[func_name][module_name]['count']  = 0

		add_cycles_to_function.prev_func_name   = func_name
		add_cycles_to_function.prev_module_name = module_name
		add_cycles_to_function.prev_entry       = functions[func_name][module_name]
		return (func_name, module_name)
	else:
		# Check if we are still in the previous function
		if (add_cycles_to_function.prev_entry is not None) and (add_cycles_to_function.prev_entry['start'] <= addr) and (addr < add_cycles_to_function.prev_entry['end']):
			add_cycles_to_function.prev_entry['cycles'] += cycles
			return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)

		# Generate the key for the given address
		key = addr & ~0x0FFF

		if key not in functions_addr.keys():
			if 'Unknown' not in functions.keys():
				functions['Unknown'] = {}
			if 'Unknown' not in functions['Unknown'].keys():
				functions['Unknown']['Unknown'] = {}
				functions['Unknown']['Unknown']['cycles'] = 0
				functions['Unknown']['Unknown']['count'] = 0
			functions['Unknown']['Unknown']['cycles'] += cycles

			add_cycles_to_function.prev_func_name = None
			return None

		for func_key, module in functions_addr[key].iteritems():
			for module_key, module_value in module.iteritems():
				if (module_value['start'] <= addr) and (addr < module_value['end']):
					module_value['cycles'] += cycles

					# In case o <Unknown> we prefer to fallback on the direct search
					add_cycles_to_function.prev_func_name   = func_key
					add_cycles_to_function.prev_module_name = module_key
					add_cycles_to_function.prev_entry       = module_value
					return (func_key, module_key)

	print "Warning: Function %s @ 0x%x not found" % (func_name, addr)

	add_cycles_to_function.prev_func_name = None
	return None

# Static variables for the previous function
add_cycles_to_function.prev_func_name = None
add_cycles_to_function.prev_entry     = None

def trace_read():
	global trace_process
	line = trace.readline()
	trace_process += len(line)
	return line

#
# Parse arguments
#
trace_name = None
symbols_file = None

opts,args = getopt.getopt(sys.argv[1:], "ht:vs:v", ["help","trace=","symbols="])
if (opts is None) or (not opts):
	usage()
	sys.exit()

for o,a in opts:
    if o in ("-h","--help"):
        usage()
        sys.exit()
    elif o in ("-t","--trace"):
        trace_name = a
    elif o in ("-s","--symbols"):
        symbols_file = a
    else:
        assert False, "Unhandled option (%s)" % o

#
# We try first to see if we run the script from DS-5
#
try:
	from arm_ds.debugger_v1 import Debugger
	from arm_ds.debugger_v1 import DebugException

	# Debugger object for accessing the debugger
	debugger = Debugger()

	# Initialisation commands
	ec = debugger.getExecutionContext(0)
	ec.getExecutionService().stop()
	ec.getExecutionService().waitForStop()
	# in case the execution context reference is out of date
	ec = debugger.getExecutionContext(0)

	#
	# Get the module name and their memory range
	#
	info_file = ec.executeDSCommand("info file")
	info_file_str = StringIO(info_file)

	line = info_file_str.readline().strip('\n')
	while line != '':
		if ("Symbols from" in line):
			# Get the module name from the line 'Symbols from "/home/...."'
			module_name = line.split("\"")[1].split("/")[-1]
			modules[module_name] = {}

			# Look for the text section
			line = info_file_str.readline().strip('\n')
			while (line != '') and ("Symbols from" not in line):
				if ("ER_RO" in line):
					modules[module_name]['start'] = get_address_from_string(line.split()[0])
					modules[module_name]['end']   = get_address_from_string(line.split()[2])
					line = info_file_str.readline().strip('\n')
					break;
				if (".text" in line):
					modules[module_name]['start'] = get_address_from_string(line.split()[0])
					modules[module_name]['end']   = get_address_from_string(line.split()[2])
					line = info_file_str.readline().strip('\n')
					break;
				line = info_file_str.readline().strip('\n')
		line = info_file_str.readline().strip('\n')

	#
	# Get the function name and their memory range
	#
	info_func = ec.executeDSCommand("info func")
	info_func_str = StringIO(info_func)

	# Skip the first line 'Low-level symbols ...'
	line = info_func_str.readline().strip('\n')
	func_prev = None
	while line != '':
		# We ignore all the functions after 'Functions in'
		if ("Functions in " in line):
			line = info_func_str.readline().strip('\n')
			while line != '':
				line = info_func_str.readline().strip('\n')
			line = info_func_str.readline().strip('\n')
			continue

		if ("Low-level symbols" in line):
			# We need to fixup the last function of the module
			if func_prev is not None:
				func_prev['end'] = modules[module_name]['end']
				func_prev = None

			line = info_func_str.readline().strip('\n')
			continue

		func_name = line.split()[1]
		func_start = get_address_from_string(line.split()[0])
		module_name = get_module_from_addr(modules, func_start)

		if func_name not in functions.keys():
			functions[func_name] = {}
		functions[func_name][module_name] = {}
		functions[func_name][module_name]['start'] = func_start
		functions[func_name][module_name]['cycles'] = 0
		functions[func_name][module_name]['count'] = 0

		# Set the end address of the previous function
		if func_prev is not None:
			func_prev['end'] = func_start
		func_prev = functions[func_name][module_name]

		line = info_func_str.readline().strip('\n')

	# Fixup the last function
	func_prev['end'] = modules[module_name]['end']

	if symbols_file is not None:
		pickle.dump((modules, functions), open(symbols_file, "w"))
except:
	if symbols_file is None:
		print "Error: Symbols file is required when run out of ARM DS-5"
		sys.exit()

	(modules, functions) = pickle.load(open(symbols_file, "r"))

#
# Build optimized table for the <Unknown> functions
#
functions_addr = {}
for func_key, module in functions.iteritems():
	for module_key, module_value in module.iteritems():
		key = module_value['start'] & ~0x0FFF
		if key not in functions_addr.keys():
			functions_addr[key] = {}
		if func_key not in functions_addr[key].keys():
			functions_addr[key][func_key] = {}
		functions_addr[key][func_key][module_key] = module_value

#
# Process the trace file
#
if trace_name is None:
	sys.exit()

trace = open(trace_name, "r")
trace_size = os.path.getsize(trace_name)
trace_process = 0

# Get the column names from the first line
columns = trace_read().split()
column_addr     = columns.index('Address')
column_cycles   = columns.index('Cycles')
column_function = columns.index('Function')

line = trace_read()
i = 0
prev_callee = None
while line:
	try:
		func_name = line.split('\t')[column_function].strip()
		address   = get_address_from_string(line.split('\t')[column_addr])
		cycles    = int(line.split('\t')[column_cycles])
		callee = add_cycles_to_function(functions, func_name, address, cycles)
		if (prev_callee != None) and (prev_callee != callee):
			functions[prev_callee[0]][prev_callee[1]]['count'] += 1
		prev_callee = callee
	except ValueError:
		pass
	line = trace_read()
	if ((i % 1000000) == 0) and (i != 0):
		percent = (trace_process * 100.00) / trace_size
		print "Processing file ... (%.2f %%)" % (percent)
	i = i + 1

# Fixup the last callee
functions[prev_callee[0]][prev_callee[1]]['count'] += 1

#
# Process results
#
functions_cycles     = {}
all_functions_cycles = {}
total_cycles         = 0

for func_key, module in functions.iteritems():
	for module_key, module_value in module.iteritems():
		key = "%s/%s" % (module_key, func_key)
		functions_cycles[key] = (module_value['cycles'], module_value['count'])
		total_cycles += module_value['cycles']

		if func_key not in all_functions_cycles.keys():
			all_functions_cycles[func_key] = (module_value['cycles'], module_value['count'])
		else:
			all_functions_cycles[func_key] = tuple(map(sum, zip(all_functions_cycles[func_key], (module_value['cycles'], module_value['count']))))

sorted_functions_cycles     = sorted(functions_cycles.iteritems(), key=operator.itemgetter(1), reverse = True)
sorted_all_functions_cycles = sorted(all_functions_cycles.items(), key=operator.itemgetter(1), reverse = True)

print
print "----"
for (key,value) in sorted_functions_cycles[:20]:
	if value[0] != 0:
		print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
	else:
		break;
print "----"
for (key,value) in sorted_all_functions_cycles[:20]: 
	if value[0] != 0:
		print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
	else:
		break;
