Merge "linker: add test for zeroed out shdr_table_"
diff --git a/tests/Android.build.prebuilt.mk b/tests/Android.build.prebuilt.mk
index 2d12557..09c2366 100644
--- a/tests/Android.build.prebuilt.mk
+++ b/tests/Android.build.prebuilt.mk
@@ -21,6 +21,8 @@
 LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/prebuilt-elf-files
 LOCAL_MODULE_CLASS := EXECUTABLES
 
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
+
 LOCAL_SRC_FILES_arm := prebuilt-elf-files/arm/$(bionic_tests_module)
 LOCAL_SRC_FILES_arm64 := prebuilt-elf-files/arm64/$(bionic_tests_module)
 LOCAL_SRC_FILES_x86 := prebuilt-elf-files/x86/$(bionic_tests_module)
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index f474ed9..ecc2a12 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1144,7 +1144,7 @@
 }
 
 // Bionic specific tests
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) && !defined(__mips__)
 
 #if defined(__LP64__)
 #define NATIVE_TESTS_PATH "/nativetest64"
diff --git a/tools/versioner/run_tests.py b/tools/versioner/run_tests.py
index 9bac3e2..f3bb6db 100755
--- a/tools/versioner/run_tests.py
+++ b/tools/versioner/run_tests.py
@@ -53,13 +53,33 @@
     print("{} {}".format(prefix_pass, test_name))
     return True
 
+
+def usage():
+    print("Usage: run_tests.py [-f]")
+    print("    -f\t\tdon't run slow tests")
+    sys.exit(0)
+
+
 root_dir = os.path.dirname(os.path.realpath(__file__))
 test_dir = os.path.join(root_dir, "tests")
 tests = os.listdir(test_dir)
+run_slow = True
+
+if len(sys.argv) > 2:
+    usage()
+elif len(sys.argv) == 2:
+    if sys.argv[1] != "-f":
+        usage()
+    run_slow = False
 
 success = True
 for test in sorted(tests):
-    if not run_test(test, os.path.join(test_dir, test)):
+    if test.startswith("slow") and not run_slow:
+        continue
+    path = os.path.join(test_dir, test)
+    if not os.path.isdir(path):
+        continue
+    if not run_test(test, path):
         success = False
 
 sys.exit(0 if success else 1)
diff --git a/tools/versioner/src/Preprocessor.cpp b/tools/versioner/src/Preprocessor.cpp
index 33531bd..8d0b943 100644
--- a/tools/versioner/src/Preprocessor.cpp
+++ b/tools/versioner/src/Preprocessor.cpp
@@ -93,12 +93,12 @@
   }
 
   DeclarationAvailability result = decl_av;
-  if (result.global_availability.introduced < global_min_api_visible) {
+  if (result.global_availability.introduced <= global_min_api_visible) {
     result.global_availability.introduced = 0;
   }
 
   for (Arch arch : supported_archs) {
-    if (result.arch_availability[arch].introduced < arch_visibility[arch]) {
+    if (result.arch_availability[arch].introduced <= arch_visibility[arch]) {
       result.arch_availability[arch].introduced = 0;
     }
   }
@@ -459,7 +459,7 @@
     }
   }
 
-  // Copy over any unchanged files directly.
+  // 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)) {
@@ -473,18 +473,14 @@
     }
 
     std::string rel_path = path.substr(src_dir.length() + 1);
-    if (guards.count(rel_path) == 0) {
-      std::string dst_path = dst_dir + "/" + rel_path;
-      llvm::StringRef parent_path = llvm::sys::path::parent_path(dst_path);
-      if (llvm::sys::fs::create_directories(parent_path)) {
-        errx(1, "failed to ensure existence of directory '%s'", parent_path.str().c_str());
-      }
-      if (llvm::sys::fs::copy_file(path, dst_path)) {
-        errx(1, "failed to copy '%s/%s' to '%s'", src_dir.c_str(), path.str().c_str(),
-             dst_path.c_str());
-      }
-
-      printf("Copied unmodified header %s\n", dst_path.c_str());
+    std::string dst_path = dst_dir + "/" + rel_path;
+    llvm::StringRef parent_path = llvm::sys::path::parent_path(dst_path);
+    if (llvm::sys::fs::create_directories(parent_path)) {
+      errx(1, "failed to ensure existence of directory '%s'", parent_path.str().c_str());
+    }
+    if (llvm::sys::fs::copy_file(path, dst_path)) {
+      errx(1, "failed to copy '%s/%s' to '%s'", src_dir.c_str(), path.str().c_str(),
+           dst_path.c_str());
     }
   }
   fts_close(fts);
