1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 """Common utilities for tools that deal with binary size information.
12 def ParseNm(nm_lines
):
13 """Parse nm output, returning data for all relevant (to binary size)
14 symbols and ignoring the rest.
17 nm_lines: an iterable over lines of nm output.
20 (symbol name, symbol type, symbol size, source file path).
22 Path may be None if nm couldn't figure out the source file.
25 # Match lines with size, symbol, optional location, optional discriminator
26 sym_re
= re
.compile(r
'^[0-9a-f]{8,} ' # address (8+ hex digits)
27 '([0-9a-f]{8,}) ' # size (8+ hex digits)
28 '(.) ' # symbol type, one character
29 '([^\t]+)' # symbol name, separated from next by tab
30 '(?:\t(.*):[\d\?]+)?.*$') # location
31 # Match lines with addr but no size.
32 addr_re
= re
.compile(r
'^[0-9a-f]{8,} (.) ([^\t]+)(?:\t.*)?$')
33 # Match lines that don't have an address at all -- typically external symbols.
34 noaddr_re
= re
.compile(r
'^ {8,} (.) (.*)$')
35 # Match lines with no symbol name, only addr and type
36 addr_only_re
= re
.compile(r
'^[0-9a-f]{8,} (.)$')
40 match
= sym_re
.match(line
)
42 size
, sym_type
, sym
= match
.groups()[0:3]
44 if sym_type
in ('B', 'b'):
45 continue # skip all BSS for now.
47 yield sym
, sym_type
, size
, path
49 match
= addr_re
.match(line
)
51 # sym_type, sym = match.groups()[0:2]
52 continue # No size == we don't care.
53 match
= noaddr_re
.match(line
)
55 sym_type
, sym
= match
.groups()
56 if sym_type
in ('U', 'w'):
57 continue # external or weak symbol
58 match
= addr_only_re
.match(line
)
60 continue # Nothing to do.
63 # If we reach this part of the loop, there was something in the
64 # line that we didn't expect or recognize.
65 logging
.warning('nm output parser failed to parse: %s', repr(line
))