|  | #!/usr/bin/env python | 
|  | # Copyright 2018 The Chromium Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | """Find incompatible symbols in glibc and output a list of replacements. | 
|  | """ | 
|  |  | 
|  | import re | 
|  | import sys | 
|  |  | 
|  | # This constant comes from https://crbug.com/580892 | 
|  | MAX_ALLOWED_GLIBC_VERSION = [2, 17] | 
|  |  | 
|  |  | 
|  | def get_replacements(nm_file, max_allowed_glibc_version): | 
|  | symbol_format = re.compile('\S+ \S+ ([^@]+)@@?(\S+)\n') | 
|  | version_format = re.compile('GLIBC_[0-9\.]+') | 
|  | symbols = {} | 
|  | for line in nm_file: | 
|  | m = re.match(symbol_format, line) | 
|  | symbol = m.group(1) | 
|  | version = m.group(2) | 
|  | if not re.match(version_format, version): | 
|  | continue | 
|  | if symbol in symbols: | 
|  | symbols[symbol].add(version) | 
|  | else: | 
|  | symbols[symbol] = set([version]) | 
|  |  | 
|  | replacements = [] | 
|  | for symbol, versions in symbols.iteritems(): | 
|  | if len(versions) <= 1: | 
|  | continue | 
|  | versions_parsed = [[ | 
|  | int(part) for part in version.lstrip('GLIBC_').split('.') | 
|  | ] for version in versions] | 
|  | if (max(versions_parsed) > max_allowed_glibc_version and | 
|  | min(versions_parsed) <= max_allowed_glibc_version): | 
|  | # Use the newest allowed version of the symbol. | 
|  | replacement_version_parsed = max([ | 
|  | version for version in versions_parsed | 
|  | if version <= max_allowed_glibc_version | 
|  | ]) | 
|  | replacement_version = 'GLIBC_' + '.'.join( | 
|  | [str(part) for part in replacement_version_parsed]) | 
|  | replacements.append('__asm__(".symver %s, %s@%s");' % | 
|  | (symbol, symbol, replacement_version)) | 
|  | return sorted(replacements) | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | replacements = get_replacements(sys.stdin, MAX_ALLOWED_GLIBC_VERSION) | 
|  | if replacements: | 
|  | print('// Chromium-specific hack.') | 
|  | print('// See explanation in sysroot-creator.sh.') | 
|  | for replacement in replacements: | 
|  | print replacement |