diff --git a/tools/versioner/tests/.gitignore b/tools/versioner/tests/.gitignore
new file mode 100644
index 0000000..89f9ac0
--- /dev/null
+++ b/tools/versioner/tests/.gitignore
@@ -0,0 +1 @@
+out/
diff --git a/tools/versioner/tests/preprocessor/expected/foo.h b/tools/versioner/tests/preprocessor/expected/foo.h
index 3e05a1e..b83dd07 100644
--- a/tools/versioner/tests/preprocessor/expected/foo.h
+++ b/tools/versioner/tests/preprocessor/expected/foo.h
@@ -3,44 +3,64 @@
 int also_always_available() __INTRODUCED_IN(9);
 
 
-#if __ANDROID_API__ >= 10
-int needs_guard() __INTRODUCED_IN(10);
-#endif /* __ANDROID_API__ >= 10 */
+#if __ANDROID_API__ >= 13
+int needs_guard() __INTRODUCED_IN(13);
+#endif /* __ANDROID_API__ >= 13 */
 
 
-#if __ANDROID_API__ >= 10
-int already_guarded() __INTRODUCED_IN(10);
+#if __ANDROID_API__ >= 12
+
+#if __ANDROID_API__ >= 13
+int needs_guard_2() __INTRODUCED_IN(13);
+#endif /* __ANDROID_API__ >= 13 */
+
+#endif
+
+#if __ANDROID_API__ >= 13
+int already_guarded() __INTRODUCED_IN(13);
+#endif
+
+#if __ANDROID_API__ > 13
+int already_guarded_2() __INTRODUCED_IN(13);
 #endif
 
 #if defined(__arm__)
 
-#if __ANDROID_API__ >= 11
-int specific_arch() __INTRODUCED_IN(11);
-#endif /* __ANDROID_API__ >= 11 */
+#if __ANDROID_API__ >= 14
+int specific_arch() __INTRODUCED_IN(14);
+#endif /* __ANDROID_API__ >= 14 */
 
+
+#if __ANDROID_API__ >= 14
+int specific_arch_already_guarded() __INTRODUCED_IN(14);
+#endif
+
+#if __ANDROID_API__ > 14
+int specific_arch_already_guarded_2() __INTRODUCED_IN(14);
+#endif
 #endif
 
 #if defined(__arm__) || defined(__i386__)
 
-#if __ANDROID_API__ >= 11
-int multiple_archs() __INTRODUCED_IN(11);
-#endif /* __ANDROID_API__ >= 11 */
+#if __ANDROID_API__ >= 14
+int multiple_archs() __INTRODUCED_IN(14);
+#endif /* __ANDROID_API__ >= 14 */
 
 #endif
 
 // __INTRODUCED_IN_64(21) should be ignored.
 
-#if (defined(__LP64__)) || (defined(__arm__) && __ANDROID_API__ >= 10) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 11) || (defined(__i386__) && __ANDROID_API__ >= 10)
-int multiple_introduced_1() __INTRODUCED_IN_ARM(10) __INTRODUCED_IN_MIPS(11) __INTRODUCED_IN_X86(10)
+#if (defined(__LP64__)) || (defined(__arm__) && __ANDROID_API__ >= 13) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 14) || (defined(__i386__) && __ANDROID_API__ >= 13)
+int multiple_introduced_1() __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(14) __INTRODUCED_IN_X86(13)
     __INTRODUCED_IN_64(21);
-#endif /* (defined(__LP64__)) || (defined(__arm__) && __ANDROID_API__ >= 10) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 11) || (defined(__i386__) && __ANDROID_API__ >= 10) */
+#endif /* (defined(__LP64__)) || (defined(__arm__) && __ANDROID_API__ >= 13) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 14) || (defined(__i386__) && __ANDROID_API__ >= 13) */
 
 
 
-#if (defined(__LP64__) && __ANDROID_API__ >= 22) || (defined(__arm__) && __ANDROID_API__ >= 10) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 11) || (defined(__i386__) && __ANDROID_API__ >= 10)
-int multiple_introduced_2() __INTRODUCED_IN_ARM(10) __INTRODUCED_IN_MIPS(11) __INTRODUCED_IN_X86(10)
+#if (defined(__LP64__) && __ANDROID_API__ >= 22) || (defined(__arm__) && __ANDROID_API__ >= 13) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 14) || (defined(__i386__) && __ANDROID_API__ >= 13)
+int multiple_introduced_2() __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(14) __INTRODUCED_IN_X86(13)
     __INTRODUCED_IN_64(22);
