Merge "Rename <grp.h>/<pwd.h> tests to fit the usual pattern."
diff --git a/libc/Android.bp b/libc/Android.bp
index 2f21ea8..b1d077d 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1193,13 +1193,6 @@
     name: "libc_bionic",
 }
 
-genrule {
-    name: "generated_android_ids",
-    out: [ "generated_android_ids.h" ],
-    tool_files: [ "fs_config_generator.py" ],
-    cmd: "$(location fs_config_generator.py) aidarray system/core/include/private/android_filesystem_config.h > $(out)",
-}
-
 // ========================================================
 // libc_bionic_ndk.a- The portions of libc_bionic that can
 // be safely used in libc_ndk.a (no troublesome global data
@@ -1388,7 +1381,6 @@
     local_include_dirs: ["stdio"],
     include_dirs: ["bionic/libstdc++/include"],
     name: "libc_bionic_ndk",
-    generated_headers: ["generated_android_ids"],
 }
 
 // ========================================================
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index b6b5796..332b2b8 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -43,9 +43,6 @@
 #include "private/libc_logging.h"
 #include "private/ThreadLocalBuffer.h"
 
-// Generated android_ids array
-#include "generated_android_ids.h"
-
 // POSIX seems to envisage an implementation where the <pwd.h> functions are
 // implemented by brute-force searching with getpwent(3), and the <grp.h>
 // functions are implemented similarly with getgrent(3). This means that it's
diff --git a/libc/fs_config_generator.py b/libc/fs_config_generator.py
deleted file mode 120000
index aafb7dc..0000000
--- a/libc/fs_config_generator.py
+++ /dev/null
@@ -1 +0,0 @@
-../../build/tools/fs_config/fs_config_generator.py
\ No newline at end of file
diff --git a/libdl/libdl.c b/libdl/libdl.c
index 8329468..3fbd7e5 100644
--- a/libdl/libdl.c
+++ b/libdl/libdl.c
@@ -85,6 +85,9 @@
                                 struct android_namespace_t* parent,
                                 const void* caller_addr);
 
+__attribute__((__weak__, visibility("default")))
+void __loader_android_dlwarning(void* obj, void (*f)(void*, const char*));
+
 // Proxy calls to bionic loader
 void* dlopen(const char* filename, int flag) {
   const void* caller_addr = __builtin_return_address(0);
@@ -164,4 +167,6 @@
                                            caller_addr);
 }
 
-void android_dlwarning(void* obj, void (*f)(void*, const char*)) { f(obj, 0); }
+void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
+  __loader_android_dlwarning(obj, f);
+}
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index feb36cf..bb7b1ca 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -221,8 +221,8 @@
   // 01234567890 1234567890123456789012345678901234567890123456789012 3456789012345678901234567890123456789
     "dlopen_ext\0__loader_android_set_application_target_sdk_version\0__loader_android_get_application_targ"
   // 3*
-  // 000000000011111 111112222222222333333333344444444 4455555555556666666666777777777788 888888889999999 999
-  // 012345678901234 567890123456789012345678901234567 8901234567890123456789012345678901 234567890123456 789
+  // 000000000011111 111112222222222333333333344444444 4455555555556666666666777777777788 8888888899999999 99
+  // 012345678901234 567890123456789012345678901234567 8901234567890123456789012345678901 2345678901234567 89
     "et_sdk_version\0__loader_android_init_namespaces\0__loader_android_create_namespace\0__loader_dlvsym\0__"
   // 4*
   // 0000000000111111111122222 2222233333333334444444 4445555555555666666666677777777778 8888888889999999 999
@@ -254,7 +254,7 @@
   ELFW(SYM_INITIALIZER)(315, &__android_init_namespaces, 1),
   ELFW(SYM_INITIALIZER)(348, &__android_create_namespace, 1),
   ELFW(SYM_INITIALIZER)(382, &__dlvsym, 1),
