OSDN Git Service

Add a basic NDK compatibility library.
authorDan Albert <danalbert@google.com>
Thu, 22 Jan 2015 01:50:29 +0000 (17:50 -0800)
committerDan Albert <danalbert@google.com>
Thu, 22 Jan 2015 02:12:15 +0000 (18:12 -0800)
We know we can safely statically link `libm`, since it doesn't have
any dependencies on the OS or the layout of a data type that has
changed between releases (like `pthread_t`).

We can safely statically link `libc_syscalls` because the user can
check for and handle `ENOSYS`.

Update `ndk_missing_symbols.py` to account for symbols that are in the
compatibility library.

Improve `symbols.py` to be able to pull symbols from a static library.

Change-Id: Ifb0ede1e8b4a8f0f33865d9fed72fb8b4d443fbc

libc/Android.mk
libc/tools/ndk_missing_symbols.py
libc/tools/symbols.py

index 2f534c3..71ddbd3 100644 (file)
@@ -944,6 +944,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
 # ========================================================
 
index 7b22ca8..a9f92b1 100755 (executable)
@@ -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
 
 
index 43454e4..3f40aad 100644 (file)
@@ -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