-#endif /* (defined(__LP64__) && __ANDROID_API__ >= 22) || (defined(__arm__) && __ANDROID_API__ >= 10) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 11) || (defined(__i386__) && __ANDROID_API__ >= 10) */
+#endif /* (defined(__LP64__) && __ANDROID_API__ >= 22) || (defined(__arm__) && __ANDROID_API__ >= 13) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 14) || (defined(__i386__) && __ANDROID_API__ >= 13) */
 
 
 
diff --git a/tools/versioner/tests/preprocessor/headers/foo.h b/tools/versioner/tests/preprocessor/headers/foo.h
index ae5b847..7eba47f 100644
--- a/tools/versioner/tests/preprocessor/headers/foo.h
+++ b/tools/versioner/tests/preprocessor/headers/foo.h
@@ -2,25 +2,41 @@
 
 int also_always_available() __INTRODUCED_IN(9);
 
-int needs_guard() __INTRODUCED_IN(10);
+int needs_guard() __INTRODUCED_IN(13);
 
-#if __ANDROID_API__ >= 10
-int already_guarded() __INTRODUCED_IN(10);
+#if __ANDROID_API__ >= 12
+int needs_guard_2() __INTRODUCED_IN(13);
+#endif
+
+#if __ANDROID_API__ >= 13
+int already_guarded() __INTRODUCED_IN(13);
+#endif
+
+#if __ANDROID_API__ > 13
+int already_guarded_2() __INTRODUCED_IN(13);
 #endif
 
 #if defined(__arm__)
-int specific_arch() __INTRODUCED_IN(11);
+int specific_arch() __INTRODUCED_IN(14);
+
+#if __ANDROID_API__ >= 14
+int specific_arch_already_guarded() __INTRODUCED_IN(14);
+#endif
+
+#if __ANDROID_API__ > 14
+int specific_arch_already_guarded_2() __INTRODUCED_IN(14);
+#endif
 #endif
 
 #if defined(__arm__) || defined(__i386__)
-int multiple_archs() __INTRODUCED_IN(11);
+int multiple_archs() __INTRODUCED_IN(14);
 #endif
 
 // __INTRODUCED_IN_64(21) should be ignored.
-int multiple_introduced_1() __INTRODUCED_IN_ARM(10) __INTRODUCED_IN_MIPS(11) __INTRODUCED_IN_X86(10)
+int multiple_introduced_1() __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(14) __INTRODUCED_IN_X86(13)
     __INTRODUCED_IN_64(21);
 
-int multiple_introduced_2() __INTRODUCED_IN_ARM(10) __INTRODUCED_IN_MIPS(11) __INTRODUCED_IN_X86(10)
+int multiple_introduced_2() __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(14) __INTRODUCED_IN_X86(13)
     __INTRODUCED_IN_64(22);
 
 int group_lp32() __INTRODUCED_IN_ARM(12) __INTRODUCED_IN_X86(12) __INTRODUCED_IN_MIPS(12);
diff --git a/tools/versioner/tests/preprocessor/out/foo.h b/tools/versioner/tests/preprocessor/out/foo.h
deleted file mode 100644
index 3e05a1e..0000000
--- a/tools/versioner/tests/preprocessor/out/foo.h
+++ /dev/null
@@ -1,50 +0,0 @@
-int always_available();
-
-int also_always_available() __INTRODUCED_IN(9);
-
-
-#if __ANDROID_API__ >= 10
-int needs_guard() __INTRODUCED_IN(10);
-#endif /* __ANDROID_API__ >= 10 */
-
-
-#if __ANDROID_API__ >= 10
-int already_guarded() __INTRODUCED_IN(10);
-#endif
-
-#if defined(__arm__)
-
-#if __ANDROID_API__ >= 11
-int specific_arch() __INTRODUCED_IN(11);
-#endif /* __ANDROID_API__ >= 11 */
-
-#endif
-
-#if defined(__arm__) || defined(__i386__)
-
-#if __ANDROID_API__ >= 11
-int multiple_archs() __INTRODUCED_IN(11);
-#endif /* __ANDROID_API__ >= 11 */
-
-#endif
-
-// __INTRODUCED_IN_64(21) should be ignored.
-
-#if (defined(__LP64__)) || (defined(__arm__) && __ANDROID_API__ >= 10) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 11) || (defined(__i386__) && __ANDROID_API__ >= 10)
-int multiple_introduced_1() __INTRODUCED_IN_ARM(10) __INTRODUCED_IN_MIPS(11) __INTRODUCED_IN_X86(10)
-    __INTRODUCED_IN_64(21);
-#endif /* (defined(__LP64__)) || (defined(__arm__) && __ANDROID_API__ >= 10) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 11) || (defined(__i386__) && __ANDROID_API__ >= 10) */
-
-
-
-#if (defined(__LP64__) && __ANDROID_API__ >= 22) || (defined(__arm__) && __ANDROID_API__ >= 10) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 11) || (defined(__i386__) && __ANDROID_API__ >= 10)
-int multiple_introduced_2() __INTRODUCED_IN_ARM(10) __INTRODUCED_IN_MIPS(11) __INTRODUCED_IN_X86(10)
-    __INTRODUCED_IN_64(22);
-#endif /* (defined(__LP64__) && __ANDROID_API__ >= 22) || (defined(__arm__) && __ANDROID_API__ >= 10) || (defined(__mips__) && !defined(__LP64__) && __ANDROID_API__ >= 11) || (defined(__i386__) && __ANDROID_API__ >= 10) */
-
-
-
-#if (!defined(__LP64__) && __ANDROID_API__ >= 12) || (defined(__LP64__))
-int group_lp32() __INTRODUCED_IN_ARM(12) __INTRODUCED_IN_X86(12) __INTRODUCED_IN_MIPS(12);
-#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 12) || (defined(__LP64__)) */
-
diff --git a/tools/versioner/tests/preprocessor/run.sh b/tools/versioner/tests/preprocessor/run.sh
index 1b0aae2..60e7024 100644
--- a/tools/versioner/tests/preprocessor/run.sh
+++ b/tools/versioner/tests/preprocessor/run.sh
@@ -1,4 +1,29 @@
-rm -rf out
 set -e
