summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDmitriy Ivanov <dimitry@google.com>2014-08-28 14:12:12 -0700
committerDmitriy Ivanov <dimitry@google.com>2014-10-31 17:10:30 -0700
commit976402cca13a1f4f3aa988fd301575e134ef5f2c (patch)
tree96d5ca98af5d4638b03541afc5e40d1f888516c0 /tests
parentbf3d5ef5fd240d4c5fbde1b32f9084dbc720840b (diff)
downloadbionic-976402cca13a1f4f3aa988fd301575e134ef5f2c.zip
bionic-976402cca13a1f4f3aa988fd301575e134ef5f2c.tar.gz
bionic-976402cca13a1f4f3aa988fd301575e134ef5f2c.tar.bz2
Fix symbol lookup order during relocation
Relocate symbol against DF_1_GLOBAL shared libraries loaded before this shared library. This includes main executable, ld_preloads and other libraries that have DF_1_GLOBAL flag set. Bug: 2643900 Bug: 15432753 Bug: 18186310 (cherry picked from commit d225a5e65223b375a63548c4b780f04d8f3d7b60) Change-Id: I4e889cdf2dfbf8230b0790053d311ee6b0d0ee2d
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.mk13
-rw-r--r--tests/dl_test.cpp72
-rw-r--r--tests/dlfcn_test.cpp14
-rw-r--r--tests/libs/Android.mk36
-rw-r--r--tests/libs/dl_df_1_global.cpp19
-rw-r--r--tests/libs/dl_df_1_use_global.cpp23
-rw-r--r--tests/libs/dl_preempt_library_1.cpp45
-rw-r--r--tests/libs/dl_preempt_library_2.cpp37
8 files changed, 257 insertions, 2 deletions
diff --git a/tests/Android.mk b/tests/Android.mk
index 8b0b0a0..6423df1 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -225,6 +225,7 @@ bionic-unit-tests_whole_static_libraries := \
bionic-unit-tests_src_files := \
atexit_test.cpp \
+ dl_test.cpp \
dlext_test.cpp \
dlfcn_test.cpp \
@@ -237,8 +238,7 @@ bionic-unit-tests_conlyflags := \
bionic-unit-tests_cppflags := $(test_cppflags)
bionic-unit-tests_ldflags := \
- -Wl,--export-dynamic \
- -Wl,-u,DlSymTestFunction \
+ -Wl,--export-dynamic
bionic-unit-tests_c_includes := \
bionic/libc \
@@ -247,6 +247,9 @@ bionic-unit-tests_c_includes := \
bionic-unit-tests_shared_libraries_target := \
libdl \
libpagemap \
+ libdl_preempt_test_1 \
+ libdl_preempt_test_2 \
+ libdl_test_df_1_global
module := bionic-unit-tests
module_tag := optional
@@ -286,6 +289,12 @@ ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x
bionic-unit-tests-glibc_src_files := \
atexit_test.cpp \
dlfcn_test.cpp \
+ dl_test.cpp \
+
+bionic-unit-tests-glibc_shared_libraries := \
+ libdl_preempt_test_1 \
+ libdl_preempt_test_2 \
+ libdl_test_df_1_global
bionic-unit-tests-glibc_whole_static_libraries := \
libBionicStandardTests \
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
new file mode 100644
index 0000000..74c7b51
--- /dev/null
+++ b/tests/dl_test.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <dlfcn.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include <string>
+
+extern "C" int main_global_default_serial() {
+ return 3370318;
+}
+
+extern "C" int main_global_protected_serial() {
+ return 2716057;
+}
+
+// The following functions are defined in DT_NEEDED
+// libdl_preempt_test.so library.
+
+// This one calls main_global_default_serial
+extern "C" int main_global_default_get_serial();
+
+// This one calls main_global_protected_serial
+extern "C" int main_global_protected_get_serial();
+
+// This one calls lib_global_default_serial
+extern "C" int lib_global_default_get_serial();
+
+// This one calls lib_global_protected_serial
+extern "C" int lib_global_protected_get_serial();
+
+// This test verifies that the global default function
+// main_global_default_serial() is preempted by
+// the function defined above.
+TEST(dl, main_preempts_global_default) {
+ ASSERT_EQ(3370318, main_global_default_get_serial());
+}
+
+// This one makes sure that the global protected
+// symbols do not get preempted
+TEST(dl, main_does_not_preempt_global_protected) {
+ ASSERT_EQ(3370318, main_global_protected_get_serial());
+}
+
+// check same things for lib
+TEST(dl, lib_preempts_global_default) {
+ ASSERT_EQ(3370318, lib_global_default_get_serial());
+}
+
+TEST(dl, lib_does_not_preempt_global_protected) {
+ ASSERT_EQ(3370318, lib_global_protected_get_serial());
+}
+
+// TODO: Add tests for LD_PRELOADs
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index e604f5a..a7fe2f8 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -499,6 +499,20 @@ TEST(dlfcn, dlopen_nodelete_dt_flags_1) {
ASSERT_TRUE(!is_unloaded);
}
+TEST(dlfcn, dlsym_df_1_global) {
+#if !defined(__arm__)
+ void* handle = dlopen("libtest_dlsym_df_1_global.so", RTLD_NOW);
+ ASSERT_TRUE(handle != nullptr) << dlerror();
+ int (*get_answer)();
+ get_answer = reinterpret_cast<int (*)()>(dlsym(handle, "dl_df_1_global_get_answer"));
+ ASSERT_TRUE(get_answer != nullptr) << dlerror();
+ ASSERT_EQ(42, get_answer());
+ ASSERT_EQ(0, dlclose(handle));
+#else
+ GTEST_LOG_(INFO) << "This test does nothing on arm (to be reenabled once b/18137520 or b/18130452 are fixed).\n";
+#endif
+}
+
TEST(dlfcn, dlopen_failure) {
void* self = dlopen("/does/not/exist", RTLD_NOW);
ASSERT_TRUE(self == NULL);
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index 05e7113..f45e5a8 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -290,6 +290,42 @@ module := libtest_atexit
include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
+# This library is used by dl_load test to check symbol preempting
+# by main executable
+# -----------------------------------------------------------------------------
+libdl_preempt_test_1_src_files := dl_preempt_library_1.cpp
+
+module := libdl_preempt_test_1
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
+# This library is used by dl_load test to check symbol preempting
+# by libdl_preempt_test_1.so
+# -----------------------------------------------------------------------------
+libdl_preempt_test_2_src_files := dl_preempt_library_2.cpp
+
+module := libdl_preempt_test_2
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
+# Library with DF_1_GLOBAL
+# -----------------------------------------------------------------------------
+# TODO: re-enable arm once b/18137520 or b/18130452 are fixed
+ifeq ($(filter $(TARGET_ARCH),arm),)
+libdl_test_df_1_global_src_files := dl_df_1_global.cpp
+libdl_test_df_1_global_ldflags := -fuse-ld=bfd -Wl,-z,global
+module := libdl_test_df_1_global
+include $(LOCAL_PATH)/Android.build.testlib.mk
+endif
+
+# -----------------------------------------------------------------------------
+# Library using symbol from libdl_test_df_1_global
+# -----------------------------------------------------------------------------
+libtest_dlsym_df_1_global_src_files := dl_df_1_use_global.cpp
+module := libtest_dlsym_df_1_global
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
# Library with weak function
# -----------------------------------------------------------------------------
libtest_dlsym_weak_func_src_files := \
diff --git a/tests/libs/dl_df_1_global.cpp b/tests/libs/dl_df_1_global.cpp
new file mode 100644
index 0000000..39856fd
--- /dev/null
+++ b/tests/libs/dl_df_1_global.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+extern "C" int dl_df_1_global_get_answer_impl() {
+ return 42;
+}
diff --git a/tests/libs/dl_df_1_use_global.cpp b/tests/libs/dl_df_1_use_global.cpp
new file mode 100644
index 0000000..e14910d
--- /dev/null
+++ b/tests/libs/dl_df_1_use_global.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+extern "C" int __attribute__((weak)) dl_df_1_global_get_answer_impl() {
+ return 0;
+}
+
+extern "C" int dl_df_1_global_get_answer() {
+ return dl_df_1_global_get_answer_impl();
+}
diff --git a/tests/libs/dl_preempt_library_1.cpp b/tests/libs/dl_preempt_library_1.cpp
new file mode 100644
index 0000000..b4d81d5
--- /dev/null
+++ b/tests/libs/dl_preempt_library_1.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// This one should be preempted by the function
+// defined in the main executable.
+extern "C" int __attribute__((weak)) main_global_default_serial() {
+ return 2716057;
+}
+
+// Even though this one is defined by the main
+// executable it should not be preempted
+// because of protected visibility
+extern "C" int __attribute__((weak, visibility("protected"))) main_global_protected_serial() {
+ return 3370318;
+}
+
+extern "C" int main_global_default_get_serial() {
+ return main_global_default_serial();
+}
+
+extern "C" int main_global_protected_get_serial() {
+ return main_global_protected_serial();
+}
+
+// Trying to preempt functions from a DT_NEEDED .so
+extern "C" int lib_global_default_serial() {
+ return 3370318;
+}
+
+extern "C" int lib_global_protected_serial() {
+ return 2716057;
+}
diff --git a/tests/libs/dl_preempt_library_2.cpp b/tests/libs/dl_preempt_library_2.cpp
new file mode 100644
index 0000000..8df9a16
--- /dev/null
+++ b/tests/libs/dl_preempt_library_2.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// This one should be preempted by the function
+// defined in libdl_preempt_test_1.so
+extern "C" int __attribute__((weak)) lib_global_default_serial() {
+ return 2716057;
+}
+
+// Even though this one is defined by
+// libdl_preempt_test_1.so it should not be
+// preempted because of protected visibility
+extern "C" int __attribute__((weak,visibility("protected"))) lib_global_protected_serial() {
+ return 3370318;
+}
+
+extern "C" int lib_global_default_get_serial() {
+ return lib_global_default_serial();
+}
+
+extern "C" int lib_global_protected_get_serial() {
+ return lib_global_protected_serial();
+}
+