• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
2# Copyright 2013 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
6import commands
7import os
8import sys
9
10orderfile = sys.argv[1]
11uninstrumented_shlib = sys.argv[2]
12
13nmlines_uninstrumented = commands.getoutput ('nm -S -n ' +
14   uninstrumented_shlib + '  | egrep "( t )|( W )|( T )"').split('\n')
15
16nmlines = []
17for 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.
23nm_index = 0
24uniqueAddrs = []
25addressMap = {}
26while 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
41def binary_search (addr, start, end):
42  if start >= end or start == end - 1:
43    (nm_addr, size) = uniqueAddrs[start]
44    if not (addr >= nm_addr and addr < nm_addr + size):
45      sys.stderr.write ("ERROR: did not find function in binary: addr: " +
46          hex(addr) + " nm_addr: " + str(nm_addr) + " start: " + str(start) +
47          " end: " + str(end) + "\n")
48      raise Error("error")
49    return (addressMap[nm_addr], size)
50  else:
51    halfway = start + ((end - start) / 2)
52    (nm_addr, size) = uniqueAddrs[halfway]
53    if (addr >= nm_addr and addr < nm_addr + size):
54      return (addressMap[nm_addr], size)
55    elif (addr < nm_addr):
56      return binary_search (addr, start, halfway)
57    elif (addr >= nm_addr + size):
58      return binary_search (addr, halfway, end)
59    else:
60      raise "ERROR: did not expect this case"
61
62f = open (orderfile)
63lines = f.readlines()
64profiled_list = []
65for line in lines:
66  if (line.strip() == ''):
67    continue
68  functionName = line.replace('.text.', '').split('.clone.')[0].strip()
69  profiled_list.append (functionName)
70
71# Symbol names are not unique.  Since the order file uses symbol names, the
72# patched order file pulls in all symbols with the same name.  Multiple function
73# addresses for the same function name may also be due to ".clone" symbols,
74# since the substring is stripped.
75functions = []
76functionAddressMap = {}
77for line in nmlines:
78  try:
79    functionName = line.split()[3]
80  except:
81    functionName = line.split()[2]
82  functionName = functionName.split('.clone.')[0]
83  functionAddress = int (line.split()[0].strip(), 16)
84  try:
85    functionAddressMap[functionName].append(functionAddress)
86  except:
87    functionAddressMap[functionName] = [functionAddress]
88    functions.append(functionName)
89
90sys.stderr.write ("profiled list size: " + str(len(profiled_list)) + "\n")
91addresses = []
92symbols_found = 0
93for function in profiled_list:
94   try:
95     addrs = functionAddressMap[function]
96     symbols_found = symbols_found + 1
97   except:
98     addrs = []
99     # sys.stderr.write ("WARNING: could not find symbol " + function + "\n")
100   for addr in addrs:
101     if not (addr in addresses):
102       addresses.append(addr)
103sys.stderr.write ("symbols found: " + str(symbols_found) + "\n")
104
105sys.stderr.write ("number of addresses: " + str(len(addresses)) + "\n")
106total_size = 0
107for addr in addresses:
108  (functions, size) = binary_search (addr, 0, len(uniqueAddrs))
109  total_size = total_size + size
110  prefixes = ['.text.', '.text.startup.', '.text.hot.', '.text.unlikely.']
111  for function in functions:
112    for prefix in prefixes:
113      print prefix + function
114
115# The following is needed otherwise Gold only applies a partial sort.
116print '.text.*'
117sys.stderr.write ("total_size: " + str(total_size) + "\n")
118