From: Dmitriy Ivanov Date: Wed, 19 Nov 2014 01:26:31 +0000 (-0800) Subject: Yet another relocation test X-Git-Tag: android-x86-7.1-r1~757^2~108^2~225^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=7699d13a74769fe8063fcca95588c87c571226c0;p=android-x86%2Fbionic.git Yet another relocation test This time we check if a -> b -> c function in 'a' relocates against implementation in 'c'. Change-Id: I528180c3efd346bd447ea0237e5a8a0ac3cc031f --- diff --git a/tests/Android.build.mk b/tests/Android.build.mk index 0754a7bf9..5b2b41728 100644 --- a/tests/Android.build.mk +++ b/tests/Android.build.mk @@ -42,6 +42,8 @@ endif LOCAL_FORCE_STATIC_EXECUTABLE := $($(module)_force_static_executable) +LOCAL_ALLOW_UNDEFINED_SYMBOLS := $($(module)_allow_undefined_symbols) + ifneq ($($(module)_multilib),) LOCAL_MULTILIB := $($(module)_multilib) endif diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp index 88f0b197c..ea20869d0 100644 --- a/tests/dlfcn_test.cpp +++ b/tests/dlfcn_test.cpp @@ -278,6 +278,44 @@ TEST(dlfcn, dlopen_check_order_reloc_siblings_with_preload) { ASSERT_EQ(0, dlclose(handle)); } +TEST(dlfcn, dlopen_check_order_reloc_grandchild) { + // This is how this one works: + // we lookup and call grandchild_get_answer which is defined in '_2.so' + // and in turn calls external get_answer_impl() defined in '_c_1.so and _c_2.so' + // the correct _impl() is implemented by '_c_1.so'; + // + // Here is the picture of subtree: + // + // libtest_check_order_reloc_siblings.so + // | + // +-> ..._2.so <- grandchild_get_answer() + // | + // +-> ..._c.so <- empty + // | | + // | +-> _c_1.so <- exports correct answer_impl() + // | | + // | +-> _c_2.so <- exports incorrect answer_impl() + // | + // +-> ..._d.so <- empty + + void* handle = dlopen("libtest_check_order_reloc_siblings.so", RTLD_NOW | RTLD_NOLOAD); + ASSERT_TRUE(handle == nullptr); +#ifdef __BIONIC__ + // TODO: glibc returns nullptr on dlerror() here. Is it bug? + ASSERT_STREQ("dlopen failed: library \"libtest_check_order_reloc_siblings.so\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror()); +#endif + + handle = dlopen("libtest_check_order_reloc_siblings.so", RTLD_NOW | RTLD_LOCAL); + ASSERT_TRUE(handle != nullptr) << dlerror(); + + typedef int (*fn_t) (void); + fn_t fn = reinterpret_cast(dlsym(handle, "check_order_reloc_grandchild_get_answer")); + ASSERT_TRUE(fn != nullptr) << dlerror(); + ASSERT_EQ(42, fn()); + + ASSERT_EQ(0, dlclose(handle)); +} + TEST(dlfcn, dlopen_check_order_reloc_nephew) { // This is how this one works: // we lookup and call nephew_get_answer which is defined in '_2.so' diff --git a/tests/libs/Android.build.dlopen_check_order_reloc_siblings.mk b/tests/libs/Android.build.dlopen_check_order_reloc_siblings.mk index 0f1a2b4da..bd35a51a1 100644 --- a/tests/libs/Android.build.dlopen_check_order_reloc_siblings.mk +++ b/tests/libs/Android.build.dlopen_check_order_reloc_siblings.mk @@ -37,12 +37,13 @@ include $(LOCAL_PATH)/Android.build.testlib.mk # ..._2.so - empty # ----------------------------------------------------------------------------- libtest_check_order_reloc_siblings_2_src_files := \ - empty.cpp + dlopen_check_order_reloc_grandchild_answer.cpp libtest_check_order_reloc_siblings_2_shared_libraries := \ libtest_check_order_reloc_siblings_c \ libtest_check_order_reloc_siblings_d +libtest_check_order_reloc_siblings_2_allow_undefined_symbols := true module := libtest_check_order_reloc_siblings_2 include $(LOCAL_PATH)/Android.build.testlib.mk @@ -86,6 +87,10 @@ libtest_check_order_reloc_siblings_c_src_files := \ dlopen_check_order_reloc_answer_impl.cpp libtest_check_order_reloc_siblings_c_cflags := -D__ANSWER=2 +libtest_check_order_reloc_siblings_c_shared_libraries := \ + libtest_check_order_reloc_siblings_c_1 \ + libtest_check_order_reloc_siblings_c_2 + module := libtest_check_order_reloc_siblings_c include $(LOCAL_PATH)/Android.build.testlib.mk @@ -119,6 +124,26 @@ module := libtest_check_order_reloc_siblings_f include $(LOCAL_PATH)/Android.build.testlib.mk # ----------------------------------------------------------------------------- +# ..._c_1.so +# ----------------------------------------------------------------------------- +libtest_check_order_reloc_siblings_c_1_src_files := \ + dlopen_check_order_reloc_grandchild_answer_impl.cpp + +libtest_check_order_reloc_siblings_c_1_cflags := -D__ANSWER=42 +module := libtest_check_order_reloc_siblings_c_1 +include $(LOCAL_PATH)/Android.build.testlib.mk + +# ----------------------------------------------------------------------------- +# ..._c_2.so +# ----------------------------------------------------------------------------- +libtest_check_order_reloc_siblings_c_2_src_files := \ + dlopen_check_order_reloc_grandchild_answer_impl.cpp + +libtest_check_order_reloc_siblings_c_2_cflags := -D__ANSWER=0 +module := libtest_check_order_reloc_siblings_c_2 +include $(LOCAL_PATH)/Android.build.testlib.mk + +# ----------------------------------------------------------------------------- # libtest_check_order_reloc_siblings.so # ----------------------------------------------------------------------------- libtest_check_order_reloc_siblings_src_files := \ diff --git a/tests/libs/dlopen_check_order_reloc_grandchild_answer.cpp b/tests/libs/dlopen_check_order_reloc_grandchild_answer.cpp new file mode 100644 index 000000000..afb5f2c8d --- /dev/null +++ b/tests/libs/dlopen_check_order_reloc_grandchild_answer.cpp @@ -0,0 +1,22 @@ +/* + * 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 check_order_reloc_grandchild_get_answer_impl(); + +extern "C" int check_order_reloc_grandchild_get_answer() { + return check_order_reloc_grandchild_get_answer_impl(); +} + diff --git a/tests/libs/dlopen_check_order_reloc_grandchild_answer_impl.cpp b/tests/libs/dlopen_check_order_reloc_grandchild_answer_impl.cpp new file mode 100644 index 000000000..32d2b2457 --- /dev/null +++ b/tests/libs/dlopen_check_order_reloc_grandchild_answer_impl.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 check_order_reloc_grandchild_get_answer_impl() { + return __ANSWER; +}