blob: ffff9649d25dc05859797cd71b30e02d65740b5a [file] [log] [blame]
Elliott Hughes5a93e882014-05-16 14:44:38 -07001#!/usr/bin/python
2
3import glob
4import os
5import re
Elliott Hughes5a93e882014-05-16 14:44:38 -07006import subprocess
7import sys
8
Dan Albert76212ee2014-08-13 13:04:28 -07009only_unwanted = False
10if len(sys.argv) > 1:
11 if sys.argv[1] in ('-u', '--unwanted'):
12 only_unwanted = True
13
Elliott Hughes5a93e882014-05-16 14:44:38 -070014toolchain = os.environ['ANDROID_TOOLCHAIN']
15arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain)
Dan Albert76212ee2014-08-13 13:04:28 -070016if arch == 'aarch64':
17 arch = 'arm64'
Elliott Hughes5a93e882014-05-16 14:44:38 -070018
19def GetSymbolsFromSo(so_file):
Elliott Hughes5a93e882014-05-16 14:44:38 -070020 # Example readelf output:
21 # 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf
22 # 266: 00016244 4 FUNC GLOBAL DEFAULT 8 dremf
23 # 267: 00019018 4 OBJECT GLOBAL DEFAULT 11 __fe_dfl_env
24 # 268: 00000000 0 FUNC GLOBAL DEFAULT UND __aeabi_dcmplt
25
26 r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (I?FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
27
28 symbols = set()
29
30 for line in subprocess.check_output(['readelf', '--dyn-syms', '-W', so_file]).split('\n'):
Elliott Hughese8e45342014-06-13 11:50:07 -070031 if ' HIDDEN ' in line or ' UND ' in line:
32 continue
33 m = r.match(line)
34 if m:
35 symbol = m.group(2)
36 symbol = re.sub('@.*', '', symbol)
37 symbols.add(symbol)
Elliott Hughes5a93e882014-05-16 14:44:38 -070038
39 return symbols
40
41def GetSymbolsFromAndroidSo(*files):
42 symbols = set()
43 for f in files:
44 symbols = symbols | GetSymbolsFromSo('%s/system/lib64/%s' % (os.environ['ANDROID_PRODUCT_OUT'], f))
45 return symbols
46
47def GetSymbolsFromSystemSo(*files):
48 symbols = set()
49 for f in files:
50 f = glob.glob('/lib/x86_64-linux-gnu/%s' % f)[-1]
51 symbols = symbols | GetSymbolsFromSo(f)
52 return symbols
53
Elliott Hughese8e45342014-06-13 11:50:07 -070054def MangleGlibcNameToBionic(name):
55 if name in glibc_to_bionic_names:
56 return glibc_to_bionic_names[name]
57 return name
58
Dan Albert76212ee2014-08-13 13:04:28 -070059def GetNdkIgnored():
60 global arch
61 symbols = set()
62 files = glob.glob('%s/ndk/build/tools/unwanted-symbols/%s/*' %
63 (os.getenv('ANDROID_BUILD_TOP'), arch))
64 for f in files:
65 symbols |= set(open(f, 'r').read().splitlines())
66 return symbols
67
Elliott Hughese8e45342014-06-13 11:50:07 -070068glibc_to_bionic_names = {
69 '__res_init': 'res_init',
70 '__res_mkquery': 'res_mkquery',
71 '__res_query': 'res_query',
72 '__res_search': 'res_search',
73}
74
Elliott Hughes5a93e882014-05-16 14:44:38 -070075glibc = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*')
76bionic = GetSymbolsFromAndroidSo('libc.so', 'libm.so')
Dan Albert76212ee2014-08-13 13:04:28 -070077ndk_ignored = GetNdkIgnored()
Elliott Hughes5a93e882014-05-16 14:44:38 -070078
Elliott Hughese8e45342014-06-13 11:50:07 -070079glibc = map(MangleGlibcNameToBionic, glibc)
80
Elliott Hughes5a93e882014-05-16 14:44:38 -070081# bionic includes various BSD symbols to ease porting other BSD-licensed code.
82bsd_stuff = set([
Elliott Hughes45bf4c32014-05-22 18:53:21 -070083 'basename_r',
84 'dirname_r',
85 'fgetln',
86 'fpurge',
87 'funopen',
88 'gamma_r',
89 'gammaf_r',
Elliott Hughes5a93e882014-05-16 14:44:38 -070090 'getprogname',
91 'setprogname',
92 'strlcat',
93 'strlcpy',
Elliott Hughes45bf4c32014-05-22 18:53:21 -070094 'sys_signame',
Elliott Hughes5a93e882014-05-16 14:44:38 -070095 'wcslcat',
96 'wcslcpy'
97])
98# Some symbols are part of the FORTIFY implementation.
99FORTIFY_stuff = set([
100 '__FD_CLR_chk',
101 '__FD_ISSET_chk',
102 '__FD_SET_chk',
103 '__stack_chk_guard',
104 '__stpncpy_chk2',
105 '__strchr_chk',
106 '__strlcat_chk',
107 '__strlcpy_chk',
108 '__strlen_chk',
109 '__strncpy_chk2',
110 '__strrchr_chk',
111 '__umask_chk'
112])
Elliott Hughesb497c432014-05-20 20:37:56 -0700113# Some symbols are used to implement public macros.
114macro_stuff = set([
115 '__assert2',
116 '__errno',
117 '__fe_dfl_env',
118 '__get_h_errno',
Dan Albert76212ee2014-08-13 13:04:28 -0700119 '__fpclassifyd',
120 '__isfinite',
121 '__isfinitef',
122 '__isfinitel',
123 '__isnormal',
124 '__isnormalf',
125 '__isnormall',
126 '__sF',
127 '__pthread_cleanup_pop',
128 '__pthread_cleanup_push',
Elliott Hughesb497c432014-05-20 20:37:56 -0700129])
Elliott Hughes5a93e882014-05-16 14:44:38 -0700130# bionic exposes various Linux features that glibc doesn't.
131linux_stuff = set([
132 'getauxval',
133 'gettid',
134 'tgkill'
135])
136# Some standard stuff isn't yet in the versions of glibc we're using.
137std_stuff = set([
Elliott Hughesf6b1d432014-06-06 15:20:50 -0700138 'at_quick_exit',
139 'c16rtomb',
140 'c32rtomb',
141 'mbrtoc16',
142 'mbrtoc32',
Elliott Hughes5a93e882014-05-16 14:44:38 -0700143])
144# These have mangled names in glibc, with a macro taking the "obvious" name.
145weird_stuff = set([
146 'fstat',
147 'fstat64',
148 'fstatat',
149 'fstatat64',
150 'isfinite',
151 'isfinitef',
152 'isfinitel',
153 'isnormal',
154 'isnormalf',
155 'isnormall',
156 'lstat',
157 'lstat64',
158 'mknod',
159 'mknodat',
160 'stat',
161 'stat64',
Dan Albert76212ee2014-08-13 13:04:28 -0700162 'optreset',
163 'sigsetjmp',
164])
165# These exist in glibc, but under slightly different names (generally one extra
166# or one fewer _). TODO: check against glibc names.
167libresolv_stuff = set([
168 '__res_send_setqhook',
169 '__res_send_setrhook',
170 '_resolv_flush_cache_for_net',
171 '_resolv_set_nameservers_for_net',
172 'dn_expand',
173 'nsdispatch',
174])
175# libstdc++ stuff we took over.
176libstdcxx_stuff = set([
177 # new, delete, nothrow
178 '_ZSt7nothrow',
179 '_ZdaPv',
180 '_ZdaPvRKSt9nothrow_t',
181 '_ZdlPv',
182 '_ZdlPvRKSt9nothrow_t',
183 '_Znam',
184 '_ZnamRKSt9nothrow_t',
185 '_Znwm',
186 '_ZnwmRKSt9nothrow_t',
187
188 '__cxa_guard_abort',
189 '__cxa_guard_acquire',
190 '__cxa_guard_release',
191 '__cxa_pure_virtual',
192])
193# Implementation details we know we export (and can't get away from).
194known = set([
195 '_ctype_',
196 '__libc_init',
Elliott Hughes5a93e882014-05-16 14:44:38 -0700197])
198
Dan Albert76212ee2014-08-13 13:04:28 -0700199if not only_unwanted:
200 print 'glibc:'
201 for symbol in sorted(glibc):
202 print symbol
Elliott Hughes5a93e882014-05-16 14:44:38 -0700203
Dan Albert76212ee2014-08-13 13:04:28 -0700204 print
205 print 'bionic:'
206 for symbol in sorted(bionic):
207 print symbol
Elliott Hughes5a93e882014-05-16 14:44:38 -0700208
Dan Albert76212ee2014-08-13 13:04:28 -0700209 print
210 print 'in bionic but not glibc:'
211
212allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff |
213 std_stuff | weird_stuff | libresolv_stuff | libstdcxx_stuff |
214 known)
Elliott Hughesb497c432014-05-20 20:37:56 -0700215for symbol in sorted((bionic - allowed_stuff).difference(glibc)):
Dan Albert76212ee2014-08-13 13:04:28 -0700216 if symbol in ndk_ignored:
217 symbol += '*'
Elliott Hughes5a93e882014-05-16 14:44:38 -0700218 print symbol
219
220sys.exit(0)