Replace public library list with shared lib sonames (part 2/2)

This commit updates interface of libdl.c.

1. android_init_namespaces is replaces with android_init_anonymous_namespace
2. added 2 arguments to android_create_namespace to specify linked namespace
   and the list of shared libraries sonames.
3. symbol lookup does not get past boundary libraries (added check and test for it).

Bug: http://b/26833548
Bug: http://b/21879602
Test: bionic-unit-tests --gtest_filter=dl*:Dl*
Change-Id: I32921da487a02e5bd0d2fc528904d1228394bfb9
diff --git a/tests/libs/Android.build.linker_namespaces.mk b/tests/libs/Android.build.linker_namespaces.mk
index df6428c..cd9d7f1 100644
--- a/tests/libs/Android.build.linker_namespaces.mk
+++ b/tests/libs/Android.build.linker_namespaces.mk
@@ -25,10 +25,13 @@
 # 2. Check that public libraries loaded in different namespaces are shared
 #    between them.
 # 3. Check that namespace sticks on dlopen
+# 4. Check that having access to shared library (libnstest_public.so)
+#    does not expose symbols from dependent library (libnstest_public_internal.so)
 #
 # Dependency tree (visibility)
 # libnstest_root.so (this should be local to the namespace)
 # +-> libnstest_public.so
+#     +-> libnstest_public_internal.so
 # +-> libnstest_private.so
 #
 # libnstest_dlopened.so (library in private namespace dlopened from libnstest_root.so)
@@ -39,7 +42,13 @@
 module := libnstest_root
 include $(LOCAL_PATH)/Android.build.testlib.target.mk
 
+libnstest_public_internal_src_files := namespaces_public_internal.cpp
+module := libnstest_public_internal
+libnstest_public_internal_relative_install_path := public_namespace_libs
+include $(LOCAL_PATH)/Android.build.testlib.target.mk
+
 libnstest_public_src_files := namespaces_public.cpp
+libnstest_public_shared_libraries := libnstest_public_internal
 module := libnstest_public
 libnstest_public_relative_install_path := public_namespace_libs
 include $(LOCAL_PATH)/Android.build.testlib.target.mk
diff --git a/tests/libs/namespaces_public_internal.cpp b/tests/libs/namespaces_public_internal.cpp
new file mode 100644
index 0000000..15ae398
--- /dev/null
+++ b/tests/libs/namespaces_public_internal.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+static const char* g_internal_extern_string = "This string is from a library a shared library depends on";
+
+extern "C" const char* internal_extern_string() {
+  return g_internal_extern_string;
+}
diff --git a/tests/libs/namespaces_root.cpp b/tests/libs/namespaces_root.cpp
index b0006c7..a551673 100644
--- a/tests/libs/namespaces_root.cpp
+++ b/tests/libs/namespaces_root.cpp
@@ -20,6 +20,14 @@
 extern "C" const char* g_private_extern_string;
 extern "C" const char* g_public_extern_string;
 
+// This is resolved only if public library is in the same namespace as
+// the root one. It should remain unresolved if looking up for public library
+// crosses namespace boundary.
+//
+// Defined in libnstest_public_internal.so on which libnstest_public.so
+// depends on
+extern "C" const char* __attribute__((weak)) internal_extern_string();
+
 bool g_dlopened = false;
 
 extern "C" const char* ns_get_local_string() {
@@ -34,6 +42,14 @@
   return g_public_extern_string;
 }
 
+extern "C" const char* ns_get_internal_extern_string() {
+  if (internal_extern_string != nullptr) {
+    return internal_extern_string();
+  } else {
+    return nullptr;
+  }
+}
+
 extern "C" const char* ns_get_dlopened_string() {
   void* handle = dlopen("libnstest_dlopened.so", RTLD_NOW | RTLD_GLOBAL);
   if (handle == nullptr) {