blob: d79a89b98bf67e64a8b7532f62d2ef23292d1fb4 [file] [log] [blame]
#!/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.
"""
from __future__ import print_function
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)