summaryrefslogtreecommitdiffstats
path: root/ArmPlatformPkg/Scripts/Ds5/profile.py
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPlatformPkg/Scripts/Ds5/profile.py')
-rw-r--r--ArmPlatformPkg/Scripts/Ds5/profile.py656
1 files changed, 328 insertions, 328 deletions
diff --git a/ArmPlatformPkg/Scripts/Ds5/profile.py b/ArmPlatformPkg/Scripts/Ds5/profile.py
index f87dee2469..979c6ea2bd 100644
--- a/ArmPlatformPkg/Scripts/Ds5/profile.py
+++ b/ArmPlatformPkg/Scripts/Ds5/profile.py
@@ -1,328 +1,328 @@
-#!/usr/bin/python
-
-#
-# Copyright (c) 2014, ARM Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-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;
+#!/usr/bin/python
+
+#
+# Copyright (c) 2014, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+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;