OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Utilities to get and manipulate symbols from a binary.""" | 6 """Utilities to get and manipulate symbols from a binary.""" |
7 | 7 |
8 import collections | 8 import collections |
9 import logging | |
9 import os | 10 import os |
10 import re | 11 import re |
11 import subprocess | 12 import subprocess |
12 import sys | 13 import sys |
13 | 14 |
14 sys.path.insert( | 15 sys.path.insert( |
15 0, os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, | 16 0, os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, |
16 'third_party', 'android_platform', 'development', | 17 'third_party', 'android_platform', 'development', |
17 'scripts')) | 18 'scripts')) |
18 import symbol | 19 import symbol |
19 | 20 |
21 _MAX_WARNINGS_TO_PRINT = 200 | |
20 | 22 |
21 SymbolInfo = collections.namedtuple('SymbolInfo', ('name', 'offset', 'size', | 23 SymbolInfo = collections.namedtuple('SymbolInfo', ('name', 'offset', 'size', |
22 'section')) | 24 'section')) |
23 | 25 |
24 def SetArchitecture(arch): | 26 def SetArchitecture(arch): |
25 """Set the architecture for binaries to be symbolized.""" | 27 """Set the architecture for binaries to be symbolized.""" |
26 symbol.ARCH = arch | 28 symbol.ARCH = arch |
27 | 29 |
28 | 30 |
29 def _FromObjdumpLine(line): | 31 def _FromObjdumpLine(line): |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 symbol_infos: iterable of SymbolInfo instances | 101 symbol_infos: iterable of SymbolInfo instances |
100 | 102 |
101 Returns: | 103 Returns: |
102 a dict {offset: [symbol_info1, ...], ...} | 104 a dict {offset: [symbol_info1, ...], ...} |
103 """ | 105 """ |
104 offset_to_symbol_infos = collections.defaultdict(list) | 106 offset_to_symbol_infos = collections.defaultdict(list) |
105 for symbol_info in symbol_infos: | 107 for symbol_info in symbol_infos: |
106 offset_to_symbol_infos[symbol_info.offset].append(symbol_info) | 108 offset_to_symbol_infos[symbol_info.offset].append(symbol_info) |
107 return dict(offset_to_symbol_infos) | 109 return dict(offset_to_symbol_infos) |
108 | 110 |
111 def GroupSymbolInfosByName(symbol_infos): | |
112 """Create a dict {name: [symbol_info1, ...], ...}. | |
113 | |
114 A a symbol can have several offsets, this is a 1-to-many relationship. | |
Benoit L
2015/02/23 16:02:48
Typo: A -> As
azarchs
2015/02/23 16:10:08
Done.
| |
115 | |
116 Args: | |
117 symbol_infos: iterable of SymbolInfo instances | |
118 | |
119 Returns: | |
120 a dict {name: [symbol_info1, ...], ...} | |
121 """ | |
122 name_to_symbol_infos = collections.defaultdict(list) | |
123 for symbol_info in symbol_infos: | |
124 name_to_symbol_infos[symbol_info.name].append(symbol_info) | |
125 return dict(name_to_symbol_infos) | |
109 | 126 |
110 def CreateNameToSymbolInfo(symbol_infos): | 127 def CreateNameToSymbolInfo(symbol_infos): |
111 """Create a dict {name: symbol_info, ...}. | 128 """Create a dict {name: symbol_info, ...}. |
112 | 129 |
113 Args: | 130 Args: |
114 symbol_infos: iterable of SymbolInfo instances | 131 symbol_infos: iterable of SymbolInfo instances |
115 | 132 |
116 Returns: | 133 Returns: |
117 a dict {name: symbol_info, ...} | 134 a dict {name: symbol_info, ...} |
135 If a symbol name corresponds to more than one symbol_info, the symbol_info | |
136 with the lowest offset is chosen. | |
118 """ | 137 """ |
119 return {symbol_info.name: symbol_info for symbol_info in symbol_infos} | 138 #TODO(azarchs): move the functionality in this method into check_orderfile. |
139 symbol_infos_by_name = {} | |
140 collision_count = 0 | |
141 for infos in GroupSymbolInfosByName(symbol_infos).itervalues(): | |
142 first_symbol_info = min(infos, key=lambda x:x.offset) | |
143 symbol_infos_by_name[first_symbol_info.name] = first_symbol_info | |
144 if len(infos) > 1: | |
145 collision_count += 1 | |
146 if collision_count <= _MAX_WARNINGS_TO_PRINT: | |
147 logging.warning('Symbol %s appears at %d offsets: %s' % | |
148 (first_symbol_info.name, | |
149 len(infos), | |
150 ','.join([hex(x.offset) for x in infos]))) | |
151 if collision_count > _MAX_WARNINGS_TO_PRINT: | |
152 logging.warning('%d symbols at multiple offsets. First %d shown.' % | |
153 (collision_count, _MAX_WARNINGS_TO_PRINT)) | |
154 return symbol_infos_by_name | |
OLD | NEW |