1#!/usr/bin/env python2 2# 3# Copyright (C) 2015 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the 'License'); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an 'AS IS' BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17# pylint: disable=bad-indentation,bad-continuation 18import glob 19import os 20import re 21import sys 22 23import symbols 24 25only_unwanted = False 26if len(sys.argv) > 1: 27 if sys.argv[1] in ('-u', '--unwanted'): 28 only_unwanted = True 29 30toolchain = os.environ['ANDROID_TOOLCHAIN'] 31arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain) 32if arch == 'aarch64': 33 arch = 'arm64' 34 35def MangleGlibcNameToBionic(name): 36 if name in glibc_to_bionic_names: 37 return glibc_to_bionic_names[name] 38 return name 39 40def GetNdkIgnored(arch): # pylint: disable=redefined-outer-name 41 ignored_symbols = set() 42 files = glob.glob('%s/ndk/build/tools/unwanted-symbols/%s/*' % 43 (os.getenv('ANDROID_BUILD_TOP'), arch)) 44 for f in files: 45 ignored_symbols |= set(open(f, 'r').read().splitlines()) 46 return ignored_symbols 47 48glibc_to_bionic_names = { 49 '__res_init': 'res_init', 50 '__res_mkquery': 'res_mkquery', 51 '__res_query': 'res_query', 52 '__res_search': 'res_search', 53 '__xpg_basename': '__gnu_basename', 54} 55 56glibc = symbols.GetFromSystemSo([ 57 'libc.so.*', 58 'librt.so.*', 59 'libpthread.so.*', 60 'libresolv.so.*', 61 'libm.so.*', 62 'libutil.so.*', 63]) 64 65bionic = symbols.GetFromAndroidSo(['libc.so', 'libm.so']) 66this_dir = os.path.dirname(os.path.realpath(__file__)) 67posix = symbols.GetFromTxt(os.path.join(this_dir, 'posix-2013.txt')) 68ndk_ignored = GetNdkIgnored(arch) 69 70glibc = set(map(MangleGlibcNameToBionic, glibc)) 71 72# bionic includes various BSD symbols to ease porting other BSD-licensed code. 73bsd_stuff = set([ 74 'basename_r', 75 'dirname_r', 76 'fgetln', 77 'fpurge', 78 'funopen', 79 'gamma_r', 80 'gammaf_r', 81 'getprogname', 82 'setprogname', 83 'strlcat', 84 'strlcpy', 85 'sys_signame', 86 'wcslcat', 87 'wcslcpy' 88]) 89# Some symbols are part of the FORTIFY implementation. 90FORTIFY_stuff = set([ 91 '__FD_CLR_chk', 92 '__FD_ISSET_chk', 93 '__FD_SET_chk', 94 '__stack_chk_guard', 95 '__stpncpy_chk2', 96 '__strchr_chk', 97 '__strlcat_chk', 98 '__strlcpy_chk', 99 '__strlen_chk', 100 '__strncpy_chk2', 101 '__strrchr_chk', 102 '__umask_chk' 103]) 104# Some symbols are used to implement public macros. 105macro_stuff = set([ 106 '__assert2', 107 '__errno', 108 '__fe_dfl_env', 109 '__get_h_errno', 110 '__fpclassifyd', 111 '__isfinite', 112 '__isfinitef', 113 '__isfinitel', 114 '__isnormal', 115 '__isnormalf', 116 '__isnormall', 117 '__sF', 118 '__pthread_cleanup_pop', 119 '__pthread_cleanup_push', 120]) 121# bionic exposes various Linux features that glibc doesn't. 122linux_stuff = set([ 123 'getauxval', 124 'gettid', 125 'tgkill' 126]) 127# Some standard stuff isn't yet in the versions of glibc we're using. 128std_stuff = set([ 129 'at_quick_exit', 130 'c16rtomb', 131 'c32rtomb', 132 'mbrtoc16', 133 'mbrtoc32', 134]) 135# These have mangled names in glibc, with a macro taking the "obvious" name. 136weird_stuff = set([ 137 'fstat', 138 'fstat64', 139 'fstatat', 140 'fstatat64', 141 'isfinite', 142 'isfinitef', 143 'isfinitel', 144 'isnormal', 145 'isnormalf', 146 'isnormall', 147 'lstat', 148 'lstat64', 149 'mknod', 150 'mknodat', 151 'stat', 152 'stat64', 153 'optreset', 154 'sigsetjmp', 155]) 156# These exist in glibc, but under slightly different names (generally one extra 157# or one fewer _). TODO: check against glibc names. 158libresolv_stuff = set([ 159 '__res_send_setqhook', 160 '__res_send_setrhook', 161 '_resolv_flush_cache_for_net', 162 '_resolv_set_nameservers_for_net', 163 'dn_expand', 164 'nsdispatch', 165]) 166# Implementation details we know we export (and can't get away from). 167known = set([ 168 '_ctype_', 169 '__libc_init', 170]) 171 172if not only_unwanted: 173 #print 'glibc:' 174 #for symbol in sorted(glibc): 175 # print symbol 176 #print 177 178 #print 'bionic:' 179 #for symbol in sorted(bionic): 180 # print symbol 181 #print 182 183 print 'in glibc (but not posix) but not bionic:' 184 for symbol in sorted((glibc - posix).difference(bionic)): 185 print symbol 186 print 187 188 print 'in posix (and implemented in glibc) but not bionic:' 189 for symbol in sorted((posix.intersection(glibc)).difference(bionic)): 190 print symbol 191 print 192 193 print 'in bionic but not glibc:' 194 195allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff | 196 std_stuff | weird_stuff | libresolv_stuff | known) 197for symbol in sorted((bionic - allowed_stuff).difference(glibc)): 198 if symbol in ndk_ignored: 199 symbol += '*' 200 print symbol 201 202sys.exit(0) 203