-  ELFW(SYM_INITIALIZER)(397, &__android_dlwarning, 1),
+  ELFW(SYM_INITIALIZER)(398, &__android_dlwarning, 1),
 #if defined(__arm__)
   ELFW(SYM_INITIALIZER)(425, &__dl_unwind_find_exidx, 1),
 #endif
diff --git a/linker/linker.cpp b/linker/linker.cpp
index d3ab8d8..fc8d1ef 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1869,15 +1869,33 @@
   }
 #endif
 
-  if (sym_name == nullptr) {
-    DL_ERR("dlsym failed: symbol name is null");
-    return false;
-  }
-
   soinfo* found = nullptr;
   const ElfW(Sym)* sym = nullptr;
   soinfo* caller = find_containing_library(caller_addr);
   android_namespace_t* ns = get_caller_namespace(caller);
+  soinfo* si = nullptr;
+  if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
+    si = soinfo_from_handle(handle);
+  }
+
+  LD_LOG(kLogDlsym,
+         "dlsym(handle=%p(\"%s\"), sym_name=\"%s\", sym_ver=\"%s\", caller=\"%s\", caller_ns=%s@%p) ...",
+         handle,
+         si != nullptr ? si->get_realpath() : "n/a",
+         sym_name,
+         sym_ver,
+         caller == nullptr ? "(null)" : caller->get_realpath(),
+         ns == nullptr ? "(null)" : ns->get_name(),
+         ns);
+
+  auto failure_guard = make_scope_guard([&]() {
+    LD_LOG(kLogDlsym, "... dlsym failed: %s", linker_get_error_buffer());
+  });
+
+  if (sym_name == nullptr) {
+    DL_ERR("dlsym failed: symbol name is null");
+    return false;
+  }
 
   version_info vi_instance;
   version_info* vi = nullptr;
@@ -1891,7 +1909,6 @@
   if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
     sym = dlsym_linear_lookup(ns, sym_name, vi, &found, caller, handle);
   } else {
-    soinfo* si = soinfo_from_handle(handle);
     if (si == nullptr) {
       DL_ERR("dlsym failed: invalid handle: %p", handle);
       return false;
@@ -1904,6 +1921,10 @@
 
     if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
       *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
+      failure_guard.disable();
+      LD_LOG(kLogDlsym,
+             "... dlsym successful: sym_name=\"%s\", sym_ver=\"%s\", found in=\"%s\", address=%p",
+             sym_name, sym_ver, found->get_soname(), *symbol);
       return true;
     }
 
diff --git a/linker/linker_logger.h b/linker/linker_logger.h
index 0932471..502f872 100644
--- a/linker/linker_logger.h
+++ b/linker/linker_logger.h
@@ -40,6 +40,7 @@
 
 constexpr const uint32_t kLogErrors = 1 << 0;
 constexpr const uint32_t kLogDlopen = 1 << 1;
+constexpr const uint32_t kLogDlsym  = 1 << 2;
 
 class LinkerLogger {
  public:
diff --git a/tests/Android.bp b/tests/Android.bp
index 0868f6e..a9d302a 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -155,8 +155,6 @@
     shared: {
         enabled: false,
     },
-
-    generated_headers: ["generated_android_ids"],
 }
 
 // -----------------------------------------------------------------------------
diff --git a/tests/Android.build.mk b/tests/Android.build.mk
index cce4344..9236558 100644
--- a/tests/Android.build.mk
+++ b/tests/Android.build.mk
@@ -20,24 +20,30 @@
 LOCAL_MODULE := $(module)
 LOCAL_MODULE_TAGS := $(module_tag)
 ifeq ($(build_type),host)
-# Always make host multilib
-LOCAL_MULTILIB := both
+  # Always make host multilib
+  LOCAL_MULTILIB := both
 endif
 
 ifneq ($(findstring LIBRARY, $(build_target)),LIBRARY)
-    LOCAL_MODULE_STEM_32 := $(module)32
-    LOCAL_MODULE_STEM_64 := $(module)64
+  LOCAL_MODULE_STEM_32 := $(module)32
+  LOCAL_MODULE_STEM_64 := $(module)64
 else
-ifneq ($($(module)_install_to_out_data_dir),)
-    LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$($(module)_install_to_out_data_dir)
-    LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$($(module)_install_to_out_data_dir)
+ifneq ($($(module)_install_to_native_tests_dir),)
+  ifeq ($(build_type),host)
+    native_tests_var := HOST_OUT_NATIVE_TESTS
+  else
+    native_tests_var := TARGET_OUT_DATA_NATIVE_TESTS
+  endif
+
+  LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)$(native_tests_var))/$($(module)_install_to_native_tests_dir)
+  LOCAL_MODULE_PATH_64 := $($(native_tests_var))/$($(module)_install_to_native_tests_dir)
 endif
 endif
 
 LOCAL_CLANG := $($(module)_clang_$(build_type))
 
 ifneq ($($(module)_allow_asan),true)
