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.
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.
25 symbols: ordered sequence of symbols from the orderfile
26 symbol_infos: ordered list of SymbolInfo from the binary
29 (misordered_pairs_count, matched_symbols_count, unmatched_symbols_count)
31 name_to_symbol_info
= symbol_extractor
.CreateNameToSymbolInfo(symbol_infos
)
32 matched_symbol_infos
= []
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
])
42 if missing_count
< _MAX_WARNINGS_TO_PRINT
:
43 logging
.warning('Symbol "%s" is in the orderfile, not in the binary' %
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
)))
59 previous_symbol_info
= symbol_info
60 return (misordered_count
, len(matched_symbol_infos
), missing_count
)
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
)
73 options
.arch
= cygprofile_utils
.DetectArchitecture()
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
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
)