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

Side by Side Diff: tools/binary_size/linker_map_parser.py

Issue 2791433004: //tools/binary_size: source_path information, change file format, fixes (Closed)
Patch Set: fix comment for _DetectToolPrefix 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 | « tools/binary_size/integration_test.py ('k') | tools/binary_size/map2size.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 import logging 5 import logging
6 6
7 import models 7 import models
8 8
9 9
10 class MapFileParser(object): 10 class MapFileParser(object):
11 """Parses a linker map file (tested only on files from gold linker).""" 11 """Parses a linker map file (tested only on files from gold linker)."""
12 # Map file writer for gold linker: 12 # Map file writer for gold linker:
13 # https://github.com/gittup/binutils/blob/HEAD/gold/mapfile.cc 13 # https://github.com/gittup/binutils/blob/HEAD/gold/mapfile.cc
14 14
15 def __init__(self): 15 def __init__(self):
16 self._symbols = [] 16 self._symbols = []
17 self._section_sizes = {} 17 self._section_sizes = {}
18 self._lines = None 18 self._lines = None
19 19
20 def Parse(self, lines): 20 def Parse(self, lines):
21 """Parses a linker map file. 21 """Parses a linker map file.
22 22
23 Args: 23 Args:
24 lines: Iterable of lines. 24 lines: Iterable of lines.
25 25
26 Returns: 26 Returns:
27 A SizeInfo object. 27 A tuple of (section_sizes, symbols).
28 """ 28 """
29 self._lines = iter(lines) 29 self._lines = iter(lines)
30 logging.info('Parsing common symbols') 30 logging.info('Parsing common symbols')
31 self._ParseCommonSymbols() 31 self._ParseCommonSymbols()
32 logging.debug('.bss common entries: %d', len(self._symbols)) 32 logging.debug('.bss common entries: %d', len(self._symbols))
33 logging.info('Parsing section symbols') 33 logging.info('Parsing section symbols')
34 self._ParseSections() 34 self._ParseSections()
35 return models.SizeInfo(models.SymbolGroup(self._symbols), 35 return self._section_sizes, self._symbols
36 self._section_sizes)
37 36
38 def _SkipToLineWithPrefix(self, prefix): 37 def _SkipToLineWithPrefix(self, prefix):
39 for l in self._lines: 38 for l in self._lines:
40 if l.startswith(prefix): 39 if l.startswith(prefix):
41 return l 40 return l
42 41
43 def _ParsePossiblyWrappedParts(self, line, count): 42 def _ParsePossiblyWrappedParts(self, line, count):
44 parts = line.split(None, count - 1) 43 parts = line.split(None, count - 1)
45 if not parts: 44 if not parts:
46 return None 45 return None
(...skipping 13 matching lines...) Expand all
60 self._SkipToLineWithPrefix('Common symbol') 59 self._SkipToLineWithPrefix('Common symbol')
61 next(self._lines) # Skip past blank line 60 next(self._lines) # Skip past blank line
62 61
63 name, size_str, path = None, None, None 62 name, size_str, path = None, None, None
64 for l in self._lines: 63 for l in self._lines:
65 parts = self._ParsePossiblyWrappedParts(l, 3) 64 parts = self._ParsePossiblyWrappedParts(l, 3)
66 if not parts: 65 if not parts:
67 break 66 break
68 name, size_str, path = parts 67 name, size_str, path = parts
69 self._symbols.append( 68 self._symbols.append(
70 models.Symbol('.bss', int(size_str[2:], 16), name=name, path=path)) 69 models.Symbol('.bss', int(size_str[2:], 16), name=name,
70 object_path=path))
71 71
72 def _ParseSections(self): 72 def _ParseSections(self):
73 # .text 0x0028c600 0x22d3468 73 # .text 0x0028c600 0x22d3468
74 # .text.startup._GLOBAL__sub_I_bbr_sender.cc 74 # .text.startup._GLOBAL__sub_I_bbr_sender.cc
75 # 0x0028c600 0x38 obj/net/net/bbr_sender.o 75 # 0x0028c600 0x38 obj/net/net/bbr_sender.o
76 # .text._reset 0x00339d00 0xf0 obj/third_party/icu/icuuc/ucnv.o 76 # .text._reset 0x00339d00 0xf0 obj/third_party/icu/icuuc/ucnv.o
77 # ** fill 0x0255fb00 0x02 77 # ** fill 0x0255fb00 0x02
78 # .text._ZN4base8AutoLockD2Ev 78 # .text._ZN4base8AutoLockD2Ev
79 # 0x00290710 0xe obj/net/net/file_name.o 79 # 0x00290710 0xe obj/net/net/file_name.o
80 # 0x00290711 base::AutoLock::~AutoLock() 80 # 0x00290711 base::AutoLock::~AutoLock()
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 address_str, size_str = self._ParsePossiblyWrappedParts(line, 2) 134 address_str, size_str = self._ParsePossiblyWrappedParts(line, 2)
135 line = next(self._lines) 135 line = next(self._lines)
136 # These bytes are already accounted for. 136 # These bytes are already accounted for.
137 if name == '** common': 137 if name == '** common':
138 continue 138 continue
139 address = int(address_str[2:], 16) 139 address = int(address_str[2:], 16)
140 size = int(size_str[2:], 16) 140 size = int(size_str[2:], 16)
141 path = None 141 path = None
142 syms.append( 142 syms.append(
143 models.Symbol(section_name, size, address=address, name=name, 143 models.Symbol(section_name, size, address=address, name=name,
144 path=path)) 144 object_path=path))
145 else: 145 else:
146 # A normal symbol entry. 146 # A normal symbol entry.
147 subsection_name, address_str, size_str, path = ( 147 subsection_name, address_str, size_str, path = (
148 self._ParsePossiblyWrappedParts(line, 4)) 148 self._ParsePossiblyWrappedParts(line, 4))
149 size = int(size_str[2:], 16) 149 size = int(size_str[2:], 16)
150 assert subsection_name.startswith(section_name), ( 150 assert subsection_name.startswith(section_name), (
151 'subsection name was: ' + subsection_name) 151 'subsection name was: ' + subsection_name)
152 mangled_name = subsection_name[prefix_len:] 152 mangled_name = subsection_name[prefix_len:]
153 name = None 153 name = None
154 address_str2 = None 154 address_str2 = None
(...skipping 27 matching lines...) Expand all
182 else: 182 else:
183 address = int(address_str[2:], 16) 183 address = int(address_str[2:], 16)
184 # Finish off active address gap / merge section. 184 # Finish off active address gap / merge section.
185 if merge_symbol_start_address: 185 if merge_symbol_start_address:
186 merge_size = address - merge_symbol_start_address 186 merge_size = address - merge_symbol_start_address
187 logging.debug('Merge symbol of size %d found at:\n %r', 187 logging.debug('Merge symbol of size %d found at:\n %r',
188 merge_size, syms[-1]) 188 merge_size, syms[-1])
189 sym = models.Symbol( 189 sym = models.Symbol(
190 section_name, merge_size, 190 section_name, merge_size,
191 address=merge_symbol_start_address, 191 address=merge_symbol_start_address,
192 name='** symbol gap %d' % symbol_gap_count, path=path) 192 name='** symbol gap %d' % symbol_gap_count,
193 object_path=path)
193 symbol_gap_count += 1 194 symbol_gap_count += 1
194 syms.append(sym) 195 syms.append(sym)
195 merge_symbol_start_address = 0 196 merge_symbol_start_address = 0
196 197
197 if address == -1 and address_str2: 198 if address == -1 and address_str2:
198 address = int(address_str2[2:], 16) - 1 199 address = int(address_str2[2:], 16) - 1
199 # Merge sym with no second line showing real address. 200 # Merge sym with no second line showing real address.
200 if address == -1: 201 if address == -1:
201 address = syms[-1].end_address 202 address = syms[-1].end_address
202 syms.append(models.Symbol(section_name, size, address=address, 203 syms.append(models.Symbol(section_name, size, address=address,
203 name=name or mangled_name, path=path)) 204 name=name or mangled_name,
205 object_path=path))
204 logging.debug('Symbol count for %s: %d', section_name, 206 logging.debug('Symbol count for %s: %d', section_name,
205 len(syms) - sym_count_at_start) 207 len(syms) - sym_count_at_start)
206 except: 208 except:
207 logging.error('Problem line: %r', line) 209 logging.error('Problem line: %r', line)
208 logging.error('In section: %r', section_name) 210 logging.error('In section: %r', section_name)
209 raise 211 raise
OLDNEW
« no previous file with comments | « tools/binary_size/integration_test.py ('k') | tools/binary_size/map2size.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698