diff options
author | Dimitry Ivanov <dimitry@google.com> | 2017-05-03 16:11:25 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-05-03 16:11:27 +0000 |
commit | 846924ae9583991a99a5924b2542c992d4bc094e (patch) | |
tree | 2514a8fe2183d79dbb52d422fa4db73b25f27f6e /tests/dlfcn_test.cpp | |
parent | 6323cfad7472990bde6efe3075faf03f251040ff (diff) | |
parent | 21975b2861d859fb580ddfba50d323740486b7bc (diff) | |
download | bionic-846924ae9583991a99a5924b2542c992d4bc094e.tar.gz |
Merge "Add ifunc for variable test-case"
Diffstat (limited to 'tests/dlfcn_test.cpp')
-rw-r--r-- | tests/dlfcn_test.cpp | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp index 4ff324e34..0ec46634c 100644 --- a/tests/dlfcn_test.cpp +++ b/tests/dlfcn_test.cpp @@ -247,6 +247,40 @@ TEST(dlfcn, dlopen_by_soname) { // mips doesn't support ifuncs #if !defined(__mips__) +TEST(dlfcn, ifunc_variable) { + typedef const char* (*fn_ptr)(); + + // ifunc's choice depends on whether IFUNC_CHOICE has a value + // first check the set case + setenv("IFUNC_CHOICE", "set", 1); + // preload libtest_ifunc_variable_impl.so + void* handle_impl = dlopen("libtest_ifunc_variable_impl.so", RTLD_NOW); + void* handle = dlopen("libtest_ifunc_variable.so", RTLD_NOW); + ASSERT_TRUE(handle != nullptr) << dlerror(); + const char** foo_ptr = reinterpret_cast<const char**>(dlsym(handle, "foo")); + fn_ptr foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library")); + ASSERT_TRUE(foo_ptr != nullptr) << dlerror(); + ASSERT_TRUE(foo_library_ptr != nullptr) << dlerror(); + ASSERT_EQ(strncmp("set", *foo_ptr, 3), 0); + ASSERT_EQ(strncmp("set", foo_library_ptr(), 3), 0); + dlclose(handle); + dlclose(handle_impl); + + // then check the unset case + unsetenv("IFUNC_CHOICE"); + handle_impl = dlopen("libtest_ifunc_variable_impl.so", RTLD_NOW); + handle = dlopen("libtest_ifunc_variable.so", RTLD_NOW); + ASSERT_TRUE(handle != nullptr) << dlerror(); + foo_ptr = reinterpret_cast<const char**>(dlsym(handle, "foo")); + foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library")); + ASSERT_TRUE(foo_ptr != nullptr) << dlerror(); + ASSERT_TRUE(foo_library_ptr != nullptr) << dlerror(); + ASSERT_EQ(strncmp("unset", *foo_ptr, 5), 0); + ASSERT_EQ(strncmp("unset", foo_library_ptr(), 5), 0); + dlclose(handle); + dlclose(handle_impl); +} + TEST(dlfcn, ifunc) { typedef const char* (*fn_ptr)(); @@ -254,11 +288,11 @@ TEST(dlfcn, ifunc) { // first check the set case setenv("IFUNC_CHOICE", "set", 1); void* handle = dlopen("libtest_ifunc.so", RTLD_NOW); - ASSERT_TRUE(handle != nullptr); + ASSERT_TRUE(handle != nullptr) << dlerror(); fn_ptr foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo")); fn_ptr foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library")); - ASSERT_TRUE(foo_ptr != nullptr); - ASSERT_TRUE(foo_library_ptr != nullptr); + ASSERT_TRUE(foo_ptr != nullptr) << dlerror(); + ASSERT_TRUE(foo_library_ptr != nullptr) << dlerror(); ASSERT_EQ(strncmp("set", foo_ptr(), 3), 0); ASSERT_EQ(strncmp("set", foo_library_ptr(), 3), 0); dlclose(handle); @@ -266,13 +300,13 @@ TEST(dlfcn, ifunc) { // then check the unset case unsetenv("IFUNC_CHOICE"); handle = dlopen("libtest_ifunc.so", RTLD_NOW); - ASSERT_TRUE(handle != nullptr); + ASSERT_TRUE(handle != nullptr) << dlerror(); foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo")); foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library")); - ASSERT_TRUE(foo_ptr != nullptr); - ASSERT_TRUE(foo_library_ptr != nullptr); + ASSERT_TRUE(foo_ptr != nullptr) << dlerror(); + ASSERT_TRUE(foo_library_ptr != nullptr) << dlerror(); ASSERT_EQ(strncmp("unset", foo_ptr(), 5), 0); - ASSERT_EQ(strncmp("unset", foo_library_ptr(), 3), 0); + ASSERT_EQ(strncmp("unset", foo_library_ptr(), 5), 0); dlclose(handle); } |