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

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

Issue 2858793002: Create a star symbol for gaps at the start & end of sections (Closed)
Patch Set: Created 3 years, 7 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/libsupersize/describe.py ('k') | tools/binary_size/libsupersize/models.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 # About linker maps: 9 # About linker maps:
10 # * "Discarded input sections" include symbols merged with other symbols 10 # * "Discarded input sections" include symbols merged with other symbols
(...skipping 17 matching lines...) Expand all
28 def Parse(self, lines): 28 def Parse(self, lines):
29 """Parses a linker map file. 29 """Parses a linker map file.
30 30
31 Args: 31 Args:
32 lines: Iterable of lines. 32 lines: Iterable of lines.
33 33
34 Returns: 34 Returns:
35 A tuple of (section_sizes, symbols). 35 A tuple of (section_sizes, symbols).
36 """ 36 """
37 self._lines = iter(lines) 37 self._lines = iter(lines)
38 logging.info('Parsing common symbols') 38 logging.debug('Scanning for Header')
39 self._common_symbols = self._ParseCommonSymbols() 39
40 logging.debug('.bss common entries: %d', len(self._common_symbols)) 40 while True:
41 logging.info('Parsing section symbols') 41 line = self._SkipToLineWithPrefix('Common symbol', 'Memory map')
42 self._ParseSections() 42 if line.startswith('Common symbol'):
43 self._common_symbols = self._ParseCommonSymbols()
44 logging.debug('.bss common entries: %d', len(self._common_symbols))
45 continue
46 elif line.startswith('Memory map'):
47 self._ParseSections()
48 break
43 return self._section_sizes, self._symbols 49 return self._section_sizes, self._symbols
44 50
45 def _SkipToLineWithPrefix(self, prefix): 51 def _SkipToLineWithPrefix(self, prefix, prefix2=None):
46 for l in self._lines: 52 for l in self._lines:
47 if l.startswith(prefix): 53 if l.startswith(prefix) or (prefix2 and l.startswith(prefix2)):
48 return l 54 return l
49 55
50 def _ParsePossiblyWrappedParts(self, line, count): 56 def _ParsePossiblyWrappedParts(self, line, count):
51 parts = line.split(None, count - 1) 57 parts = line.split(None, count - 1)
52 if not parts: 58 if not parts:
53 return None 59 return None
54 if len(parts) != count: 60 if len(parts) != count:
55 line = next(self._lines) 61 line = next(self._lines)
56 parts.extend(line.split(None, count - len(parts) - 1)) 62 parts.extend(line.split(None, count - len(parts) - 1))
57 assert len(parts) == count, 'parts: ' + ' '.join(parts) 63 assert len(parts) == count, 'parts: ' + ' '.join(parts)
58 parts[-1] = parts[-1].rstrip() 64 parts[-1] = parts[-1].rstrip()
59 return parts 65 return parts
60 66
61 def _ParseCommonSymbols(self): 67 def _ParseCommonSymbols(self):
62 # Common symbol size file 68 # Common symbol size file
63 # 69 #
64 # ff_cos_131072 0x40000 obj/third_party/<snip> 70 # ff_cos_131072 0x40000 obj/third_party/<snip>
65 # ff_cos_131072_fixed 71 # ff_cos_131072_fixed
66 # 0x20000 obj/third_party/<snip> 72 # 0x20000 obj/third_party/<snip>
67 ret = [] 73 ret = []
68 self._SkipToLineWithPrefix('Common symbol')
69 next(self._lines) # Skip past blank line 74 next(self._lines) # Skip past blank line
70 75
71 name, size_str, path = None, None, None 76 name, size_str, path = None, None, None
72 for l in self._lines: 77 for l in self._lines:
73 parts = self._ParsePossiblyWrappedParts(l, 3) 78 parts = self._ParsePossiblyWrappedParts(l, 3)
74 if not parts: 79 if not parts:
75 break 80 break
76 name, size_str, path = parts 81 name, size_str, path = parts
77 sym = models.Symbol('.bss', int(size_str[2:], 16), name=name, 82 sym = models.Symbol('.bss', int(size_str[2:], 16), name=name,
78 object_path=path) 83 object_path=path)
(...skipping 19 matching lines...) Expand all
98 # 0x02d4b294 guard variable for void GrProcessor::initClassID 103 # 0x02d4b294 guard variable for void GrProcessor::initClassID
99 # .data 0x0028c600 0x22d3468 104 # .data 0x0028c600 0x22d3468
100 # .data.rel.ro._ZTVN3gvr7android19ScopedJavaGlobalRefIP12_jfloatArrayEE 105 # .data.rel.ro._ZTVN3gvr7android19ScopedJavaGlobalRefIP12_jfloatArrayEE
101 # 0x02d1e668 0x10 ../../third_party/.../libfoo.a(bar.o) 106 # 0x02d1e668 0x10 ../../third_party/.../libfoo.a(bar.o)
102 # 0x02d1e668 vtable for gvr::android::GlobalRef<_jfloatArray*> 107 # 0x02d1e668 vtable for gvr::android::GlobalRef<_jfloatArray*>
103 # ** merge strings 108 # ** merge strings
104 # 0x0255fb00 0x1f2424 109 # 0x0255fb00 0x1f2424
105 # ** merge constants 110 # ** merge constants
106 # 0x0255fb00 0x8 111 # 0x0255fb00 0x8
107 # ** common 0x02db5700 0x13ab48 112 # ** common 0x02db5700 0x13ab48
108 self._SkipToLineWithPrefix('Memory map')
109 syms = self._symbols 113 syms = self._symbols
110 symbol_gap_count = 0 114 symbol_gap_count = 0
111 while True: 115 while True:
112 line = self._SkipToLineWithPrefix('.') 116 line = self._SkipToLineWithPrefix('.')
113 if not line: 117 if not line:
114 break 118 break
115 section_name = None 119 section_name = None
116 try: 120 try:
117 # Parse section name and size. 121 # Parse section name and size.
118 parts = self._ParsePossiblyWrappedParts(line, 3) 122 parts = self._ParsePossiblyWrappedParts(line, 3)
119 if not parts: 123 if not parts:
120 break 124 break
121 section_name, address, size_str = parts 125 section_name, section_address_str, section_size_str = parts
122 self._section_sizes[section_name] = int(size_str[2:], 16) 126 section_address = int(section_address_str[2:], 16)
127 section_size = int(section_size_str[2:], 16)
128 self._section_sizes[section_name] = section_size
123 if (section_name in ('.bss', '.rodata', '.text') or 129 if (section_name in ('.bss', '.rodata', '.text') or
124 section_name.startswith('.data')): 130 section_name.startswith('.data')):
125 logging.info('Parsing %s', section_name) 131 logging.info('Parsing %s', section_name)
126 if section_name == '.bss': 132 if section_name == '.bss':
133 # Common symbols have no address.
127 syms.extend(self._common_symbols) 134 syms.extend(self._common_symbols)
128 prefix_len = len(section_name) + 1 # + 1 for the trailing . 135 prefix_len = len(section_name) + 1 # + 1 for the trailing .
129 merge_symbol_start_address = 0 136 merge_symbol_start_address = section_address
130 sym_count_at_start = len(syms) 137 sym_count_at_start = len(syms)
131 line = next(self._lines) 138 line = next(self._lines)
132 # Parse section symbols. 139 # Parse section symbols.
133 while True: 140 while True:
134 if not line or line.isspace(): 141 if not line or line.isspace():
135 break 142 break
136 if line.startswith(' **'): 143 if line.startswith(' **'):
137 zero_index = line.find('0') 144 zero_index = line.find('0')
138 if zero_index == -1: 145 if zero_index == -1:
139 # Line wraps. 146 # Line wraps.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 else: 202 else:
196 logging.warning('First symbol of section had address -1') 203 logging.warning('First symbol of section had address -1')
197 address = 0 204 address = 0
198 205
199 merge_symbol_start_address = address + size 206 merge_symbol_start_address = address + size
200 else: 207 else:
201 address = int(address_str[2:], 16) 208 address = int(address_str[2:], 16)
202 # Finish off active address gap / merge section. 209 # Finish off active address gap / merge section.
203 if merge_symbol_start_address: 210 if merge_symbol_start_address:
204 merge_size = address - merge_symbol_start_address 211 merge_size = address - merge_symbol_start_address
205 logging.debug('Merge symbol of size %d found at:\n %r',
206 merge_size, syms[-1])
207 # Set size=0 so that it will show up as padding.
208 sym = models.Symbol(
209 section_name, 0,
210 address=address,
211 name='** symbol gap %d' % symbol_gap_count,
212 object_path=path)
213 symbol_gap_count += 1
214 syms.append(sym)
215 merge_symbol_start_address = 0 212 merge_symbol_start_address = 0
213 if merge_size > 0:
214 # merge_size == 0 for the initial symbol generally.
215 logging.debug('Merge symbol of size %d found at:\n %r',
216 merge_size, syms[-1])
217 # Set size=0 so that it will show up as padding.
218 sym = models.Symbol(
219 section_name, 0,
220 address=address,
221 name='** symbol gap %d' % symbol_gap_count,
222 object_path=path)
223 symbol_gap_count += 1
224 syms.append(sym)
216 225
217 sym = models.Symbol(section_name, size, address=address, 226 sym = models.Symbol(section_name, size, address=address,
218 name=name or mangled_name, object_path=path) 227 name=name or mangled_name, object_path=path)
219 syms.append(sym) 228 syms.append(sym)
229 section_end_address = section_address + section_size
230 if section_name != '.bss' and (
231 syms[-1].end_address < section_end_address):
232 # Set size=0 so that it will show up as padding.
233 sym = models.Symbol(
234 section_name, 0,
235 address=section_end_address,
236 name='** symbol gap %d (end of section)' % symbol_gap_count)
237 syms.append(sym)
220 logging.debug('Symbol count for %s: %d', section_name, 238 logging.debug('Symbol count for %s: %d', section_name,
221 len(syms) - sym_count_at_start) 239 len(syms) - sym_count_at_start)
222 except: 240 except:
223 logging.error('Problem line: %r', line) 241 logging.error('Problem line: %r', line)
224 logging.error('In section: %r', section_name) 242 logging.error('In section: %r', section_name)
225 raise 243 raise
OLDNEW
« no previous file with comments | « tools/binary_size/libsupersize/describe.py ('k') | tools/binary_size/libsupersize/models.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698