| Index: tools/cygprofile/symbol_extractor.py | 
| diff --git a/tools/cygprofile/symbol_extractor.py b/tools/cygprofile/symbol_extractor.py | 
| index 81c6e66d8fbca2805ba8b7c673d12eb18a3d8d14..dbd625b2979e9cdb0b7f6f8a272f112e544d291b 100755 | 
| --- a/tools/cygprofile/symbol_extractor.py | 
| +++ b/tools/cygprofile/symbol_extractor.py | 
| @@ -6,6 +6,7 @@ | 
| """Utilities to get and manipulate symbols from a binary.""" | 
|  | 
| import collections | 
| +import logging | 
| import os | 
| import re | 
| import subprocess | 
| @@ -17,6 +18,7 @@ sys.path.insert( | 
| 'scripts')) | 
| import symbol | 
|  | 
| +_MAX_WARNINGS_TO_PRINT = 200 | 
|  | 
| SymbolInfo = collections.namedtuple('SymbolInfo', ('name', 'offset', 'size', | 
| 'section')) | 
| @@ -106,6 +108,21 @@ def GroupSymbolInfosByOffset(symbol_infos): | 
| offset_to_symbol_infos[symbol_info.offset].append(symbol_info) | 
| return dict(offset_to_symbol_infos) | 
|  | 
| +def GroupSymbolInfosByName(symbol_infos): | 
| +  """Create a dict {name: [symbol_info1, ...], ...}. | 
| + | 
| +  A symbol can have several offsets, this is a 1-to-many relationship. | 
| + | 
| +  Args: | 
| +    symbol_infos: iterable of SymbolInfo instances | 
| + | 
| +  Returns: | 
| +    a dict {name: [symbol_info1, ...], ...} | 
| +  """ | 
| +  name_to_symbol_infos = collections.defaultdict(list) | 
| +  for symbol_info in symbol_infos: | 
| +    name_to_symbol_infos[symbol_info.name].append(symbol_info) | 
| +  return dict(name_to_symbol_infos) | 
|  | 
| def CreateNameToSymbolInfo(symbol_infos): | 
| """Create a dict {name: symbol_info, ...}. | 
| @@ -115,5 +132,23 @@ def CreateNameToSymbolInfo(symbol_infos): | 
|  | 
| Returns: | 
| a dict {name: symbol_info, ...} | 
| +    If a symbol name corresponds to more than one symbol_info, the symbol_info | 
| +    with the lowest offset is chosen. | 
| """ | 
| -  return {symbol_info.name: symbol_info for symbol_info in symbol_infos} | 
| +  #TODO(azarchs): move the functionality in this method into check_orderfile. | 
| +  symbol_infos_by_name = {} | 
| +  collision_count = 0 | 
| +  for infos in GroupSymbolInfosByName(symbol_infos).itervalues(): | 
| +    first_symbol_info = min(infos, key=lambda x:x.offset) | 
| +    symbol_infos_by_name[first_symbol_info.name] = first_symbol_info | 
| +    if len(infos) > 1: | 
| +      collision_count += 1 | 
| +      if collision_count <= _MAX_WARNINGS_TO_PRINT: | 
| +        logging.warning('Symbol %s appears at %d offsets: %s' % | 
| +                        (first_symbol_info.name, | 
| +                         len(infos), | 
| +                         ','.join([hex(x.offset) for x in infos]))) | 
| +  if collision_count > _MAX_WARNINGS_TO_PRINT: | 
| +    logging.warning('%d symbols at multiple offsets.  First %d shown.' % | 
| +                    (collision_count, _MAX_WARNINGS_TO_PRINT)) | 
| +  return symbol_infos_by_name | 
|  |