blob: a2f2ccba653f469037c6325d3e702cdad9277a15 [file] [log] [blame]
Elliott Hughesa0ee0782013-01-30 19:06:37 -08001#!/usr/bin/python
2
3import glob
4import os
5import re
6import string
7import subprocess
8import sys
9
10toolchain = os.environ['ANDROID_TOOLCHAIN']
11arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain)
12
13sys.stderr.write('Checking symbols for arch "%s"...\n' % arch)
14
15def GetSymbols(library, functions_or_variables):
Elliott Hughesec738d92015-05-11 12:10:40 -070016 global api
17 global arch
18
Elliott Hughesa0ee0782013-01-30 19:06:37 -080019 api = '9'
20 if library == 'libm' and arch == 'arm':
21 api = '3'
Elliott Hughesec738d92015-05-11 12:10:40 -070022
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 Hughesa0ee0782013-01-30 19:06:37 -080031 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
38def CheckSymbols(library, functions_or_variables):
39 expected_symbols = GetSymbols(library, functions_or_variables)
40
Elliott Hughesec738d92015-05-11 12:10:40 -070041 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 Hughesa0ee0782013-01-30 19:06:37 -080046
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 Hughesec738d92015-05-11 12:10:40 -070057 for line in subprocess.check_output(['readelf', '-W', '--dyn-syms', so_file]).split('\n'):
Elliott Hughesa0ee0782013-01-30 19:06:37 -080058 m = r.match(line)
59 if m:
60 if m.group(1) == 'FUNC' and functions_or_variables == 'functions':
61 actual_symbols.add(m.group(2))
62 elif m.group(1) == 'OBJECT' and functions_or_variables == 'variables':
63 actual_symbols.add(m.group(2))
64 #else:
65 #print 'ignoring: ' % line
66
67 missing = expected_symbols - actual_symbols
68 if len(missing) > 0:
69 sys.stderr.write('%d missing %s in %s for %s:\n' % (len(missing), functions_or_variables, library, arch))
70 for miss in sorted(missing):
71 sys.stderr.write(' %s\n' % miss)
72
Elliott Hughesec738d92015-05-11 12:10:40 -070073 extra = actual_symbols - expected_symbols
74 if len(extra) > 0:
75 sys.stderr.write('%d extra %s in %s for %s:\n' % (len(extra), functions_or_variables, library, arch))
76 for s in sorted(extra):
77 sys.stderr.write(' %s\n' % s)
78
Elliott Hughesa0ee0782013-01-30 19:06:37 -080079 return len(missing) == 0
80
81CheckSymbols("libc", "functions")
82CheckSymbols("libc", "variables")
83CheckSymbols("libm", "functions")
84CheckSymbols("libm", "variables")
85
86sys.exit(0)