blob: 153b840366add234c2305ccea422477e6bcece70 [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
Elliott Hughes6370aed2014-11-05 16:22:26 -080019def GetSymbolsFromTxt(txt_file):
20 symbols = set()
21 f = open(txt_file, 'r')
22 for line in f.read().splitlines():
23 symbols.add(line)
24 f.close()
25 return symbols
26
Elliott Hughes5a93e882014-05-16 14:44:38 -070027def GetSymbolsFromSo(so_file):
Elliott Hughes5a93e882014-05-16 14:44:38 -070028 # Example readelf output:
29 # 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf
30 # 266: 00016244 4 FUNC GLOBAL DEFAULT 8 dremf
31 # 267: 00019018 4 OBJECT GLOBAL DEFAULT 11 __fe_dfl_env
32 # 268: 00000000 0 FUNC GLOBAL DEFAULT UND __aeabi_dcmplt
33
34 r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (I?FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
35
36 symbols = set()
37
38 for line in subprocess.check_output(['readelf', '--dyn-syms', '-W', so_file]).split('\n'):
Elliott Hughese8e45342014-06-13 11:50:07 -070039 if ' HIDDEN ' in line or ' UND ' in line:
40 continue
41 m = r.match(line)
42 if m:
43 symbol = m.group(2)
44 symbol = re.sub('@.*', '', symbol)
45 symbols.add(symbol)
Elliott Hughes5a93e882014-05-16 14:44:38 -070046
47 return symbols
48
49def GetSymbolsFromAndroidSo(*files):
50 symbols = set()
51 for f in files:
52 symbols = symbols | GetSymbolsFromSo('%s/system/lib64/%s' % (os.environ['ANDROID_PRODUCT_OUT'], f))
53 return symbols
54
55def GetSymbolsFromSystemSo(*files):
56 symbols = set()
57 for f in files:
58 f = glob.glob('/lib/x86_64-linux-gnu/%s' % f)[-1]
59 symbols = symbols | GetSymbolsFromSo(f)
60 return symbols
61
Elliott Hughese8e45342014-06-13 11:50:07 -070062def MangleGlibcNameToBionic(name):
63 if name in glibc_to_bionic_names:
64 return glibc_to_bionic_names[name]
65 return name
66
Dan Albert76212ee2014-08-13 13:04:28 -070067def GetNdkIgnored():
68 global arch
69 symbols = set()
70 files = glob.glob('%s/ndk/build/tools/unwanted-symbols/%s/*' %
71 (os.getenv('ANDROID_BUILD_TOP'), arch))
72 for f in files:
73 symbols |= set(open(f, 'r').read().splitlines())
74 return symbols
75
Elliott Hughese8e45342014-06-13 11:50:07 -070076glibc_to_bionic_names = {
77 '__res_init': 'res_init',
78 '__res_mkquery': 'res_mkquery',
79 '__res_query': 'res_query',
80 '__res_search': 'res_search',
Dan Albert2320b022014-08-21 11:36:07 -070081 '__xpg_basename': '__gnu_basename',
Elliott Hughese8e45342014-06-13 11:50:07 -070082}
83
Elliott Hughes03932212014-12-04 11:24:48 -080084glibc = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*', 'libutil.so.*')
Elliott Hughes5a93e882014-05-16 14:44:38 -070085bionic = GetSymbolsFromAndroidSo('libc.so', 'libm.so')
Elliott Hughes6370aed2014-11-05 16:22:26 -080086posix = GetSymbolsFromTxt(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'posix-2013.txt'))
Dan Albert76212ee2014-08-13 13:04:28 -070087ndk_ignored = GetNdkIgnored()
Elliott Hughes5a93e882014-05-16 14:44:38 -070088
Elliott Hughes03932212014-12-04 11:24:48 -080089glibc = set(map(MangleGlibcNameToBionic, glibc))
Elliott Hughese8e45342014-06-13 11:50:07 -070090
Elliott Hughes5a93e882014-05-16 14:44:38 -070091# bionic includes various BSD symbols to ease porting other BSD-licensed code.
92bsd_stuff = set([
Elliott Hughes45bf4c32014-05-22 18:53:21 -070093 'basename_r',
94 'dirname_r',
95 'fgetln',
96 'fpurge',
97 'funopen',
98 'gamma_r',
99 'gammaf_r',
Elliott Hughes5a93e882014-05-16 14:44:38 -0700100 'getprogname',
101 'setprogname',
102 'strlcat',
103 'strlcpy',
Elliott Hughes45bf4c32014-05-22 18:53:21 -0700104 'sys_signame',
Elliott Hughes5a93e882014-05-16 14:44:38 -0700105 'wcslcat',
106 'wcslcpy'
107])
108# Some symbols are part of the FORTIFY implementation.
109FORTIFY_stuff = set([
110 '__FD_CLR_chk',
111 '__FD_ISSET_chk',
112 '__FD_SET_chk',
113 '__stack_chk_guard',
114 '__stpncpy_chk2',
115 '__strchr_chk',
116 '__strlcat_chk',
117 '__strlcpy_chk',
118 '__strlen_chk',
119 '__strncpy_chk2',
120 '__strrchr_chk',
121 '__umask_chk'
122])
Elliott Hughesb497c432014-05-20 20:37:56 -0700123# Some symbols are used to implement public macros.
124macro_stuff = set([
125 '__assert2',
126 '__errno',
127 '__fe_dfl_env',
128 '__get_h_errno',
Dan Albert76212ee2014-08-13 13:04:28 -0700129 '__fpclassifyd',
130 '__isfinite',
131 '__isfinitef',
132 '__isfinitel',
133 '__isnormal',
134 '__isnormalf',
135 '__isnormall',
136 '__sF',
137 '__pthread_cleanup_pop',
138 '__pthread_cleanup_push',
Elliott Hughesb497c432014-05-20 20:37:56 -0700139])
Elliott Hughes5a93e882014-05-16 14:44:38 -0700140# bionic exposes various Linux features that glibc doesn't.
141linux_stuff = set([
142 'getauxval',
143 'gettid',
144 'tgkill'
145])
146# Some standard stuff isn't yet in the versions of glibc we're using.
147std_stuff = set([
Elliott Hughesf6b1d432014-06-06 15:20:50 -0700148 'at_quick_exit',
149 'c16rtomb',
150 'c32rtomb',
151 'mbrtoc16',
152 'mbrtoc32',
Elliott Hughes5a93e882014-05-16 14:44:38 -0700153])
154# These have mangled names in glibc, with a macro taking the "obvious" name.
155weird_stuff = set([
156 'fstat',
157 'fstat64',
158 'fstatat',
159 'fstatat64',
160 'isfinite',
161 'isfinitef',
162 'isfinitel',
163 'isnormal',
164 'isnormalf',
165 'isnormall',
166 'lstat',
167 'lstat64',
168 'mknod',
169 'mknodat',
170 'stat',
171 'stat64',
Dan Albert76212ee2014-08-13 13:04:28 -0700172 'optreset',
173 'sigsetjmp',
174])
175# These exist in glibc, but under slightly different names (generally one extra
176# or one fewer _). TODO: check against glibc names.
177libresolv_stuff = set([
178 '__res_send_setqhook',
179 '__res_send_setrhook',
180 '_resolv_flush_cache_for_net',
181 '_resolv_set_nameservers_for_net',
182 'dn_expand',
183 'nsdispatch',
184])
Dan Albert76212ee2014-08-13 13:04:28 -0700185# Implementation details we know we export (and can't get away from).
186known = set([
187 '_ctype_',
188 '__libc_init',
Elliott Hughes5a93e882014-05-16 14:44:38 -0700189])
190
Dan Albert76212ee2014-08-13 13:04:28 -0700191if not only_unwanted:
Elliott Hughes03932212014-12-04 11:24:48 -0800192 #print 'glibc:'
193 #for symbol in sorted(glibc):
194 # print symbol
195 #print
Elliott Hughes5a93e882014-05-16 14:44:38 -0700196
Elliott Hughes03932212014-12-04 11:24:48 -0800197 #print 'bionic:'
198 #for symbol in sorted(bionic):
199 # print symbol
200 #print
Elliott Hughes5a93e882014-05-16 14:44:38 -0700201
Elliott Hughes03932212014-12-04 11:24:48 -0800202 print 'in glibc (but not posix) but not bionic:'
203 for symbol in sorted((glibc - posix).difference(bionic)):
Elliott Hughes6370aed2014-11-05 16:22:26 -0800204 print symbol
Elliott Hughes6370aed2014-11-05 16:22:26 -0800205 print
Elliott Hughes03932212014-12-04 11:24:48 -0800206
207 print 'in posix (and implemented in glibc) but not bionic:'
208 for symbol in sorted((posix.intersection(glibc)).difference(bionic)):
209 print symbol
210 print
211
Dan Albert76212ee2014-08-13 13:04:28 -0700212 print 'in bionic but not glibc:'
213
214allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff |
Dan Albertfd5ee9a2014-08-15 14:20:04 -0700215 std_stuff | weird_stuff | libresolv_stuff | known)
Elliott Hughesb497c432014-05-20 20:37:56 -0700216for symbol in sorted((bionic - allowed_stuff).difference(glibc)):
Dan Albert76212ee2014-08-13 13:04:28 -0700217 if symbol in ndk_ignored:
218 symbol += '*'
Elliott Hughes5a93e882014-05-16 14:44:38 -0700219 print symbol
220
221sys.exit(0)