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 # 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")
50 return (addressMap
[nm_addr
], size
)
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
)
62 raise "ERROR: did not expect this case"
68 if (line
.strip() == ''):
70 functionName
= line
.replace('.text.', '').split('.clone.')[0].strip()
71 profiled_list
.append (functionName
)
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.
78 functionAddressMap
= {}
81 functionName
= line
.split()[3]
83 functionName
= line
.split()[2]
84 functionName
= functionName
.split('.clone.')[0]
85 functionAddress
= int (line
.split()[0].strip(), 16)
87 functionAddressMap
[functionName
].append(functionAddress
)
89 functionAddressMap
[functionName
] = [functionAddress
]
90 functions
.append(functionName
)
92 sys
.stderr
.write ("profiled list size: " + str(len(profiled_list
)) + "\n")
95 for function
in profiled_list
:
97 addrs
= functionAddressMap
[function
]
98 symbols_found
= symbols_found
+ 1
101 # sys.stderr.write ("WARNING: could not find symbol " + function + "\n")
103 if not (addr
in addresses
):
104 addresses
.append(addr
)
105 sys
.stderr
.write ("symbols found: " + str(symbols_found
) + "\n")
107 sys
.stderr
.write ("number of addresses: " + str(len(addresses
)) + "\n")
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
117 sys
.stderr
.write ("total_size: " + str(total_size
) + "\n")