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.
10 orderfile
= sys
.argv
[1]
11 uninstrumented_shlib
= sys
.argv
[2]
13 nmlines_uninstrumented
= commands
.getoutput ('nm -S -n ' +
14 uninstrumented_shlib
+ ' | egrep "( t )|( W )|( T )"').split('\n')
17 for nmline
in nmlines_uninstrumented
:
18 if (len(nmline
.split()) == 4):
19 nmlines
.append(nmline
)
21 # Map addresses to list of functions at that address. There are multiple
22 # functions at an address because of aliasing.
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
))
39 nm_index
= nm_index
+ 1
41 def 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")
49 return (addressMap
[nm_addr
], size
)
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
)
60 raise "ERROR: did not expect this case"
66 if (line
.strip() == ''):
68 functionName
= line
.replace('.text.', '').split('.clone.')[0].strip()
69 profiled_list
.append (functionName
)
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.
76 functionAddressMap
= {}
79 functionName
= line
.split()[3]
81 functionName
= line
.split()[2]
82 functionName
= functionName
.split('.clone.')[0]
83 functionAddress
= int (line
.split()[0].strip(), 16)
85 functionAddressMap
[functionName
].append(functionAddress
)
87 functionAddressMap
[functionName
] = [functionAddress
]
88 functions
.append(functionName
)
90 sys
.stderr
.write ("profiled list size: " + str(len(profiled_list
)) + "\n")
93 for function
in profiled_list
:
95 addrs
= functionAddressMap
[function
]
96 symbols_found
= symbols_found
+ 1
99 # sys.stderr.write ("WARNING: could not find symbol " + function + "\n")
101 if not (addr
in addresses
):
102 addresses
.append(addr
)
103 sys
.stderr
.write ("symbols found: " + str(symbols_found
) + "\n")
105 sys
.stderr
.write ("number of addresses: " + str(len(addresses
)) + "\n")
107 for 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
115 # The following is needed otherwise Gold only applies a partial sort.
117 sys
.stderr
.write ("total_size: " + str(total_size
) + "\n")