1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#!/usr/bin/python 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# found in the LICENSE file. 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import commands 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import os 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import sys 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)orderfile = sys.argv[1] 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uninstrumented_shlib = sys.argv[2] 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)nmlines_uninstrumented = commands.getoutput ('nm -S -n ' + 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uninstrumented_shlib + ' | egrep "( t )|( W )|( T )"').split('\n') 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)nmlines = [] 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)for nmline in nmlines_uninstrumented: 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (len(nmline.split()) == 4): 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nmlines.append(nmline) 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# Map addresses to list of functions at that address. There are multiple 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# functions at an address because of aliasing. 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)nm_index = 0 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uniqueAddrs = [] 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)addressMap = {} 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)while nm_index < len(nmlines): 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (len(nmlines[nm_index].split()) == 4): 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nm_int = int (nmlines[nm_index].split()[0], 16) 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size = int (nmlines[nm_index].split()[1], 16) 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fnames = [nmlines[nm_index].split()[3]] 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nm_index = nm_index + 1 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) while nm_index < len(nmlines) and nm_int == int ( 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nmlines[nm_index].split()[0], 16): 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fnames.append(nmlines[nm_index].split()[3]) 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nm_index = nm_index + 1 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) addressMap[nm_int] = fnames 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uniqueAddrs.append((nm_int, size)) 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else: 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nm_index = nm_index + 1 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)def binary_search (addr, start, end): 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if start >= end or start == end - 1: 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (nm_addr, size) = uniqueAddrs[start] 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if not (addr >= nm_addr and addr < nm_addr + size): 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sys.stderr.write ("ERROR: did not find function in binary: addr: " + 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) hex(addr) + " nm_addr: " + str(nm_addr) + " start: " + str(start) + 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " end: " + str(end) + "\n") 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) raise Error("error") 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return (addressMap[nm_addr], size) 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else: 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) halfway = start + ((end - start) / 2) 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (nm_addr, size) = uniqueAddrs[halfway] 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (addr >= nm_addr and addr < nm_addr + size): 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return (addressMap[nm_addr], size) 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) elif (addr < nm_addr): 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return binary_search (addr, start, halfway) 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) elif (addr >= nm_addr + size): 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return binary_search (addr, halfway, end) 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else: 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) raise "ERROR: did not expect this case" 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)f = open (orderfile) 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)lines = f.readlines() 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)profiled_list = [] 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)for line in lines: 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (line.strip() == ''): 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) continue 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) functionName = line.replace('.text.', '').split('.clone.')[0].strip() 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profiled_list.append (functionName) 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# Symbol names are not unique. Since the order file uses symbol names, the 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# patched order file pulls in all symbols with the same name. Multiple function 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# addresses for the same function name may also be due to ".clone" symbols, 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# since the substring is stripped. 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)functions = [] 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)functionAddressMap = {} 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)for line in nmlines: 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) try: 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) functionName = line.split()[3] 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) except: 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) functionName = line.split()[2] 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) functionName = functionName.split('.clone.')[0] 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) functionAddress = int (line.split()[0].strip(), 16) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) try: 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) functionAddressMap[functionName].append(functionAddress) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) except: 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) functionAddressMap[functionName] = [functionAddress] 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) functions.append(functionName) 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)sys.stderr.write ("profiled list size: " + str(len(profiled_list)) + "\n") 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)addresses = [] 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)symbols_found = 0 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)for function in profiled_list: 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) try: 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) addrs = functionAddressMap[function] 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) symbols_found = symbols_found + 1 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) except: 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) addrs = [] 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) # sys.stderr.write ("WARNING: could not find symbol " + function + "\n") 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for addr in addrs: 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if not (addr in addresses): 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) addresses.append(addr) 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)sys.stderr.write ("symbols found: " + str(symbols_found) + "\n") 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)sys.stderr.write ("number of addresses: " + str(len(addresses)) + "\n") 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)total_size = 0 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)for addr in addresses: 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (functions, size) = binary_search (addr, 0, len(uniqueAddrs)) 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) total_size = total_size + size 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prefixes = ['.text.', '.text.startup.', '.text.hot.', '.text.unlikely.'] 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for function in functions: 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for prefix in prefixes: 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) print prefix + function 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# The following is needed otherwise Gold only applies a partial sort. 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)print '.text.*' 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)sys.stderr.write ("total_size: " + str(total_size) + "\n") 118