2 * Copyright (C) 2012 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <gtest/gtest.h>
29 #include "gtest_globals.h"
32 extern "C" int main_global_default_serial() {
36 extern "C" int main_global_protected_serial() {
40 // The following functions are defined in DT_NEEDED
41 // libdl_preempt_test.so library.
43 // This one calls main_global_default_serial
44 extern "C" int main_global_default_get_serial();
46 // This one calls main_global_protected_serial
47 extern "C" int main_global_protected_get_serial();
49 // This one calls lib_global_default_serial
50 extern "C" int lib_global_default_get_serial();
52 // This one calls lib_global_protected_serial
53 extern "C" int lib_global_protected_get_serial();
55 // This test verifies that the global default function
56 // main_global_default_serial() is preempted by
57 // the function defined above.
58 TEST(dl, main_preempts_global_default) {
59 ASSERT_EQ(3370318, main_global_default_get_serial());
62 // This one makes sure that the global protected
63 // symbols do not get preempted
64 TEST(dl, main_does_not_preempt_global_protected) {
65 ASSERT_EQ(3370318, main_global_protected_get_serial());
68 // check same things for lib
69 TEST(dl, lib_preempts_global_default) {
70 ASSERT_EQ(3370318, lib_global_default_get_serial());
73 TEST(dl, lib_does_not_preempt_global_protected) {
74 ASSERT_EQ(3370318, lib_global_protected_get_serial());
77 TEST(dl, exec_linker) {
78 #if defined(__BIONIC__)
80 static constexpr const char* kPathToLinker = "/system/bin/linker64";
82 static constexpr const char* kPathToLinker = "/system/bin/linker";
85 std::string expected_output = std::string("This is ") + kPathToLinker +
86 ", the helper program for dynamic executables.\n";
87 eth.SetArgs( { kPathToLinker, nullptr });
88 eth.Run([&]() { execve(kPathToLinker, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
92 TEST(dl, preinit_system_calls) {
93 #if defined(__BIONIC__)
94 std::string helper = get_testlib_root() +
95 "/preinit_syscall_test_helper/preinit_syscall_test_helper";
96 chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
98 eth.SetArgs({ helper.c_str(), nullptr });
99 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, nullptr);
103 TEST(dl, xfail_preinit_getauxval) {
104 #if defined(__BIONIC__)
105 std::string helper = get_testlib_root() +
106 "/preinit_getauxval_test_helper/preinit_getauxval_test_helper";
107 chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
109 eth.SetArgs({ helper.c_str(), nullptr });
110 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, nullptr);
115 TEST(dl, exec_without_ld_preload) {
116 #if defined(__BIONIC__)
117 std::string helper = get_testlib_root() +
118 "/ld_preload_test_helper/ld_preload_test_helper";
119 chmod(helper.c_str(), 0755);
121 eth.SetArgs({ helper.c_str(), nullptr });
122 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345");
126 TEST(dl, exec_with_ld_preload) {
127 #if defined(__BIONIC__)
128 std::string helper = get_testlib_root() +
129 "/ld_preload_test_helper/ld_preload_test_helper";
130 std::string env = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_preload_test_helper_lib2.so";
131 chmod(helper.c_str(), 0755);
133 eth.SetArgs({ helper.c_str(), nullptr });
134 eth.SetEnv({ env.c_str(), nullptr });
135 // ld_preload_test_helper calls get_value_from_lib() and returns the value.
136 // The symbol is defined by two libs: ld_preload_test_helper_lib.so and
137 // ld_preloaded_lib.so. The former is DT_NEEDED and the latter is LD_PRELOADED
138 // via this execution. The main executable is linked to the LD_PRELOADED lib
139 // and the value given from the lib is returned.
140 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321");
145 // ld_config_test_helper must fail because it is depending on a lib which is not
146 // in the search path
148 // Call sequence is...
149 // _helper -- (get_value_from_lib()) -->
150 // _lib1.so -- (get_value_from_another_lib()) -->
151 // _lib2.so (returns 12345)
152 // The two libs are in ns2/ subdir.
153 TEST(dl, exec_without_ld_config_file) {
154 #if defined(__BIONIC__)
155 std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n";
156 std::string helper = get_testlib_root() +
157 "/ld_config_test_helper/ld_config_test_helper";
158 chmod(helper.c_str(), 0755);
160 eth.SetArgs({ helper.c_str(), nullptr });
161 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
165 #if defined(__BIONIC__)
166 static void create_ld_config_file(std::string& config_file) {
167 std::ofstream fout(config_file.c_str(), std::ios::out);
168 fout << "dir.test = " << get_testlib_root() << "/ld_config_test_helper/" << std::endl
169 << "[test]" << std::endl
170 << "additional.namespaces = ns2" << std::endl
171 << "namespace.default.search.paths = " << get_testlib_root() << std::endl
172 << "namespace.default.links = ns2" << std::endl
173 << "namespace.default.link.ns2.shared_libs = libc.so:libm.so:libdl.so:ld_config_test_helper_lib1.so" << std::endl
174 << "namespace.ns2.search.paths = /system/${LIB}:" << get_testlib_root() << "/ns2" << std::endl;
179 #ifdef USE_LD_CONFIG_FILE
181 // _lib1.so and _lib2.so are now searchable by having another namespace 'ns2'
182 // whose search paths include the 'ns2/' subdir.
183 TEST(dl, exec_with_ld_config_file) {
184 #if defined(__BIONIC__)
185 std::string helper = get_testlib_root() +
186 "/ld_config_test_helper/ld_config_test_helper";
187 std::string config_file = get_testlib_root() + "/ld.config.txt";
188 create_ld_config_file(config_file);
189 std::string env = std::string("LD_CONFIG_FILE=") + config_file;
190 chmod(helper.c_str(), 0755);
192 eth.SetArgs({ helper.c_str(), nullptr });
193 eth.SetEnv({ env.c_str(), nullptr });
194 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345");
198 // _lib3.so has same symbol as lib2.so but returns 54321. _lib3.so is
199 // LD_PRELOADed. This test is to ensure LD_PRELOADed libs are available to
200 // additional namespaces other than the default namespace.
201 TEST(dl, exec_with_ld_config_file_with_ld_preload) {
202 #if defined(__BIONIC__)
203 std::string helper = get_testlib_root() +
204 "/ld_config_test_helper/ld_config_test_helper";
205 std::string config_file = get_testlib_root() + "/ld.config.txt";
206 create_ld_config_file(config_file);
207 std::string env = std::string("LD_CONFIG_FILE=") + config_file;
208 std::string env2 = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_config_test_helper_lib3.so";
209 chmod(helper.c_str(), 0755);
211 eth.SetArgs({ helper.c_str(), nullptr });
212 eth.SetEnv({ env.c_str(), env2.c_str(), nullptr });
213 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321");
217 #endif // USE_LD_CONFIG_FILE
219 // ensures that LD_CONFIG_FILE env var does not work for production builds.
220 // The test input is the same as exec_with_ld_config_file, but it must fail in
222 TEST(dl, disable_ld_config_file) {
223 #if defined(__BIONIC__)
225 // when executed from the shell (e.g. not as part of CTS), skip the test.
226 // This test is only for CTS.
229 std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n";
230 std::string helper = get_testlib_root() +
231 "/ld_config_test_helper/ld_config_test_helper";
232 std::string config_file = get_testlib_root() + "/ld.config.txt";
233 create_ld_config_file(config_file);
234 std::string env = std::string("LD_CONFIG_FILE=") + config_file;
235 chmod(helper.c_str(), 0755);
237 eth.SetArgs({ helper.c_str(), nullptr });
238 eth.SetEnv({ env.c_str(), nullptr });
239 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());