Chromium Code Reviews| 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 |