Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | |
| 3 | import glob |
| 4 | import os |
| 5 | import re |
| 6 | import string |
| 7 | import subprocess |
| 8 | import sys |
| 9 | |
| 10 | toolchain = os.environ['ANDROID_TOOLCHAIN'] |
| 11 | arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain) |
| 12 | |
| 13 | sys.stderr.write('Checking symbols for arch "%s"...\n' % arch) |
| 14 | |
| 15 | def GetSymbols(library, functions_or_variables): |
Elliott Hughes | ec738d9 | 2015-05-11 12:10:40 -0700 | [diff] [blame] | 16 | global api |
| 17 | global arch |
| 18 | |
Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 19 | api = '9' |
| 20 | if library == 'libm' and arch == 'arm': |
| 21 | api = '3' |
Elliott Hughes | ec738d9 | 2015-05-11 12:10:40 -0700 | [diff] [blame] | 22 | |
| 23 | # There were no 64-bit ABIs before API level 21. |
| 24 | if '64' in arch: |
| 25 | api = '21' |
| 26 | |
| 27 | # What GCC calls aarch64, Android calls arm64. |
| 28 | if arch == 'aarch64': |
| 29 | arch = 'arm64' |
| 30 | |
Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 31 | path = '%s/development/ndk/platforms/android-%s/arch-%s/symbols/%s.so.%s.txt' % (os.environ['ANDROID_BUILD_TOP'], api, arch, library, functions_or_variables) |
| 32 | symbols = set() |
| 33 | for line in open(path, 'r'): |
| 34 | symbols.add(line.rstrip()) |
| 35 | #sys.stdout.write('%d %s in %s for %s\n' % (len(symbols), functions_or_variables, library, arch)) |
| 36 | return symbols |
| 37 | |
| 38 | def CheckSymbols(library, functions_or_variables): |
| 39 | expected_symbols = GetSymbols(library, functions_or_variables) |
| 40 | |
Elliott Hughes | ec738d9 | 2015-05-11 12:10:40 -0700 | [diff] [blame] | 41 | lib_dir = 'lib' |
| 42 | if '64' in arch: |
| 43 | lib_dir = 'lib64' |
| 44 | |
| 45 | so_file = '%s/system/%s/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], lib_dir, library) |
Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 46 | |
| 47 | # Example readelf output: |
| 48 | # 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf |
| 49 | # 266: 00016244 4 FUNC GLOBAL DEFAULT 8 dremf |
| 50 | # 267: 00019018 4 OBJECT GLOBAL DEFAULT 11 __fe_dfl_env |
| 51 | # 268: 00000000 0 FUNC GLOBAL DEFAULT UND __aeabi_dcmplt |
| 52 | |
| 53 | |
| 54 | r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)') |
| 55 | |
| 56 | actual_symbols = set() |
Elliott Hughes | ec738d9 | 2015-05-11 12:10:40 -0700 | [diff] [blame] | 57 | for line in subprocess.check_output(['readelf', '-W', '--dyn-syms', so_file]).split('\n'): |
Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 58 | m = r.match(line) |
| 59 | if m: |
Dmitriy Ivanov | 6cda074 | 2015-06-04 10:12:37 -0700 | [diff] [blame] | 60 | symbol = string.split(m.group(2), '@')[0] |
Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 61 | if m.group(1) == 'FUNC' and functions_or_variables == 'functions': |
Dmitriy Ivanov | 6cda074 | 2015-06-04 10:12:37 -0700 | [diff] [blame] | 62 | actual_symbols.add(symbol) |
Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 63 | elif m.group(1) == 'OBJECT' and functions_or_variables == 'variables': |
Dmitriy Ivanov | 6cda074 | 2015-06-04 10:12:37 -0700 | [diff] [blame] | 64 | actual_symbols.add(symbol) |
Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 65 | #else: |
| 66 | #print 'ignoring: ' % line |
| 67 | |
| 68 | missing = expected_symbols - actual_symbols |
| 69 | if len(missing) > 0: |
| 70 | sys.stderr.write('%d missing %s in %s for %s:\n' % (len(missing), functions_or_variables, library, arch)) |
| 71 | for miss in sorted(missing): |
| 72 | sys.stderr.write(' %s\n' % miss) |
| 73 | |
Elliott Hughes | ec738d9 | 2015-05-11 12:10:40 -0700 | [diff] [blame] | 74 | extra = actual_symbols - expected_symbols |
| 75 | if len(extra) > 0: |
| 76 | sys.stderr.write('%d extra %s in %s for %s:\n' % (len(extra), functions_or_variables, library, arch)) |
| 77 | for s in sorted(extra): |
| 78 | sys.stderr.write(' %s\n' % s) |
| 79 | |
Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 80 | return len(missing) == 0 |
| 81 | |
| 82 | CheckSymbols("libc", "functions") |
| 83 | CheckSymbols("libc", "variables") |
| 84 | CheckSymbols("libm", "functions") |
| 85 | CheckSymbols("libm", "variables") |
| 86 | |
| 87 | sys.exit(0) |