Add test for libraries with textrels

Make sure android fails to load them.

Bug: http://b/30795430
Test: bionic-unit-tests --gtest_filter=dlfcn.dlopen_invalid*
Test: cts-tradefed run singleCommand cts --skip-preconditions -m CtsBionicTestCases
Change-Id: Id0ebdf336b2f297007479ceb1bbccf778a7ca3f2
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b2e8dbc..f8531b6 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -2880,7 +2880,7 @@
 
       case DT_TEXTREL:
 #if defined(__LP64__)
-        DL_ERR("text relocations (DT_TEXTREL) found in 64-bit ELF file \"%s\"", get_realpath());
+        DL_ERR("\"%s\" has text relocations", get_realpath());
         return false;
 #else
         has_text_relocations = true;
@@ -2898,7 +2898,7 @@
       case DT_FLAGS:
         if (d->d_un.d_val & DF_TEXTREL) {
 #if defined(__LP64__)
-          DL_ERR("text relocations (DF_TEXTREL) found in 64-bit ELF file \"%s\"", get_realpath());
+          DL_ERR("\"%s\" has text relocations", get_realpath());
           return false;
 #else
           has_text_relocations = true;
@@ -2913,7 +2913,7 @@
         set_dt_flags_1(d->d_un.d_val);
 
         if ((d->d_un.d_val & ~SUPPORTED_DT_FLAGS_1) != 0) {
-          DL_WARN("%s: unsupported flags DT_FLAGS_1=%p", get_realpath(), reinterpret_cast<void*>(d->d_un.d_val));
+          DL_WARN("\"%s\" has unsupported flags DT_FLAGS_1=%p", get_realpath(), reinterpret_cast<void*>(d->d_un.d_val));
         }
         break;
 #if defined(__mips__)
@@ -2980,7 +2980,7 @@
 
       default:
         if (!relocating_linker) {
-          DL_WARN("%s: unused DT entry: type %p arg %p", get_realpath(),
+          DL_WARN("\"%s\" unused DT entry: type %p arg %p", get_realpath(),
               reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
         }
         break;
@@ -3067,13 +3067,12 @@
   if (has_text_relocations) {
     // Fail if app is targeting sdk version > 22
     if (get_application_target_sdk_version() > 22) {
-      PRINT("%s: has text relocations", get_realpath());
-      DL_ERR("%s: has text relocations", get_realpath());
+      DL_ERR_AND_LOG("\"%s\" has text relocations", get_realpath());
       return false;
     }
     // Make segments writable to allow text relocations to work properly. We will later call
     // phdr_table_protect_segments() after all of them are applied.
-    DL_WARN("%s has text relocations. This is wasting memory and prevents "
+    DL_WARN("\"%s\" has text relocations. This is wasting memory and prevents "
             "security hardening. Please fix.", get_realpath());
     add_dlwarning(get_realpath(), "text relocations");
     if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
diff --git a/tests/Android.mk b/tests/Android.mk
index e1efbbe..b65b456 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -41,6 +41,12 @@
 bionic_tests_module := libtest_invalid-zero_shdr_table_content.so
 include $(LOCAL_PATH)/Android.build.prebuilt.mk
 
+bionic_tests_module := libtest_invalid-textrels.so
+include $(LOCAL_PATH)/Android.build.prebuilt.mk
+
+bionic_tests_module := libtest_invalid-textrels2.so
+include $(LOCAL_PATH)/Android.build.prebuilt.mk
+
 ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
 build_host := true
 else
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index dd9660b..5908fc3 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1227,4 +1227,26 @@
   ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
 }
 
+TEST(dlfcn, dlopen_invalid_textrels) {
+  const std::string libpath = g_testlib_root +
+                              "/" + kPrebuiltElfDir +
+                              "/libtest_invalid-textrels.so";
+
+  void* handle = dlopen(libpath.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle == nullptr);
+  std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\" has text relocations";
+  ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
+}
+
+TEST(dlfcn, dlopen_invalid_textrels2) {
+  const std::string libpath = g_testlib_root +
+                              "/" + kPrebuiltElfDir +
+                              "/libtest_invalid-textrels2.so";
+
+  void* handle = dlopen(libpath.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle == nullptr);
+  std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\" has text relocations";
+  ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
+}
+
 #endif
diff --git a/tests/prebuilt-elf-files/arm/libtest_invalid-textrels.so b/tests/prebuilt-elf-files/arm/libtest_invalid-textrels.so
new file mode 100755
index 0000000..7e852c0
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm/libtest_invalid-textrels.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm/libtest_invalid-textrels2.so b/tests/prebuilt-elf-files/arm/libtest_invalid-textrels2.so
new file mode 100755
index 0000000..26ebdb9
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm/libtest_invalid-textrels2.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels.so
new file mode 100755
index 0000000..7d925cb
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels2.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels2.so
new file mode 100755
index 0000000..7eb62f5
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels2.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/mips/libtest_invalid-textrels.so b/tests/prebuilt-elf-files/mips/libtest_invalid-textrels.so
new file mode 100755
index 0000000..9405863
--- /dev/null
+++ b/tests/prebuilt-elf-files/mips/libtest_invalid-textrels.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/mips/libtest_invalid-textrels2.so b/tests/prebuilt-elf-files/mips/libtest_invalid-textrels2.so
new file mode 100755
index 0000000..eb9d61c
--- /dev/null
+++ b/tests/prebuilt-elf-files/mips/libtest_invalid-textrels2.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/mips64/libtest_invalid-textrels.so b/tests/prebuilt-elf-files/mips64/libtest_invalid-textrels.so
new file mode 100755
index 0000000..d387691
--- /dev/null
+++ b/tests/prebuilt-elf-files/mips64/libtest_invalid-textrels.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/mips64/libtest_invalid-textrels2.so b/tests/prebuilt-elf-files/mips64/libtest_invalid-textrels2.so
new file mode 100755
index 0000000..eb5868a
--- /dev/null
+++ b/tests/prebuilt-elf-files/mips64/libtest_invalid-textrels2.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86/libtest_invalid-textrels.so b/tests/prebuilt-elf-files/x86/libtest_invalid-textrels.so
new file mode 100755
index 0000000..ad78ed4
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86/libtest_invalid-textrels.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86/libtest_invalid-textrels2.so b/tests/prebuilt-elf-files/x86/libtest_invalid-textrels2.so
new file mode 100755
index 0000000..f70b1fa
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86/libtest_invalid-textrels2.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels.so
new file mode 100755
index 0000000..425eb8b
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so
new file mode 100755
index 0000000..ede0148
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so
Binary files differ