/libc/tools/check-symbols-glibc.py
Python | 202 lines | 151 code | 17 blank | 34 comment | 10 complexity | 6dbc1e6ca320ff16afc0cde04efc00cc MD5 | raw file
- #!/usr/bin/env python2
- #
- # Copyright (C) 2015 The Android Open Source Project
- #
- # Licensed under the Apache License, Version 2.0 (the 'License');
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an 'AS IS' BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- #
- # pylint: disable=bad-indentation,bad-continuation
- import glob
- import os
- import re
- import sys
- import symbols
- only_unwanted = False
- if len(sys.argv) > 1:
- if sys.argv[1] in ('-u', '--unwanted'):
- only_unwanted = True
- toolchain = os.environ['ANDROID_TOOLCHAIN']
- arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain)
- if arch == 'aarch64':
- arch = 'arm64'
- def MangleGlibcNameToBionic(name):
- if name in glibc_to_bionic_names:
- return glibc_to_bionic_names[name]
- return name
- def GetNdkIgnored(arch): # pylint: disable=redefined-outer-name
- ignored_symbols = set()
- files = glob.glob('%s/ndk/build/tools/unwanted-symbols/%s/*' %
- (os.getenv('ANDROID_BUILD_TOP'), arch))
- for f in files:
- ignored_symbols |= set(open(f, 'r').read().splitlines())
- return ignored_symbols
- glibc_to_bionic_names = {
- '__res_init': 'res_init',
- '__res_mkquery': 'res_mkquery',
- '__res_query': 'res_query',
- '__res_search': 'res_search',
- '__xpg_basename': '__gnu_basename',
- }
- glibc = symbols.GetFromSystemSo([
- 'libc.so.*',
- 'librt.so.*',
- 'libpthread.so.*',
- 'libresolv.so.*',
- 'libm.so.*',
- 'libutil.so.*',
- ])
- bionic = symbols.GetFromAndroidSo(['libc.so', 'libm.so'])
- this_dir = os.path.dirname(os.path.realpath(__file__))
- posix = symbols.GetFromTxt(os.path.join(this_dir, 'posix-2013.txt'))
- ndk_ignored = GetNdkIgnored(arch)
- glibc = set(map(MangleGlibcNameToBionic, glibc))
- # bionic includes various BSD symbols to ease porting other BSD-licensed code.
- bsd_stuff = set([
- 'basename_r',
- 'dirname_r',
- 'fgetln',
- 'fpurge',
- 'funopen',
- 'gamma_r',
- 'gammaf_r',
- 'getprogname',
- 'setprogname',
- 'strlcat',
- 'strlcpy',
- 'sys_signame',
- 'wcslcat',
- 'wcslcpy'
- ])
- # Some symbols are part of the FORTIFY implementation.
- FORTIFY_stuff = set([
- '__FD_CLR_chk',
- '__FD_ISSET_chk',
- '__FD_SET_chk',
- '__stack_chk_guard',
- '__stpncpy_chk2',
- '__strchr_chk',
- '__strlcat_chk',
- '__strlcpy_chk',
- '__strlen_chk',
- '__strncpy_chk2',
- '__strrchr_chk',
- '__umask_chk'
- ])
- # Some symbols are used to implement public macros.
- macro_stuff = set([
- '__assert2',
- '__errno',
- '__fe_dfl_env',
- '__get_h_errno',
- '__fpclassifyd',
- '__isfinite',
- '__isfinitef',
- '__isfinitel',
- '__isnormal',
- '__isnormalf',
- '__isnormall',
- '__sF',
- '__pthread_cleanup_pop',
- '__pthread_cleanup_push',
- ])
- # bionic exposes various Linux features that glibc doesn't.
- linux_stuff = set([
- 'getauxval',
- 'gettid',
- 'tgkill'
- ])
- # Some standard stuff isn't yet in the versions of glibc we're using.
- std_stuff = set([
- 'at_quick_exit',
- 'c16rtomb',
- 'c32rtomb',
- 'mbrtoc16',
- 'mbrtoc32',
- ])
- # These have mangled names in glibc, with a macro taking the "obvious" name.
- weird_stuff = set([
- 'fstat',
- 'fstat64',
- 'fstatat',
- 'fstatat64',
- 'isfinite',
- 'isfinitef',
- 'isfinitel',
- 'isnormal',
- 'isnormalf',
- 'isnormall',
- 'lstat',
- 'lstat64',
- 'mknod',
- 'mknodat',
- 'stat',
- 'stat64',
- 'optreset',
- 'sigsetjmp',
- ])
- # These exist in glibc, but under slightly different names (generally one extra
- # or one fewer _). TODO: check against glibc names.
- libresolv_stuff = set([
- '__res_send_setqhook',
- '__res_send_setrhook',
- '_resolv_flush_cache_for_net',
- '_resolv_set_nameservers_for_net',
- 'dn_expand',
- 'nsdispatch',
- ])
- # Implementation details we know we export (and can't get away from).
- known = set([
- '_ctype_',
- '__libc_init',
- ])
- if not only_unwanted:
- #print 'glibc:'
- #for symbol in sorted(glibc):
- # print symbol
- #print
- #print 'bionic:'
- #for symbol in sorted(bionic):
- # print symbol
- #print
- print 'in glibc (but not posix) but not bionic:'
- for symbol in sorted((glibc - posix).difference(bionic)):
- print symbol
- print
- print 'in posix (and implemented in glibc) but not bionic:'
- for symbol in sorted((posix.intersection(glibc)).difference(bionic)):
- print symbol
- print
- print 'in bionic but not glibc:'
- allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff |
- std_stuff | weird_stuff | libresolv_stuff | known)
- for symbol in sorted((bionic - allowed_stuff).difference(glibc)):
- if symbol in ndk_ignored:
- symbol += '*'
- print symbol
- sys.exit(0)