Move android_namespace_t to a separate file.

Breaking up huge linker.cpp into smaller peaces
in order to make it easier to extract part of the
code that belongs to libdl.so and remove parts of
the code that do not belong to linker

(refactoring part 1 of many)

Change-Id: I57ac36677a815800dc127c8c45c3ea806c37e247
Test: bionic-unit-tests --gtest_filter=dl*:Dl*
diff --git a/linker/Android.bp b/linker/Android.bp
index a35eb45..73c0e90 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -21,6 +21,7 @@
         "linker_dlwarning.cpp",
         "linker_gdb_support.cpp",
         "linker_libc_support.c",
+        "linker_namespaces.cpp",
         "linker_logger.cpp",
         "linker_mapped_file_fragment.cpp",
         "linker_phdr.cpp",
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 68b3a53..b57ba27 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -55,6 +55,7 @@
 #include "linker_gdb_support.h"
 #include "linker_debug.h"
 #include "linker_dlwarning.h"
+#include "linker_namespaces.h"
 #include "linker_sleb128.h"
 #include "linker_phdr.h"
 #include "linker_relocs.h"
@@ -75,71 +76,6 @@
 #undef ELF_ST_TYPE
 #define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
 
-struct android_namespace_t {
- public:
-  android_namespace_t() : name_(nullptr), is_isolated_(false) {}
-
-  const char* get_name() const { return name_; }
-  void set_name(const char* name) { name_ = name; }
-
-  bool is_isolated() const { return is_isolated_; }
-  void set_isolated(bool isolated) { is_isolated_ = isolated; }
-
-  const std::vector<std::string>& get_ld_library_paths() const {
-    return ld_library_paths_;
-  }
-  void set_ld_library_paths(std::vector<std::string>&& library_paths) {
-    ld_library_paths_ = library_paths;
-  }
-
-  const std::vector<std::string>& get_default_library_paths() const {
-    return default_library_paths_;
-  }
-  void set_default_library_paths(std::vector<std::string>&& library_paths) {
-    default_library_paths_ = library_paths;
-  }
-
-  const std::vector<std::string>& get_permitted_paths() const {
-    return permitted_paths_;
-  }
-  void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
-    permitted_paths_ = permitted_paths;
-  }
-
-  void add_soinfo(soinfo* si) {
-    soinfo_list_.push_back(si);
-  }
-
-  void add_soinfos(const soinfo::soinfo_list_t& soinfos) {
-    for (auto si : soinfos) {
-      add_soinfo(si);
-      si->add_secondary_namespace(this);
-    }
-  }
-
-  void remove_soinfo(soinfo* si) {
-    soinfo_list_.remove_if([&](soinfo* candidate) {
-      return si == candidate;
-    });
-  }
-
-  const soinfo::soinfo_list_t& soinfo_list() const { return soinfo_list_; }
-
-  // For isolated namespaces - checks if the file is on the search path;
-  // always returns true for not isolated namespace.
-  bool is_accessible(const std::string& path);
-
- private:
-  const char* name_;
-  bool is_isolated_;
-  std::vector<std::string> ld_library_paths_;
-  std::vector<std::string> default_library_paths_;
-  std::vector<std::string> permitted_paths_;
-  soinfo::soinfo_list_t soinfo_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(android_namespace_t);
-};
-
 android_namespace_t g_default_namespace;
 
 static std::unordered_map<uintptr_t, soinfo*> g_soinfo_handles_map;
@@ -259,7 +195,7 @@
 static std::vector<soinfo*> g_ld_preloads;
 
 static bool g_public_namespace_initialized;
-static soinfo::soinfo_list_t g_public_namespace;
+static soinfo_list_t g_public_namespace;
 
 int g_ld_debug_verbosity;
 abort_msg_t* g_abort_message = nullptr; // For debuggerd.
@@ -329,32 +265,6 @@
   notify_gdb_of_unload(&(info->link_map_head));
 }
 
