OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 import commands |
| 7 import os |
| 8 import sys |
| 9 |
| 10 orderfile = sys.argv[1] |
| 11 uninstrumented_shlib = sys.argv[2] |
| 12 |
| 13 nmlines_uninstrumented = commands.getoutput ('nm -S -n ' + |
| 14 uninstrumented_shlib + ' | egrep "( t )|( W )|( T )"').split('\n') |
| 15 |
| 16 nmlines = [] |
| 17 for nmline in nmlines_uninstrumented: |
| 18 if (len(nmline.split()) == 4): |
| 19 nmlines.append(nmline) |
| 20 |
| 21 # Map addresses to list of functions at that address. There are multiple |
| 22 # functions at an address because of aliasing. |
| 23 nm_index = 0 |
| 24 uniqueAddrs = [] |
| 25 addressMap = {} |
| 26 while nm_index < len(nmlines): |
| 27 if (len(nmlines[nm_index].split()) == 4): |
| 28 nm_int = int (nmlines[nm_index].split()[0], 16) |
| 29 size = int (nmlines[nm_index].split()[1], 16) |
| 30 fnames = [nmlines[nm_index].split()[3]] |
| 31 nm_index = nm_index + 1 |
| 32 while nm_index < len(nmlines) and nm_int == int ( |
| 33 nmlines[nm_index].split()[0], 16): |
| 34 fnames.append(nmlines[nm_index].split()[3]) |
| 35 nm_index = nm_index + 1 |
| 36 addressMap[nm_int] = fnames |
| 37 uniqueAddrs.append((nm_int, size)) |
| 38 else: |
| 39 nm_index = nm_index + 1 |
| 40 |
| 41 def binary_search (addr, start, end): |
| 42 # print "addr: " + str(addr) + " start: " + str(start) + " end: " + str(end) |
| 43 if start >= end or start == end - 1: |
| 44 (nm_addr, size) = uniqueAddrs[start] |
| 45 if not (addr >= nm_addr and addr < nm_addr + size): |
| 46 sys.stderr.write ("ERROR: did not find function in binary: addr: " + |
| 47 hex(addr) + " nm_addr: " + str(nm_addr) + " start: " + str(start) + |
| 48 " end: " + str(end) + "\n") |
| 49 raise Error("error") |
| 50 return (addressMap[nm_addr], size) |
| 51 else: |
| 52 halfway = start + ((end - start) / 2) |
| 53 (nm_addr, size) = uniqueAddrs[halfway] |
| 54 # print "nm_addr: " + str(nm_addr) + " halfway: " + str(halfway) |
| 55 if (addr >= nm_addr and addr < nm_addr + size): |
| 56 return (addressMap[nm_addr], size) |
| 57 elif (addr < nm_addr): |
| 58 return binary_search (addr, start, halfway) |
| 59 elif (addr >= nm_addr + size): |
| 60 return binary_search (addr, halfway, end) |
| 61 else: |
| 62 raise "ERROR: did not expect this case" |
| 63 |
| 64 f = open (orderfile) |
| 65 lines = f.readlines() |
| 66 profiled_list = [] |
| 67 for line in lines: |
| 68 if (line.strip() == ''): |
| 69 continue |
| 70 functionName = line.replace('.text.', '').split('.clone.')[0].strip() |
| 71 profiled_list.append (functionName) |
| 72 |
| 73 # Symbol names are not unique. Since the order file uses symbol names, the |
| 74 # patched order file pulls in all symbols with the same name. Multiple function |
| 75 # addresses for the same function name may also be due to ".clone" symbols, |
| 76 # since the substring is stripped. |
| 77 functions = [] |
| 78 functionAddressMap = {} |
| 79 for line in nmlines: |
| 80 try: |
| 81 functionName = line.split()[3] |
| 82 except: |
| 83 functionName = line.split()[2] |
| 84 functionName = functionName.split('.clone.')[0] |
| 85 functionAddress = int (line.split()[0].strip(), 16) |
| 86 try: |
| 87 functionAddressMap[functionName].append(functionAddress) |
| 88 except: |
| 89 functionAddressMap[functionName] = [functionAddress] |
| 90 functions.append(functionName) |
| 91 |
| 92 sys.stderr.write ("profiled list size: " + str(len(profiled_list)) + "\n") |
| 93 addresses = [] |
| 94 symbols_found = 0 |
| 95 for function in profiled_list: |
| 96 try: |
| 97 addrs = functionAddressMap[function] |
| 98 symbols_found = symbols_found + 1 |
| 99 except: |
| 100 addrs = [] |
| 101 # sys.stderr.write ("WARNING: could not find symbol " + function + "\n") |
| 102 for addr in addrs: |
| 103 if not (addr in addresses): |
| 104 addresses.append(addr) |
| 105 sys.stderr.write ("symbols found: " + str(symbols_found) + "\n") |
| 106 |
| 107 sys.stderr.write ("number of addresses: " + str(len(addresses)) + "\n") |
| 108 total_size = 0 |
| 109 for addr in addresses: |
| 110 # if (count % 500 == 0): |
| 111 # print "current count: " + str(count) |
| 112 (functions, size) = binary_search (addr, 0, len(uniqueAddrs)) |
| 113 total_size = total_size + size |
| 114 for function in functions: |
| 115 print ".text." + function |
| 116 print "" |
| 117 sys.stderr.write ("total_size: " + str(total_size) + "\n") |
OLD | NEW |