-LOCAL_SANITIZE := never
+  LOCAL_SANITIZE := never
 endif
 
 LOCAL_FORCE_STATIC_EXECUTABLE := $($(module)_force_static_executable)
@@ -45,11 +51,11 @@
 LOCAL_ALLOW_UNDEFINED_SYMBOLS := $($(module)_allow_undefined_symbols)
 
 ifneq ($($(module)_multilib),)
-    LOCAL_MULTILIB := $($(module)_multilib)
+  LOCAL_MULTILIB := $($(module)_multilib)
 endif
 
 ifneq ($($(module)_relative_path),)
-    LOCAL_MODULE_RELATIVE_PATH := $($(module)_relative_path)
+  LOCAL_MODULE_RELATIVE_PATH := $($(module)_relative_path)
 endif
 
 LOCAL_CFLAGS := \
@@ -97,9 +103,9 @@
     $($(module)_ldlibs_$(build_type)) \
 
 ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
-LOCAL_CXX_STL := libc++_static
+  LOCAL_CXX_STL := libc++_static
 else
-LOCAL_CXX_STL := libc++
+  LOCAL_CXX_STL := libc++
 endif
 
 ifeq ($(build_type),target)
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index 8dcf771..54729b1 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -30,9 +30,6 @@
 
 #include <private/android_filesystem_config.h>
 
