#!/usr/bin/python

import glob
import os
import re
import subprocess
import sys

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 GetSymbolsFromSo(so_file):
  # Example readelf output:
  #   264: 0001623c     4 FUNC    GLOBAL DEFAULT    8 cabsf
  #   266: 00016244     4 FUNC    GLOBAL DEFAULT    8 dremf
  #   267: 00019018     4 OBJECT  GLOBAL DEFAULT   11 __fe_dfl_env
  #   268: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_dcmplt

  r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (I?FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')

  symbols = set()

  for line in subprocess.check_output(['readelf', '--dyn-syms', '-W', so_file]).split('\n'):
    if ' HIDDEN ' in line or ' UND ' in line:
      continue
    m = r.match(line)
    if m:
      symbol = m.group(2)
      symbol = re.sub('@.*', '', symbol)
      symbols.add(symbol)

  return symbols

def GetSymbolsFromAndroidSo(*files):
  symbols = set()
  for f in files:
    symbols = symbols | GetSymbolsFromSo('%s/system/lib64/%s' % (os.environ['ANDROID_PRODUCT_OUT'], f))
  return symbols

def GetSymbolsFromSystemSo(*files):
  symbols = set()
  for f in files:
    f = glob.glob('/lib/x86_64-linux-gnu/%s' % f)[-1]
    symbols = symbols | GetSymbolsFromSo(f)
  return symbols

def MangleGlibcNameToBionic(name):
  if name in glibc_to_bionic_names:
    return glibc_to_bionic_names[name]
  return name

def GetNdkIgnored():
  global arch
  symbols = set()
  files = glob.glob('%s/ndk/build/tools/unwanted-symbols/%s/*' %
                    (os.getenv('ANDROID_BUILD_TOP'), arch))
  for f in files:
    symbols |= set(open(f, 'r').read().splitlines())
  return 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 = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*')
bionic = GetSymbolsFromAndroidSo('libc.so', 'libm.so')
ndk_ignored = GetNdkIgnored()

glibc = 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 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)
