Merge changes Id8a3b7dc,I00ded8f9,I02f78ad7

* changes:
  Make the legacy inline headers compile standalone.
  Don't redefine __ANDROID_API__.
  Move <sys/_sigdefs.h> and <sys/_errdefs.h> to private.
diff --git a/linker/linker.cpp b/linker/linker.cpp
index bda713e..77f5359 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -110,6 +110,7 @@
   void add_soinfos(const soinfo::soinfo_list_t& soinfos) {
     for (auto si : soinfos) {
       add_soinfo(si);
+      si->add_secondary_namespace(this);
     }
   }
 
@@ -146,6 +147,7 @@
 static LinkerTypeAllocator<LinkedListEntry<soinfo>> g_soinfo_links_allocator;
 
 static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
+static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
 
 static soinfo* solist;
 static soinfo* sonext;
@@ -286,6 +288,14 @@
   g_soinfo_links_allocator.free(entry);
 }
 
+LinkedListEntry<android_namespace_t>* NamespaceListAllocator::alloc() {
+  return g_namespace_list_allocator.alloc();
+}
+
+void NamespaceListAllocator::free(LinkedListEntry<android_namespace_t>* entry) {
+  g_namespace_list_allocator.free(entry);
+}
+
 static soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
                             struct stat* file_stat, off64_t file_offset,
                             uint32_t rtld_flags) {
@@ -349,9 +359,6 @@
     sonext = prev;
   }
 
-  // remove from the namespace
-  si->get_namespace()->remove_soinfo(si);
-
   si->~soinfo();
   g_soinfo_allocator.free(si);
 }
@@ -843,7 +850,7 @@
   }
 
   this->rtld_flags_ = rtld_flags;
-  this->namespace_ = ns;
+  this->primary_namespace_ = ns;
 }
 
 soinfo::~soinfo() {
@@ -1003,6 +1010,7 @@
     g_soinfo_allocator.protect_all(protection);
     g_soinfo_links_allocator.protect_all(protection);
     g_namespace_allocator.protect_all(protection);
+    g_namespace_list_allocator.protect_all(protection);
   }
 
   static size_t ref_count_;
@@ -2122,7 +2130,7 @@
           TRACE("deprecated (old format of soinfo): %s needs to unload %s",
               si->get_realpath(), library_name);
 
-          soinfo* needed = find_library(si->get_namespace(),
+          soinfo* needed = find_library(si->get_primary_namespace(),
                                         library_name, RTLD_NOLOAD, nullptr, nullptr);
 
           if (needed != nullptr) {
@@ -2172,6 +2180,10 @@
   return std::string(sym_name) + ", version " + sym_ver;
 }
 
+static android_namespace_t* get_caller_namespace(soinfo* caller) {
+  return caller != nullptr ? caller->get_primary_namespace() : g_anonymous_namespace;
+}
+
 void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
   // Use basic string manipulation calls to avoid snprintf.
   // snprintf indirectly calls pthread_getspecific to get the size of a buffer.
@@ -2208,7 +2220,7 @@
     return nullptr;
   }
 
-  android_namespace_t* ns = caller != nullptr ? caller->get_namespace() : g_anonymous_namespace;
+  android_namespace_t* ns = get_caller_namespace(caller);
 
   if (extinfo != nullptr) {
     if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) {
@@ -2302,7 +2314,7 @@
   soinfo* found = nullptr;
   const ElfW(Sym)* sym = nullptr;
   soinfo* caller = find_containing_library(caller_addr);
-  android_namespace_t* ns = caller != nullptr ? caller->get_namespace() : g_anonymous_namespace;
+  android_namespace_t* ns = get_caller_namespace(caller);
 
   version_info vi_instance;
   version_info* vi = nullptr;
@@ -2415,7 +2427,7 @@
   soinfo* caller_soinfo = find_containing_library(caller_addr);
 
   android_namespace_t* caller_ns = caller_soinfo != nullptr ?
-                                   caller_soinfo->get_namespace() :
+                                   caller_soinfo->get_primary_namespace() :
                                    g_anonymous_namespace;
 
   ProtectedDataGuard guard;
@@ -3023,10 +3035,6 @@
 
   // DT_FINI should be called after DT_FINI_ARRAY if both are present.
   call_function("DT_FINI", fini_func_);
-
-  // This is needed on second call to dlopen
-  // after library has been unloaded with RTLD_NODELETE
-  constructors_called = false;
 }
 
 void soinfo::add_child(soinfo* child) {
@@ -3054,9 +3062,20 @@
     });
   });
 
