Roll src/third_party/WebKit 1e14c28:9b3210f (svn 194535:194542)
[chromium-blink-merge.git] / tools / cygprofile / check_orderfile.py
blob4202f7fdacf9d86f6f2e0b19e5e18786856308b0
1 #!/usr/bin/python
2 # Copyright 2015 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.
6 """Check that symbols are ordered into a binary as they appear in the orderfile.
7 """
9 import logging
10 import optparse
11 import sys
13 import cygprofile_utils
14 import patch_orderfile
15 import symbol_extractor
18 _MAX_WARNINGS_TO_PRINT = 200
21 def _CountMisorderedSymbols(symbols, symbol_infos):
22 """Count the number of misordered symbols, and log them.
24 Args:
25 symbols: ordered sequence of symbols from the orderfile
26 symbol_infos: ordered list of SymbolInfo from the binary
28 Returns:
29 (misordered_pairs_count, matched_symbols_count, unmatched_symbols_count)
30 """
31 name_to_symbol_info = symbol_extractor.CreateNameToSymbolInfo(symbol_infos)
32 matched_symbol_infos = []
33 missing_count = 0
34 misordered_count = 0
36 # Find the SymbolInfo matching the orderfile symbols in the binary.
37 for symbol in symbols:
38 if symbol in name_to_symbol_info:
39 matched_symbol_infos.append(name_to_symbol_info[symbol])
40 else:
41 missing_count += 1
42 if missing_count < _MAX_WARNINGS_TO_PRINT:
43 logging.warning('Symbol "%s" is in the orderfile, not in the binary' %
44 symbol)
45 logging.info('%d matched symbols, %d un-matched (Only the first %d unmatched'
46 ' symbols are shown)' % (
47 len(matched_symbol_infos), missing_count,
48 _MAX_WARNINGS_TO_PRINT))
50 # In the order of the orderfile, find all the symbols that are at an offset
51 # smaller than their immediate predecessor, and record the pair.
52 previous_symbol_info = symbol_extractor.SymbolInfo(
53 name='', offset=-1, size=0, section='')
54 for symbol_info in matched_symbol_infos:
55 if symbol_info.offset < previous_symbol_info.offset:
56 logging.warning("Misordered pair: %s - %s" % (
57 str(previous_symbol_info), str(symbol_info)))
58 misordered_count += 1
59 previous_symbol_info = symbol_info
60 return (misordered_count, len(matched_symbol_infos), missing_count)
63 def main():
64 parser = optparse.OptionParser(usage=
65 'usage: %prog [options] <binary> <orderfile>')
66 parser.add_option('--target-arch', action='store', dest='arch',
67 choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
68 help='The target architecture for the binary.')
69 parser.add_option('--threshold', action='store', dest='threshold', default=0,
70 help='The maximum allowed number of out-of-order symbols.')
71 options, argv = parser.parse_args(sys.argv)
72 if not options.arch:
73 options.arch = cygprofile_utils.DetectArchitecture()
74 if len(argv) != 3:
75 parser.print_help()
76 return 1
77 (binary_filename, orderfile_filename) = argv[1:]
79 symbol_extractor.SetArchitecture(options.arch)
80 symbols = patch_orderfile.GetSymbolsFromOrderfile(orderfile_filename)
81 symbol_infos = symbol_extractor.SymbolInfosFromBinary(binary_filename)
82 # Missing symbols is not an error since some of them can be eliminated through
83 # inlining.
84 (misordered_pairs_count, matched_symbols, _) = _CountMisorderedSymbols(
85 symbols, symbol_infos)
86 return (misordered_pairs_count > options.threshold) or (matched_symbols == 0)
89 if __name__ == '__main__':
90 logging.basicConfig(level=logging.INFO)
91 sys.exit(main())