#!/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)