-// Generated android_ids array
-#include "generated_android_ids.h"
-
 enum uid_type_t {
   TYPE_SYSTEM,
   TYPE_APP
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 6018ef5..f0dac7c 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -1020,16 +1020,16 @@
   std::string gtest_filter_str;
   for (size_t i = args.size() - 1; i >= 1; --i) {
     if (strncmp(args[i], "--gtest_filter=", strlen("--gtest_filter=")) == 0) {
-      gtest_filter_str = std::string(args[i]);
+      gtest_filter_str = args[i] + strlen("--gtest_filter=");
       args.erase(args.begin() + i);
       break;
     }
   }
   if (enable_selftest == true) {
-    args.push_back(strdup("--gtest_filter=bionic_selftest*"));
+    gtest_filter_str = "bionic_selftest*";
   } else {
-    if (gtest_filter_str == "") {
-      gtest_filter_str = "--gtest_filter=-bionic_selftest*";
+    if (gtest_filter_str.empty()) {
+      gtest_filter_str = "-bionic_selftest*";
     } else {
       // Find if '-' for NEGATIVE_PATTERNS exists.
       if (gtest_filter_str.find("-") != std::string::npos) {
@@ -1038,8 +1038,9 @@
         gtest_filter_str += ":-bionic_selftest*";
       }
     }
-    args.push_back(strdup(gtest_filter_str.c_str()));
   }
+  gtest_filter_str = "--gtest_filter=" + gtest_filter_str;
+  args.push_back(strdup(gtest_filter_str.c_str()));
 
   options.isolate = true;
   // Parse arguments that make us can't run in isolation mode.
diff --git a/tests/libs/Android.build.dt_runpath.mk b/tests/libs/Android.build.dt_runpath.mk
index 60844e5..a3fcac5 100644
--- a/tests/libs/Android.build.dt_runpath.mk
+++ b/tests/libs/Android.build.dt_runpath.mk
@@ -80,7 +80,7 @@
 libtest_dt_runpath_d_zip_shared_libraries := libtest_dt_runpath_b libtest_dt_runpath_c
 libtest_dt_runpath_d_zip_ldflags := -Wl,--rpath,\$${ORIGIN}/dt_runpath_b_c_x -Wl,--enable-new-dtags
 libtest_dt_runpath_d_zip_ldlibs := -ldl
-libtest_dt_runpath_d_zip_install_to_out_data_dir := $(module)
+libtest_dt_runpath_d_zip_install_to_native_tests_dir := $(module)
 
 module_tag := optional
 build_type := target
diff --git a/tests/libs/Android.build.target.testlib.mk b/tests/libs/Android.build.testlib.host.mk
similarity index 81%
rename from tests/libs/Android.build.target.testlib.mk
rename to tests/libs/Android.build.testlib.host.mk
index 1e767c2..38970dc 100644
--- a/tests/libs/Android.build.target.testlib.mk
+++ b/tests/libs/Android.build.testlib.host.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2015 The Android Open Source Project
+# Copyright (C) 2016 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.
@@ -15,6 +15,5 @@
 #
 
 build_target := SHARED_LIBRARY
-build_type := target
-include $(TEST_PATH)/Android.build.mk
-
+build_type := host
+include $(LOCAL_PATH)/Android.build.testlib.internal.mk
diff --git a/tests/libs/Android.build.testlib.internal.mk b/tests/libs/Android.build.testlib.internal.mk
new file mode 100644
index 0000000..e1fec2b
--- /dev/null
+++ b/tests/libs/Android.build.testlib.internal.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2016 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.
+#
+
+# 1. Install test libraries to $ANDROID_DATA/nativetests../bionic-loader-test-libs/
+#    by default.
+ifeq ($($(module)_relative_install_path),)
+  $(module)_install_to_native_tests_dir := bionic-loader-test-libs
+else
+  $(module)_install_to_native_tests_dir := bionic-loader-test-libs/$($(module)_relative_install_path)
+endif
+# 2. Set dt_runpath to origin to resolve dependencies
+$(module)_ldflags += -Wl,--rpath,\$${ORIGIN} -Wl,--enable-new-dtags
+
+include $(TEST_PATH)/Android.build.mk
diff --git a/tests/libs/Android.build.testlib.mk b/tests/libs/Android.build.testlib.mk
index 833caf6..a46c457 100644
--- a/tests/libs/Android.build.testlib.mk
+++ b/tests/libs/Android.build.testlib.mk
@@ -14,9 +14,6 @@
 # limitations under the License.
 #
 
-build_target := SHARED_LIBRARY
-build_type := host
-include $(TEST_PATH)/Android.build.mk
+include $(LOCAL_PATH)/Android.build.testlib.host.mk
 
 include $(LOCAL_PATH)/Android.build.testlib.target.mk
-
diff --git a/tests/libs/Android.build.testlib.target.mk b/tests/libs/Android.build.testlib.target.mk
index b79dbfc..5ec0d71 100644
--- a/tests/libs/Android.build.testlib.target.mk
+++ b/tests/libs/Android.build.testlib.target.mk
@@ -14,14 +14,6 @@
 # limitations under the License.
 #
 
+build_target := SHARED_LIBRARY
 build_type := target
-# 1. Install test libraries to /data/nativetests../bionic-loader-test-libs/
-#    by default.
-ifeq ($($(module)_relative_install_path),)
-  $(module)_install_to_out_data_dir := bionic-loader-test-libs
-else
-  $(module)_install_to_out_data_dir := bionic-loader-test-libs/$($(module)_relative_install_path)
-endif
-# 2. Set dt_runpath to origin to resolve dependencies
-$(module)_ldflags += -Wl,--rpath,\$${ORIGIN} -Wl,--enable-new-dtags
-include $(TEST_PATH)/Android.build.mk
+include $(LOCAL_PATH)/Android.build.testlib.internal.mk
diff --git a/tools/versioner/src/Preprocessor.cpp b/tools/versioner/src/Preprocessor.cpp
index c863e6c..86bb225 100644
--- a/tools/versioner/src/Preprocessor.cpp
+++ b/tools/versioner/src/Preprocessor.cpp
@@ -439,8 +439,13 @@
 
   // Copy over the original headers before preprocessing.
   char* fts_paths[2] = { const_cast<char*>(src_dir.c_str()), nullptr };
-  FTS* fts = fts_open(fts_paths, FTS_LOGICAL, nullptr);
-  while (FTSENT* ent = fts_read(fts)) {
+  std::unique_ptr<FTS, decltype(&fts_close)> fts(fts_open(fts_paths, FTS_LOGICAL, nullptr),
+                                                 fts_close);
+  if (!fts) {
+    err(1, "failed to open directory %s", src_dir.c_str());
+  }
+
+  while (FTSENT* ent = fts_read(fts.get())) {
     llvm::StringRef path = ent->fts_path;
     if (!path.startswith(src_dir)) {
       err(1, "path '%s' doesn't start with source dir '%s'", ent->fts_path, src_dir.c_str());
@@ -461,7 +466,6 @@
            dst_path.c_str());
     }
   }
-  fts_close(fts);
 
   for (const auto& file_it : guards) {
     file_lines[file_it.first] = readFileLines(file_it.first);
diff --git a/tools/versioner/src/Utils.cpp b/tools/versioner/src/Utils.cpp
index 3806110..ef7facc 100644
--- a/tools/versioner/src/Utils.cpp
+++ b/tools/versioner/src/Utils.cpp
@@ -41,14 +41,14 @@
   std::vector<std::string> headers;
 
   char* dir_argv[2] = { const_cast<char*>(directory.c_str()), nullptr };
-  FTS* fts = fts_open(dir_argv, FTS_LOGICAL | FTS_NOCHDIR, nullptr);
+  std::unique_ptr<FTS, decltype(&fts_close)> fts(
+      fts_open(dir_argv, FTS_LOGICAL | FTS_NOCHDIR, nullptr), fts_close);
 
   if (!fts) {
     err(1, "failed to open directory '%s'", directory.c_str());
   }
 
-  FTSENT* ent;
-  while ((ent = fts_read(fts))) {
+  while (FTSENT* ent = fts_read(fts.get())) {
     if (ent->fts_info & (FTS_D | FTS_DP)) {
       continue;
     }
@@ -60,7 +60,6 @@
     headers.push_back(ent->fts_path);
   }
 
-  fts_close(fts);
   return headers;
 }
 
diff --git a/tools/versioner/src/VFS.cpp b/tools/versioner/src/VFS.cpp
index cd6d367..1aa7229 100644
--- a/tools/versioner/src/VFS.cpp
+++ b/tools/versioner/src/VFS.cpp
@@ -36,12 +36,14 @@
 
 static void addDirectoryToVFS(InMemoryFileSystem* vfs, const std::string& path) {
   char* paths[] = { const_cast<char*>(path.c_str()), nullptr };
-  FTS* fts = fts_open(paths, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, nullptr);
+  std::unique_ptr<FTS, decltype(&fts_close)> fts(
+      fts_open(paths, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, nullptr), fts_close);
+
   if (!fts) {
     err(1, "failed to open directory %s", path.c_str());
   }
 
-  while (FTSENT* ent = fts_read(fts)) {
+  while (FTSENT* ent = fts_read(fts.get())) {
     if ((ent->fts_info & FTS_F) == 0) {
       continue;
     }
@@ -61,8 +63,6 @@
       errx(1, "failed to add file '%s'", file_path);
     }
   }
-
-  fts_close(fts);
 }
 
 llvm::IntrusiveRefCntPtr<FileSystem> createCommonVFS(const std::string& header_dir,