From b2a30ee8d209154efc367db11b4167a5d6db605f Mon Sep 17 00:00:00 2001 From: Dmitriy Ivanov Date: Thu, 4 Sep 2014 18:23:00 -0700 Subject: [PATCH] Fix order of soinfo links (repairs libcxx tests). Change-Id: Iee9de09657351cd6a7512784ca797e4b84cdd98b --- linker/linker.cpp | 4 +-- tests/Android.mk | 1 + tests/dlfcn_test.cpp | 28 +++++++++++++++++++ tests/libs/Android.mk | 23 +++++++++++++++ ...pen_testlib_relo_check_dt_needed_order.cpp | 21 ++++++++++++++ ...n_testlib_relo_check_dt_needed_order_1.cpp | 19 +++++++++++++ ...n_testlib_relo_check_dt_needed_order_2.cpp | 19 +++++++++++++ 7 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 tests/libs/dlopen_testlib_relo_check_dt_needed_order.cpp create mode 100644 tests/libs/dlopen_testlib_relo_check_dt_needed_order_1.cpp create mode 100644 tests/libs/dlopen_testlib_relo_check_dt_needed_order_2.cpp diff --git a/linker/linker.cpp b/linker/linker.cpp index 610489ea5..ac470a54b 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -1778,8 +1778,8 @@ void soinfo::CallDestructors() { void soinfo::add_child(soinfo* child) { if (has_min_version(0)) { - this->children.push_front(child); - child->parents.push_front(this); + child->parents.push_back(this); + this->children.push_back(child); } } diff --git a/tests/Android.mk b/tests/Android.mk index cb588d78e..49efdad9a 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -264,6 +264,7 @@ bionic-unit-tests_ldflags := \ -Wl,-u,DlSymTestFunction \ bionic-unit-tests_c_includes := \ + bionic/libc \ $(call include-path-for, libpagemap) \ bionic-unit-tests_shared_libraries_target := \ diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp index ccfd74319..3568f8fc1 100644 --- a/tests/dlfcn_test.cpp +++ b/tests/dlfcn_test.cpp @@ -22,6 +22,8 @@ #include #include +#include "private/ScopeGuard.h" + #include #define ASSERT_SUBSTR(needle, haystack) \ @@ -130,6 +132,32 @@ TEST(dlfcn, ifunc_ctor_call) { } #endif +TEST(dlfcn, dlopen_check_relocation_dt_needed_order) { + // This is the structure of the test library and + // its dt_needed libraries + // libtest_relo_check_dt_needed_order.so + // | + // +-> libtest_relo_check_dt_needed_order_1.so + // | + // +-> libtest_relo_check_dt_needed_order_2.so + // + // The root library references relo_test_get_answer_lib - which is defined + // in both dt_needed libraries, the correct relocation should + // use the function defined in libtest_relo_check_dt_needed_order_1.so + void* handle = nullptr; + auto guard = create_scope_guard([&]() { + dlclose(handle); + }); + + handle = dlopen("libtest_relo_check_dt_needed_order.so", RTLD_NOW); + ASSERT_TRUE(handle != nullptr) << dlerror(); + + typedef int (*fn_t) (void); + fn_t fn = reinterpret_cast(dlsym(handle, "relo_test_get_answer")); + ASSERT_TRUE(fn != nullptr) << dlerror(); + ASSERT_EQ(1, fn()); +} + TEST(dlfcn, dlopen_check_order) { // Here is how the test library and its dt_needed // libraries are arranged diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk index 2ceb15b9e..be6565bab 100644 --- a/tests/libs/Android.mk +++ b/tests/libs/Android.mk @@ -256,6 +256,29 @@ build_type := target build_target := SHARED_LIBRARY include $(TEST_PATH)/Android.build.mk +# ----------------------------------------------------------------------------- +# libtest_relo_check_dt_needed_order.so +# | +# +-> libtest_relo_check_dt_needed_order_1.so +# | +# +-> libtest_relo_check_dt_needed_order_2.so +# ----------------------------------------------------------------------------- +libtest_relo_check_dt_needed_order_shared_libraries := \ + libtest_relo_check_dt_needed_order_1 libtest_relo_check_dt_needed_order_2 + +libtest_relo_check_dt_needed_order_src_files := dlopen_testlib_relo_check_dt_needed_order.cpp +libtest_relo_check_dt_needed_order_1_src_files := dlopen_testlib_relo_check_dt_needed_order_1.cpp +libtest_relo_check_dt_needed_order_2_src_files := dlopen_testlib_relo_check_dt_needed_order_2.cpp +build_type := target +build_target := SHARED_LIBRARY + +module := libtest_relo_check_dt_needed_order +include $(TEST_PATH)/Android.build.mk +module := libtest_relo_check_dt_needed_order_1 +include $(TEST_PATH)/Android.build.mk +module := libtest_relo_check_dt_needed_order_2 +include $(TEST_PATH)/Android.build.mk + # ----------------------------------------------------------------------------- # Library with dependency used by dlfcn tests # ----------------------------------------------------------------------------- diff --git a/tests/libs/dlopen_testlib_relo_check_dt_needed_order.cpp b/tests/libs/dlopen_testlib_relo_check_dt_needed_order.cpp new file mode 100644 index 000000000..d8fb543ad --- /dev/null +++ b/tests/libs/dlopen_testlib_relo_check_dt_needed_order.cpp @@ -0,0 +1,21 @@ +/* + * 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 relo_test_get_answer_lib(); + +extern "C" int relo_test_get_answer() { + return relo_test_get_answer_lib(); +} diff --git a/tests/libs/dlopen_testlib_relo_check_dt_needed_order_1.cpp b/tests/libs/dlopen_testlib_relo_check_dt_needed_order_1.cpp new file mode 100644 index 000000000..4c877d0a1 --- /dev/null +++ b/tests/libs/dlopen_testlib_relo_check_dt_needed_order_1.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 relo_test_get_answer_lib() { + return 1; +} diff --git a/tests/libs/dlopen_testlib_relo_check_dt_needed_order_2.cpp b/tests/libs/dlopen_testlib_relo_check_dt_needed_order_2.cpp new file mode 100644 index 000000000..10288a086 --- /dev/null +++ b/tests/libs/dlopen_testlib_relo_check_dt_needed_order_2.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 relo_test_get_answer_lib() { + return 2; +}