-versioner headers -i -o out
-diff -q -w -B out expected
+
+function run_test {
+  SRC=$1
+  DST=$2
+  rm -rf $2
+  versioner $1 -i -o $2
+  diff -q -w -B $2 expected
+}
+
+run_test headers out
+run_test headers/ out
+run_test headers out/
+run_test headers/ out/
+
+run_test `pwd`/headers out
+run_test `pwd`/headers/ out
+run_test `pwd`/headers out/
+run_test `pwd`/headers/ out/
+
+run_test headers `pwd`/out
+run_test headers/ `pwd`/out
+run_test headers `pwd`/out/
+run_test headers/ `pwd`/out/
+
+run_test `pwd`/headers `pwd`/out
+run_test `pwd`/headers/ `pwd`/out
+run_test `pwd`/headers `pwd`/out/
+run_test `pwd`/headers/ `pwd`/out/
diff --git a/tools/versioner/tests/preprocessor_idempotence/expected/foo.h b/tools/versioner/tests/preprocessor_idempotence/expected/foo.h
new file mode 100644
index 0000000..ed31e8b
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_idempotence/expected/foo.h
@@ -0,0 +1,12 @@
+#if __ANDROID_API__ >= 10
+int foo() __INTRODUCED_IN(10);
+#endif
+
+#if __ANDROID_API__ >= 21
+int bar(int) __INTRODUCED_IN(21);
+#endif
+
+#if __ANDROID_API__ >= 10
+int multiple_1() __INTRODUCED_IN(10);
+int multiple_2() __INTRODUCED_IN(10);
+#endif
diff --git a/tools/versioner/tests/preprocessor_idempotence/headers/foo.h b/tools/versioner/tests/preprocessor_idempotence/headers/foo.h
new file mode 100644
index 0000000..ed31e8b
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_idempotence/headers/foo.h
@@ -0,0 +1,12 @@
+#if __ANDROID_API__ >= 10
+int foo() __INTRODUCED_IN(10);
+#endif
+
+#if __ANDROID_API__ >= 21
+int bar(int) __INTRODUCED_IN(21);
+#endif
+
+#if __ANDROID_API__ >= 10
+int multiple_1() __INTRODUCED_IN(10);
+int multiple_2() __INTRODUCED_IN(10);
+#endif
diff --git a/tools/versioner/tests/preprocessor_idempotence/run.sh b/tools/versioner/tests/preprocessor_idempotence/run.sh
new file mode 100644
index 0000000..1b0aae2
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_idempotence/run.sh
@@ -0,0 +1,4 @@
+rm -rf out
+set -e
+versioner headers -i -o out
+diff -q -w -B out expected
diff --git a/tools/versioner/tests/slow_preprocessor_idempotence/run.sh b/tools/versioner/tests/slow_preprocessor_idempotence/run.sh
new file mode 100644
index 0000000..6426156
--- /dev/null
+++ b/tools/versioner/tests/slow_preprocessor_idempotence/run.sh
@@ -0,0 +1,6 @@
+rm -rf out
+set -e
+mkdir out
+versioner -o out/initial
+versioner out/initial ../../dependencies -o out/second
+diff -qrwB out/initial out/second