diff --git a/libc/Android.mk b/libc/Android.mk index 2f534c3cd..71ddbd3f7 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -943,6 +943,26 @@ LOCAL_NATIVE_COVERAGE := $(bionic_coverage) include $(BUILD_STATIC_LIBRARY) +# ======================================================== +# libc_ndk.a +# Compatibility library for the NDK. This library contains +# all the parts of libc that are safe to statically link. +# We can't safely statically link things that can only run +# on a certain version of the OS. Examples include +# anything that talks to netd (a large portion of the DNS +# code) and anything that is dependent on the layout of a +# data structure that has changed across releases (such as +# pthread_t). +# ======================================================== + +include $(CLEAR_VARS) + +LOCAL_MODULE := libc_ndk +LOCAL_WHOLE_STATIC_LIBRARIES := libc_syscalls libm +LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies) + +include $(BUILD_STATIC_LIBRARY) + # ======================================================== # libc_common.a # ======================================================== diff --git a/libc/tools/ndk_missing_symbols.py b/libc/tools/ndk_missing_symbols.py index 7b22ca82b..a9f92b183 100755 --- a/libc/tools/ndk_missing_symbols.py +++ b/libc/tools/ndk_missing_symbols.py @@ -33,10 +33,14 @@ def main(): adb_pull('/system/lib/libm.so', tmp_dir) current = symbols.GetFromAndroidSo(['libc.so', 'libm.so']) - device = (symbols.GetFromSo(os.path.join(tmp_dir, 'libc.so')) | - symbols.GetFromSo(os.path.join(tmp_dir, 'libm.so'))) + device = (symbols.GetFromElf(os.path.join(tmp_dir, 'libc.so')) | + symbols.GetFromElf(os.path.join(tmp_dir, 'libm.so'))) + compat_lib = symbols.GetFromAndroidStaticLib(['libc_ndk.a']) - for symbol in sorted(current - device): + missing_symbols = current - device + compat_not_covered = missing_symbols - compat_lib + + for symbol in sorted(compat_not_covered): print symbol diff --git a/libc/tools/symbols.py b/libc/tools/symbols.py index 43454e491..3f40aad99 100644 --- a/libc/tools/symbols.py +++ b/libc/tools/symbols.py @@ -28,7 +28,7 @@ def GetFromTxt(txt_file): return symbols -def GetFromSo(so_file): +def GetFromElf(elf_file, sym_type='--dyn-syms'): # pylint: disable=line-too-long # Example readelf output: # 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf @@ -41,7 +41,7 @@ def GetFromSo(so_file): symbols = set() - output = subprocess.check_output(['readelf', '--dyn-syms', '-W', so_file]) + output = subprocess.check_output(['readelf', sym_type, '-W', elf_file]) for line in output.split('\n'): if ' HIDDEN ' in line or ' UND ' in line: continue @@ -54,6 +54,22 @@ def GetFromSo(so_file): return symbols +def GetFromAndroidStaticLib(files): + out_dir = os.environ['ANDROID_PRODUCT_OUT'] + lib_dir = os.path.join(out_dir, 'obj') + + results = set() + for f in files: + static_lib_dir = os.path.join( + lib_dir, + 'STATIC_LIBRARIES', + '{}_intermediates'.format(os.path.splitext(f)[0])) + results |= GetFromElf( + os.path.join(static_lib_dir, f), + sym_type='--syms') + return results + + def GetFromAndroidSo(files): out_dir = os.environ['ANDROID_PRODUCT_OUT'] lib_dir = os.path.join(out_dir, 'system/lib64') @@ -62,7 +78,7 @@ def GetFromAndroidSo(files): results = set() for f in files: - results |= GetFromSo(os.path.join(lib_dir, f)) + results |= GetFromElf(os.path.join(lib_dir, f)) return results @@ -70,5 +86,5 @@ def GetFromSystemSo(files): lib_dir = '/lib/x86_64-linux-gnu' results = set() for f in files: - results |= GetFromSo(glob.glob(os.path.join(lib_dir, f))[-1]) + results |= GetFromElf(glob.glob(os.path.join(lib_dir, f))[-1]) return results