summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/build/linux/sysroot_scripts/find_incompatible_glibc_symbols.py
blob: 1e0b5f614a355225e11b536d25d8ceb7d9743b88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/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):
  version_format = re.compile('GLIBC_[0-9\.]+')
  symbols = {}
  for line in nm_file:
    # Some versions of nm have a bug where the version gets printed twice.
    # Since the symbol may either be formatted like "name@@VERSION" or
    # "name@@VERSION@@VERSION", handle both cases.
    line = line.replace('@@', '@')
    symver = line.split('@')
    symbol = symver[0].split(' ')[-1]
    version = symver[-1]
    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.items():
    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)