PageRenderTime 31ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/libc/tools/check-symbols-glibc.py

https://gitlab.com/generic-library/bionic
Python | 202 lines | 151 code | 17 blank | 34 comment | 10 complexity | 6dbc1e6ca320ff16afc0cde04efc00cc MD5 | raw file
  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
  18. import glob
  19. import os
  20. import re
  21. import sys
  22. import symbols
  23. only_unwanted = False
  24. if len(sys.argv) > 1:
  25. if sys.argv[1] in ('-u', '--unwanted'):
  26. only_unwanted = True
  27. toolchain = os.environ['ANDROID_TOOLCHAIN']
  28. arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain)
  29. if arch == 'aarch64':
  30. arch = 'arm64'
  31. def MangleGlibcNameToBionic(name):
  32. if name in glibc_to_bionic_names:
  33. return glibc_to_bionic_names[name]
  34. return name
  35. def GetNdkIgnored(arch): # pylint: disable=redefined-outer-name
  36. ignored_symbols = set()
  37. files = glob.glob('%s/ndk/build/tools/unwanted-symbols/%s/*' %
  38. (os.getenv('ANDROID_BUILD_TOP'), arch))
  39. for f in files:
  40. ignored_symbols |= set(open(f, 'r').read().splitlines())
  41. return ignored_symbols
  42. glibc_to_bionic_names = {
  43. '__res_init': 'res_init',
  44. '__res_mkquery': 'res_mkquery',
  45. '__res_query': 'res_query',
  46. '__res_search': 'res_search',
  47. '__xpg_basename': '__gnu_basename',
  48. }
  49. glibc = symbols.GetFromSystemSo([
  50. 'libc.so.*',
  51. 'librt.so.*',
  52. 'libpthread.so.*',
  53. 'libresolv.so.*',
  54. 'libm.so.*',
  55. 'libutil.so.*',
  56. ])
  57. bionic = symbols.GetFromAndroidSo(['libc.so', 'libm.so'])
  58. this_dir = os.path.dirname(os.path.realpath(__file__))
  59. posix = symbols.GetFromTxt(os.path.join(this_dir, 'posix-2013.txt'))
  60. ndk_ignored = GetNdkIgnored(arch)
  61. glibc = set(map(MangleGlibcNameToBionic, glibc))
  62. # bionic includes various BSD symbols to ease porting other BSD-licensed code.
  63. bsd_stuff = set([
  64. 'basename_r',
  65. 'dirname_r',
  66. 'fgetln',
  67. 'fpurge',
  68. 'funopen',
  69. 'gamma_r',
  70. 'gammaf_r',
  71. 'getprogname',
  72. 'setprogname',
  73. 'strlcat',
  74. 'strlcpy',
  75. 'sys_signame',
  76. 'wcslcat',
  77. 'wcslcpy'
  78. ])
  79. # Some symbols are part of the FORTIFY implementation.
  80. FORTIFY_stuff = set([
  81. '__FD_CLR_chk',
  82. '__FD_ISSET_chk',
  83. '__FD_SET_chk',
  84. '__stack_chk_guard',
  85. '__stpncpy_chk2',
  86. '__strchr_chk',
  87. '__strlcat_chk',
  88. '__strlcpy_chk',
  89. '__strlen_chk',
  90. '__strncpy_chk2',
  91. '__strrchr_chk',
  92. '__umask_chk'
  93. ])
  94. # Some symbols are used to implement public macros.
  95. macro_stuff = set([
  96. '__assert2',
  97. '__errno',
  98. '__fe_dfl_env',
  99. '__get_h_errno',
  100. '__fpclassifyd',
  101. '__isfinite',
  102. '__isfinitef',
  103. '__isfinitel',
  104. '__isnormal',
  105. '__isnormalf',
  106. '__isnormall',
  107. '__sF',
  108. '__pthread_cleanup_pop',
  109. '__pthread_cleanup_push',
  110. ])
  111. # bionic exposes various Linux features that glibc doesn't.
  112. linux_stuff = set([
  113. 'getauxval',
  114. 'gettid',
  115. 'tgkill'
  116. ])
  117. # Some standard stuff isn't yet in the versions of glibc we're using.
  118. std_stuff = set([
  119. 'at_quick_exit',
  120. 'c16rtomb',
  121. 'c32rtomb',
  122. 'mbrtoc16',
  123. 'mbrtoc32',
  124. ])
  125. # These have mangled names in glibc, with a macro taking the "obvious" name.
  126. weird_stuff = set([
  127. 'fstat',
  128. 'fstat64',
  129. 'fstatat',
  130. 'fstatat64',
  131. 'isfinite',
  132. 'isfinitef',
  133. 'isfinitel',
  134. 'isnormal',
  135. 'isnormalf',
  136. 'isnormall',
  137. 'lstat',
  138. 'lstat64',
  139. 'mknod',
  140. 'mknodat',
  141. 'stat',
  142. 'stat64',
  143. 'optreset',
  144. 'sigsetjmp',
  145. ])
  146. # These exist in glibc, but under slightly different names (generally one extra
  147. # or one fewer _). TODO: check against glibc names.
  148. libresolv_stuff = set([
  149. '__res_send_setqhook',
  150. '__res_send_setrhook',
  151. '_resolv_flush_cache_for_net',
  152. '_resolv_set_nameservers_for_net',
  153. 'dn_expand',
  154. 'nsdispatch',
  155. ])
  156. # Implementation details we know we export (and can't get away from).
  157. known = set([
  158. '_ctype_',
  159. '__libc_init',
  160. ])
  161. if not only_unwanted:
  162. #print 'glibc:'
  163. #for symbol in sorted(glibc):
  164. # print symbol
  165. #print
  166. #print 'bionic:'
  167. #for symbol in sorted(bionic):
  168. # print symbol
  169. #print
  170. print 'in glibc (but not posix) but not bionic:'
  171. for symbol in sorted((glibc - posix).difference(bionic)):
  172. print symbol
  173. print
  174. print 'in posix (and implemented in glibc) but not bionic:'
  175. for symbol in sorted((posix.intersection(glibc)).difference(bionic)):
  176. print symbol
  177. print
  178. print 'in bionic but not glibc:'
  179. allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff |
  180. std_stuff | weird_stuff | libresolv_stuff | known)
  181. for symbol in sorted((bionic - allowed_stuff).difference(glibc)):
  182. if symbol in ndk_ignored:
  183. symbol += '*'
  184. print symbol
  185. sys.exit(0)