Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: tools/binary_size/libsupersize/archive.py

Issue 2828333003: supersize: Strip linker-added prefixes from symbol names (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/binary_size/libsupersize/describe.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2017 The Chromium Authors. All rights reserved. 1 # Copyright 2017 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Main Python API for analyzing binary size.""" 5 """Main Python API for analyzing binary size."""
6 6
7 import argparse 7 import argparse
8 import calendar 8 import calendar
9 import collections 9 import collections
10 import datetime 10 import datetime
(...skipping 20 matching lines...) Expand all
31 31
32 def _OpenMaybeGz(path, mode=None): 32 def _OpenMaybeGz(path, mode=None):
33 """Calls `gzip.open()` if |path| ends in ".gz", otherwise calls `open()`.""" 33 """Calls `gzip.open()` if |path| ends in ".gz", otherwise calls `open()`."""
34 if path.endswith('.gz'): 34 if path.endswith('.gz'):
35 if mode and 'w' in mode: 35 if mode and 'w' in mode:
36 return gzip.GzipFile(path, mode, 1) 36 return gzip.GzipFile(path, mode, 1)
37 return gzip.open(path, mode) 37 return gzip.open(path, mode)
38 return open(path, mode or 'r') 38 return open(path, mode or 'r')
39 39
40 40
41 def _StripLinkerAddedSymbolPrefixes(symbols):
42 """Removes prefixes sometimes added to symbol names during link
43
44 Removing prefixes make symbol names match up with those found in .o files.
45 """
46 for symbol in symbols:
47 name = symbol.name
48 if name.startswith('startup.'):
49 symbol.flags |= models.FLAG_STARTUP
50 symbol.name = name[8:]
51 elif name.startswith('unlikely.'):
52 symbol.flags |= models.FLAG_UNLIKELY
53 symbol.name = name[9:]
54 elif name.startswith('rel.local.'):
55 symbol.flags |= models.FLAG_REL_LOCAL
56 symbol.name = name[10:]
57 elif name.startswith('rel.'):
58 symbol.flags |= models.FLAG_REL
59 symbol.name = name[4:]
60
61
41 def _UnmangleRemainingSymbols(symbols, tool_prefix): 62 def _UnmangleRemainingSymbols(symbols, tool_prefix):
42 """Uses c++filt to unmangle any symbols that need it.""" 63 """Uses c++filt to unmangle any symbols that need it."""
43 to_process = [s for s in symbols if s.name.startswith('_Z')] 64 to_process = [s for s in symbols if s.name.startswith('_Z')]
44 if not to_process: 65 if not to_process:
45 return 66 return
46 67
47 logging.info('Unmangling %d names', len(to_process)) 68 logging.info('Unmangling %d names', len(to_process))
48 proc = subprocess.Popen([tool_prefix + 'c++filt'], stdin=subprocess.PIPE, 69 proc = subprocess.Popen([tool_prefix + 'c++filt'], stdin=subprocess.PIPE,
49 stdout=subprocess.PIPE) 70 stdout=subprocess.PIPE)
50 stdout = proc.communicate('\n'.join(s.name for s in to_process))[0] 71 stdout = proc.communicate('\n'.join(s.name for s in to_process))[0]
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 found_prefixes.add(symbol.name[:idx + 3]) 103 found_prefixes.add(symbol.name[:idx + 3])
83 symbol.name = symbol.name[idx + 4:] + ' [' + symbol.name[:idx] + ']' 104 symbol.name = symbol.name[idx + 4:] + ' [' + symbol.name[:idx] + ']'
84 105
85 # Strip out return type, and identify where parameter list starts. 106 # Strip out return type, and identify where parameter list starts.
86 if symbol.section == 't': 107 if symbol.section == 't':
87 symbol.full_name, symbol.name = function_signature.Parse(symbol.name) 108 symbol.full_name, symbol.name = function_signature.Parse(symbol.name)
88 109
89 # Remove anonymous namespaces (they just harm clustering). 110 # Remove anonymous namespaces (they just harm clustering).
90 non_anonymous = symbol.name.replace('(anonymous namespace)::', '') 111 non_anonymous = symbol.name.replace('(anonymous namespace)::', '')
91 if symbol.name != non_anonymous: 112 if symbol.name != non_anonymous:
92 symbol.is_anonymous = True 113 symbol.flags |= models.FLAG_ANONYMOUS
93 symbol.name = non_anonymous 114 symbol.name = non_anonymous
94 symbol.full_name = symbol.full_name.replace( 115 symbol.full_name = symbol.full_name.replace(
95 '(anonymous namespace)::', '') 116 '(anonymous namespace)::', '')
96 117
97 if symbol.section != 't' and '(' in symbol.name: 118 if symbol.section != 't' and '(' in symbol.name:
98 # Pretty rare. Example: 119 # Pretty rare. Example:
99 # blink::CSSValueKeywordsHash::findValueImpl(char const*)::value_word_list 120 # blink::CSSValueKeywordsHash::findValueImpl(char const*)::value_word_list
100 symbol.full_name = symbol.name 121 symbol.full_name = symbol.name
101 symbol.name = re.sub(r'\(.*\)', '', symbol.full_name) 122 symbol.name = re.sub(r'\(.*\)', '', symbol.full_name)
102 123
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 with _OpenMaybeGz(map_path) as map_file: 358 with _OpenMaybeGz(map_path) as map_file:
338 section_sizes, raw_symbols = ( 359 section_sizes, raw_symbols = (
339 linker_map_parser.MapFileParser().Parse(map_file)) 360 linker_map_parser.MapFileParser().Parse(map_file))
340 361
341 if not no_source_paths: 362 if not no_source_paths:
342 logging.info('Extracting source paths from .ninja files') 363 logging.info('Extracting source paths from .ninja files')
343 all_found = _ExtractSourcePaths(raw_symbols, lazy_paths.output_directory) 364 all_found = _ExtractSourcePaths(raw_symbols, lazy_paths.output_directory)
344 assert all_found, ( 365 assert all_found, (
345 'One or more source file paths could not be found. Likely caused by ' 366 'One or more source file paths could not be found. Likely caused by '
346 '.ninja files being generated at a different time than the .map file.') 367 '.ninja files being generated at a different time than the .map file.')
368
369 logging.info('Stripping linker prefixes from symbol names')
370 _StripLinkerAddedSymbolPrefixes(raw_symbols)
347 # Map file for some reason doesn't unmangle all names. 371 # Map file for some reason doesn't unmangle all names.
348 # Unmangle prints its own log statement. 372 # Unmangle prints its own log statement.
349 _UnmangleRemainingSymbols(raw_symbols, lazy_paths.tool_prefix) 373 _UnmangleRemainingSymbols(raw_symbols, lazy_paths.tool_prefix)
350 logging.info('Normalizing object paths') 374 logging.info('Normalizing object paths')
351 _NormalizeObjectPaths(raw_symbols) 375 _NormalizeObjectPaths(raw_symbols)
352 size_info = models.SizeInfo(section_sizes, raw_symbols) 376 size_info = models.SizeInfo(section_sizes, raw_symbols)
353 377
354 # Name normalization not strictly required, but makes for smaller files. 378 # Name normalization not strictly required, but makes for smaller files.
355 if raw_only: 379 if raw_only:
356 logging.info('Normalizing symbol names') 380 logging.info('Normalizing symbol names')
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 logging.warning('Packed section not present: %s', packed_section_name) 574 logging.warning('Packed section not present: %s', packed_section_name)
551 else: 575 else:
552 size_info.section_sizes['%s (unpacked)' % packed_section_name] = ( 576 size_info.section_sizes['%s (unpacked)' % packed_section_name] = (
553 unstripped_section_sizes.get(packed_section_name)) 577 unstripped_section_sizes.get(packed_section_name))
554 578
555 logging.info('Recording metadata: \n %s', 579 logging.info('Recording metadata: \n %s',
556 '\n '.join(describe.DescribeMetadata(size_info.metadata))) 580 '\n '.join(describe.DescribeMetadata(size_info.metadata)))
557 logging.info('Saving result to %s', args.size_file) 581 logging.info('Saving result to %s', args.size_file)
558 file_format.SaveSizeInfo(size_info, args.size_file) 582 file_format.SaveSizeInfo(size_info, args.size_file)
559 logging.info('Done') 583 logging.info('Done')
OLDNEW
« no previous file with comments | « no previous file | tools/binary_size/libsupersize/describe.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698