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 patch_orderfile
14 import symbol_extractor
17 _MAX_WARNINGS_TO_PRINT
= 200
20 def _CountMisorderedSymbols(symbols
, symbol_infos
):
21 """Count the number of misordered symbols, and log them.
24 symbols: ordered sequence of symbols from the orderfile
25 symbol_infos: ordered list of SymbolInfo from the binary
28 (misordered_pairs_count, matched_symbols_count, unmatched_symbols_count)
30 name_to_symbol_info
= symbol_extractor
.CreateNameToSymbolInfo(symbol_infos
)
31 matched_symbol_infos
= []
35 # Find the SymbolInfo matching the orderfile symbols in the binary.
36 for symbol
in symbols
:
37 if symbol
in name_to_symbol_info
:
38 matched_symbol_infos
.append(name_to_symbol_info
[symbol
])
41 if missing_count
< _MAX_WARNINGS_TO_PRINT
:
42 logging
.warning('Symbol "%s" is in the orderfile, not in the binary' %
44 logging
.info('%d matched symbols, %d un-matched (Only the first %d unmatched'
45 ' symbols are shown)' % (
46 len(matched_symbol_infos
), missing_count
,
47 _MAX_WARNINGS_TO_PRINT
))
49 # In the order of the orderfile, find all the symbols that are at an offset
50 # smaller than their immediate predecessor, and record the pair.
51 previous_symbol_info
= symbol_extractor
.SymbolInfo(
52 name
='', offset
=-1, size
=0, section
='')
53 for symbol_info
in matched_symbol_infos
:
54 if symbol_info
.offset
< previous_symbol_info
.offset
:
55 logging
.warning("Misordered pair: %s - %s" % (
56 str(previous_symbol_info
), str(symbol_info
)))
58 previous_symbol_info
= symbol_info
59 return (misordered_count
, len(matched_symbol_infos
), missing_count
)
63 parser
= optparse
.OptionParser(usage
=
64 'usage: %prog [options] <binary> <orderfile>')
65 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
)
75 (binary_filename
, orderfile_filename
) = argv
[1:]
77 symbol_extractor
.SetArchitecture(options
.arch
)
78 symbols
= patch_orderfile
.GetSymbolsFromOrderfile(orderfile_filename
)
79 symbol_infos
= symbol_extractor
.SymbolInfosFromBinary(binary_filename
)
80 # Missing symbols is not an error since some of them can be eliminated through
82 (misordered_pairs_count
, matched_symbols
, _
) = _CountMisorderedSymbols(
83 symbols
, symbol_infos
)
84 return (misordered_pairs_count
> options
.threshold
) or (matched_symbols
== 0)
87 if __name__
== '__main__':
88 logging
.basicConfig(level
=logging
.INFO
)