-bool android_namespace_t::is_accessible(const std::string& file) {
-  if (!is_isolated_) {
-    return true;
-  }
-
-  for (const auto& dir : ld_library_paths_) {
-    if (file_is_in_dir(file, dir)) {
-      return true;
-    }
-  }
-
-  for (const auto& dir : default_library_paths_) {
-    if (file_is_in_dir(file, dir)) {
-      return true;
-    }
-  }
-
-  for (const auto& dir : permitted_paths_) {
-    if (file_is_under_dir(file, dir)) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
 LinkedListEntry<soinfo>* SoinfoListAllocator::alloc() {
   return g_soinfo_links_allocator.alloc();
 }
@@ -938,8 +848,8 @@
 }
 
 bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
-                      soinfo** si_found_in, const soinfo::soinfo_list_t& global_group,
-                      const soinfo::soinfo_list_t& local_group, const ElfW(Sym)** symbol) {
+                      soinfo** si_found_in, const soinfo_list_t& global_group,
+                      const soinfo_list_t& local_group, const ElfW(Sym)** symbol) {
   SymbolName symbol_name(name);
   const ElfW(Sym)* s = nullptr;
 
@@ -1954,8 +1864,8 @@
 //
 // This group consists of the main executable, LD_PRELOADs
 // and libraries with the DF_1_GLOBAL flag set.
-static soinfo::soinfo_list_t make_global_group(android_namespace_t* ns) {
-  soinfo::soinfo_list_t global_group;
+static soinfo_list_t make_global_group(android_namespace_t* ns) {
+  soinfo_list_t global_group;
   ns->soinfo_list().for_each([&](soinfo* si) {
     if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
       global_group.push_back(si);
@@ -1970,12 +1880,12 @@
 // group (see make_global_group). For all others this is a group
 // of RTLD_GLOBAL libraries (which includes the global group from
 // the default namespace).
-static soinfo::soinfo_list_t get_shared_group(android_namespace_t* ns) {
+static soinfo_list_t get_shared_group(android_namespace_t* ns) {
   if (ns == &g_default_namespace) {
     return make_global_group(ns);
   }
 
-  soinfo::soinfo_list_t shared_group;
+  soinfo_list_t shared_group;
   ns->soinfo_list().for_each([&](soinfo* si) {
     if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
       shared_group.push_back(si);
@@ -2015,7 +1925,7 @@
   }
 
   // Construct global_group.
-  soinfo::soinfo_list_t global_group = make_global_group(ns);
+  soinfo_list_t global_group = make_global_group(ns);
 
   // If soinfos array is null allocate one on stack.
   // The array is needed in case of failure; for example
@@ -2122,7 +2032,7 @@
 
 
   // Step 5: link libraries.
-  soinfo::soinfo_list_t local_group;
+  soinfo_list_t local_group;
   walk_dependencies_tree(
       (start_with != nullptr && add_as_children) ? &start_with : soinfos,
       (start_with != nullptr && add_as_children) ? 1 : soinfos_count,
@@ -2202,7 +2112,7 @@
     return;
   }
 
-  soinfo::soinfo_list_t unload_list;
+  soinfo_list_t unload_list;
   for (size_t i = 0; i < count; ++i) {
     soinfo* si = soinfos[i];
 
@@ -2225,8 +2135,8 @@
   // linked. This is why we can safely use the first one.
   soinfo* root = soinfos[0];
 
-  soinfo::soinfo_list_t local_unload_list;
-  soinfo::soinfo_list_t external_unload_list;
+  soinfo_list_t local_unload_list;
+  soinfo_list_t external_unload_list;
   soinfo* si = nullptr;
 
   while ((si = unload_list.pop_front()) != nullptr) {
@@ -2584,6 +2494,13 @@
   return true;
 }
 
+static void add_soinfos_to_namespace(const soinfo_list_t& soinfos, android_namespace_t* ns) {
+  ns->add_soinfos(soinfos);
+  for (auto si : soinfos) {
+    si->add_secondary_namespace(ns);
+  }
+}
+
 android_namespace_t* create_namespace(const void* caller_addr,
                                       const char* name,
                                       const char* ld_library_path,
@@ -2623,10 +2540,10 @@
 
   if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
     // If shared - clone the parent namespace
-    ns->add_soinfos(parent_namespace->soinfo_list());
+    add_soinfos_to_namespace(parent_namespace->soinfo_list(), ns);
   } else {
     // If not shared - copy only the shared group
-    ns->add_soinfos(get_shared_group(parent_namespace));
+    add_soinfos_to_namespace(get_shared_group(parent_namespace), ns);
   }
 
   return ns;
@@ -3365,9 +3282,9 @@
 
 // This is a return on get_children()/get_parents() if
 // 'this->flags' does not have FLAG_NEW_SOINFO set.
-static soinfo::soinfo_list_t g_empty_list;
+static soinfo_list_t g_empty_list;
 
-soinfo::soinfo_list_t& soinfo::get_children() {
+soinfo_list_t& soinfo::get_children() {
   if (has_min_version(0)) {
     return children_;
   }
@@ -3375,7 +3292,7 @@
   return g_empty_list;
 }
 
-const soinfo::soinfo_list_t& soinfo::get_children() const {
+const soinfo_list_t& soinfo::get_children() const {
   if (has_min_version(0)) {
     return children_;
   }
@@ -3383,7 +3300,7 @@
   return g_empty_list;
 }
 
-soinfo::soinfo_list_t& soinfo::get_parents() {
+soinfo_list_t& soinfo::get_parents() {
   if (has_min_version(0)) {
     return parents_;
   }
@@ -4144,7 +4061,7 @@
   si->load_bias = get_elf_exec_load_bias(ehdr_vdso);
 
   si->prelink_image();
-  si->link_image(g_empty_list, soinfo::soinfo_list_t::make_list(si), nullptr);
+  si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr);
 #endif
 }
 
@@ -4362,7 +4279,7 @@
                       /* add_as_children */ true)) {
     __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
   } else if (needed_libraries_count == 0) {
-    if (!si->link_image(g_empty_list, soinfo::soinfo_list_t::make_list(si), nullptr)) {
+    if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr)) {
       __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
     }
     si->increment_ref_count();
diff --git a/linker/linker.h b/linker/linker.h
index d8c0e19..61ef259 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -40,6 +40,7 @@
 #include "private/bionic_page.h"
 #include "private/libc_logging.h"
 #include "linked_list.h"
+#include "linker_common_types.h"
 #include "linker_logger.h"
 
 #include <string>
@@ -104,28 +105,6 @@
 #define USE_RELA 1
 #endif
 
-struct soinfo;
-
-class SoinfoListAllocator {
- public:
-  static LinkedListEntry<soinfo>* alloc();
-  static void free(LinkedListEntry<soinfo>* entry);
-
- private:
-  // unconstructable
-  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)
@@ -177,8 +156,6 @@
 
 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];
@@ -434,8 +411,8 @@
 };
 
 bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
-                      soinfo** si_found_in, const soinfo::soinfo_list_t& global_group,
-                      const soinfo::soinfo_list_t& local_group, const ElfW(Sym)** symbol);
+                      soinfo** si_found_in, const soinfo_list_t& global_group,
+                      const soinfo_list_t& local_group, const ElfW(Sym)** symbol);
 
 enum RelocationKind {
   kRelocAbsolute = 0,
diff --git a/linker/linker_common_types.h b/linker/linker_common_types.h
new file mode 100644
index 0000000..1888c0c
--- /dev/null
+++ b/linker/linker_common_types.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_COMMON_TYPES_H
+#define __LINKER_COMMON_TYPES_H
+
+#include <android/dlext.h>
+#include "linked_list.h"
+
+struct soinfo;
+
+class SoinfoListAllocator {
+ public:
+  static LinkedListEntry<soinfo>* alloc();
+  static void free(LinkedListEntry<soinfo>* entry);
+
+ private:
+  // unconstructable
+  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);
+};
+
+typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
+typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;
+
+#endif  /* __LINKER_COMMON_TYPES_H */
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
new file mode 100644
index 0000000..675f324
--- /dev/null
+++ b/linker/linker_namespaces.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_namespaces.h"
+#include "linker_utils.h"
+
+#include <vector>
+
+bool android_namespace_t::is_accessible(const std::string& file) {
+  if (!is_isolated_) {
+    return true;
+  }
+
+  for (const auto& dir : ld_library_paths_) {
+    if (file_is_in_dir(file, dir)) {
+      return true;
+    }
+  }
+
+  for (const auto& dir : default_library_paths_) {
+    if (file_is_in_dir(file, dir)) {
+      return true;
+    }
+  }
+
+  for (const auto& dir : permitted_paths_) {
+    if (file_is_under_dir(file, dir)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
new file mode 100644
index 0000000..d4b5efd
--- /dev/null
+++ b/linker/linker_namespaces.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_NAMESPACES_H
+#define __LINKER_NAMESPACES_H
+
+#include "linker_common_types.h"
+
+#include <vector>
+
+struct android_namespace_t {
+ public:
+  android_namespace_t() : name_(nullptr), is_isolated_(false) {}
+
+  const char* get_name() const { return name_; }
+  void set_name(const char* name) { name_ = name; }
+
+  bool is_isolated() const { return is_isolated_; }
+  void set_isolated(bool isolated) { is_isolated_ = isolated; }
+
+  const std::vector<std::string>& get_ld_library_paths() const {
+    return ld_library_paths_;
+  }
+  void set_ld_library_paths(std::vector<std::string>&& library_paths) {
+    ld_library_paths_ = library_paths;
+  }
+
+  const std::vector<std::string>& get_default_library_paths() const {
+    return default_library_paths_;
+  }
+  void set_default_library_paths(std::vector<std::string>&& library_paths) {
+    default_library_paths_ = library_paths;
+  }
+
+  const std::vector<std::string>& get_permitted_paths() const {
+    return permitted_paths_;
+  }
+  void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
+    permitted_paths_ = permitted_paths;
+  }
+
+  void add_soinfo(soinfo* si) {
+    soinfo_list_.push_back(si);
+  }
+
+  void add_soinfos(const soinfo_list_t& soinfos) {
+    for (auto si : soinfos) {
+      add_soinfo(si);
+    }
+  }
+
+  void remove_soinfo(soinfo* si) {
+    soinfo_list_.remove_if([&](soinfo* candidate) {
+      return si == candidate;
+    });
+  }
+
+  const soinfo_list_t& soinfo_list() const { return soinfo_list_; }
+
+  // For isolated namespaces - checks if the file is on the search path;
+  // always returns true for not isolated namespace.
+  bool is_accessible(const std::string& path);
+
+ private:
+  const char* name_;
+  bool is_isolated_;
+  std::vector<std::string> ld_library_paths_;
+  std::vector<std::string> default_library_paths_;
+  std::vector<std::string> permitted_paths_;
+  soinfo_list_t soinfo_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(android_namespace_t);
+};
+
+#endif  /* __LINKER_NAMESPACES_H */