-  // 2. Once everything untied - clear local lists.
+  // 2. Remove from the primary namespace
+  primary_namespace_->remove_soinfo(this);
+  primary_namespace_ = nullptr;
+
+  // 3. Remove from secondary namespaces
+  secondary_namespaces_.for_each([&](android_namespace_t* ns) {
+    ns->remove_soinfo(this);
+  });
+
+
+  // 4. Once everything untied - clear local lists.
   parents_.clear();
   children_.clear();
+  secondary_namespaces_.clear();
 }
 
 dev_t soinfo::get_st_dev() const {
@@ -3190,14 +3209,19 @@
   return g_empty_runpath;
 }
 
-android_namespace_t* soinfo::get_namespace() {
+android_namespace_t* soinfo::get_primary_namespace() {
   if (has_min_version(3)) {
-    return namespace_;
+    return primary_namespace_;
   }
 
   return &g_default_namespace;
 }
 
+void soinfo::add_secondary_namespace(android_namespace_t* secondary_ns) {
+  CHECK(has_min_version(3));
+  secondary_namespaces_.push_back(secondary_ns);
+}
+
 ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const {
   if (ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC) {
     return call_ifunc_resolver(s->st_value + load_bias);
diff --git a/linker/linker.h b/linker/linker.h
index 81f93ac..4e2e0b9 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -114,6 +114,16 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
 };
 
+class NamespaceListAllocator {
+ public:
+  static LinkedListEntry<android_namespace_t>* alloc();
+  static void free(LinkedListEntry<android_namespace_t>* entry);
+
+ private:
+  // unconstructable
+  DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceListAllocator);
+};
+
 class SymbolName {
  public:
   explicit SymbolName(const char* name)
@@ -166,6 +176,7 @@
 struct soinfo {
  public:
   typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
+  typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;
 #if defined(__work_around_b_24465209__)
  private:
   char old_name_[SOINFO_NAME_LEN];
@@ -342,7 +353,8 @@
 
   void set_dt_runpath(const char *);
   const std::vector<std::string>& get_dt_runpath() const;
-  android_namespace_t* get_namespace();
+  android_namespace_t* get_primary_namespace();
+  void add_secondary_namespace(android_namespace_t* secondary_ns);
 
   void set_mapped_by_caller(bool reserved_map);
   bool is_mapped_by_caller() const;
@@ -414,7 +426,8 @@
 
   // version >= 3
   std::vector<std::string> dt_runpath_;
-  android_namespace_t* namespace_;
+  android_namespace_t* primary_namespace_;
+  android_namespace_list_t secondary_namespaces_;
   uintptr_t handle_;
 
   friend soinfo* get_libdl_info();
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index bbdc024..87e5dbc 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -959,6 +959,70 @@
   dlclose(handle2);
 }
 
+TEST(dlext, ns_shared_dlclose) {
+  std::string path = "libc.so:libc++.so:libdl.so:libm.so";
+
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
+
+  android_set_application_target_sdk_version(42U); // something > 23
+
+  ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr)) << dlerror();
+
+  // preload this library to the default namespace to check if it
+  // is shared later on.
+  void* handle_dlopened =
+          dlopen((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_dlopened != nullptr) << dlerror();
+
+  android_namespace_t* ns_isolated_shared =
+          android_create_namespace("private_isolated_shared", nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_SHARED,
+                                   nullptr);
+  ASSERT_TRUE(ns_isolated_shared != nullptr) << dlerror();
+
+  // Check if "libnstest_dlopened.so" is loaded (and the same)
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns_isolated_shared;
+
+  void* handle = android_dlopen_ext("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  ASSERT_TRUE(handle == handle_dlopened);
+  dlclose(handle);
+  dlclose(handle_dlopened);
+
+  // And now check that the library cannot be found by soname (and is no longer loaded)
+  handle = android_dlopen_ext("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in shared namespace";
+
+  handle = android_dlopen_ext((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(),
+                              RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in shared namespace";
+
+  handle = dlopen("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in default namespace";
+
+  handle = dlopen((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(),
+                  RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in default namespace";
+
+  // Now lets see if the soinfo area gets reused in the wrong way:
+  // load a library to default namespace.
+  const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+  void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_public != nullptr) << dlerror();
+
+  // try to find it in shared namespace
+  handle = android_dlopen_ext(g_public_lib, RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: " << g_public_lib << " is accessible in shared namespace";
+}
+
 TEST(dlext, ns_anonymous) {
   static const char* root_lib = "libnstest_root.so";
   std::string path = std::string("libc.so:libc++.so:libdl.so:libm.so:") + g_public_lib;