aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDmitriy Ivanov <dimitry@google.com>2014-09-11 15:16:03 -0700
committerDmitriy Ivanov <dimitry@google.com>2014-10-01 16:04:31 -0700
commitf4cb6313645ef65cc0eea0a439e51b6788cd3439 (patch)
tree816f1591e6861e041ec75a8a8181e662ee18e605 /tests
parentef1306d77718cc74a8df5673a15649dea317571d (diff)
downloadbionic-f4cb6313645ef65cc0eea0a439e51b6788cd3439.tar.gz
Add IFUNC support for arm64 and IRELATIVE reloc
There are number of changes in the way IFUNC related relocations are done: 1. IRELATIVE relocations are now supported for x86/x86_64 and arm64. 2. IFUNC relocations are now relying on static linker to generate them in correct order - this removes necessety of additional relocation pass for ifuncs. 3. Related to 2: rela?.dyn relocations are preformed before .plt ones. 4. Ifunc are resolved on symbol lookup this approach allowed to avoid mprotect(PROT_WRITE) call on r-x program segments. Bug: 17399706 Bug: 17177284 (cherry picked from commit 9aea164457c269c475592da36b4655d45f55c7bc) Change-Id: Ie19d900fc203beb93faf8943b0d06d534a6de4ad
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.build.mk4
-rw-r--r--tests/dlfcn_test.cpp14
-rw-r--r--tests/libs/Android.mk10
-rw-r--r--tests/libs/dlopen_testlib_ifunc.c11
4 files changed, 32 insertions, 7 deletions
diff --git a/tests/Android.build.mk b/tests/Android.build.mk
index d4b03960d..d54c851b2 100644
--- a/tests/Android.build.mk
+++ b/tests/Android.build.mk
@@ -37,6 +37,10 @@ LOCAL_CLANG := $($(module)_clang_$(build_type))
LOCAL_FORCE_STATIC_EXECUTABLE := $($(module)_force_static_executable)
+ifneq ($($(module)_multilib),)
+ LOCAL_MULTILIB := $($(module)_multilib)
+endif
+
LOCAL_CFLAGS := \
$(common_cflags) \
$($(module)_cflags) \
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index bb9d8c0b8..ea02c1a83 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -89,8 +89,8 @@ TEST(dlfcn, dlopen_noload) {
ASSERT_EQ(0, dlclose(handle2));
}
-// ifuncs are only supported on intel for now
-#if defined(__i386__) || defined(__x86_64__)
+// ifuncs are only supported on intel and arm64 for now
+#if defined (__aarch64__) || defined(__i386__) || defined(__x86_64__)
TEST(dlfcn, ifunc) {
typedef const char* (*fn_ptr)();
@@ -124,9 +124,13 @@ TEST(dlfcn, ifunc_ctor_call) {
typedef const char* (*fn_ptr)();
void* handle = dlopen("libtest_ifunc.so", RTLD_NOW);
- ASSERT_TRUE(handle != NULL) << dlerror();
- fn_ptr is_ctor_called = reinterpret_cast<fn_ptr>(dlsym(handle, "is_ctor_called"));
- ASSERT_TRUE(is_ctor_called != NULL) << dlerror();
+ ASSERT_TRUE(handle != nullptr) << dlerror();
+ fn_ptr is_ctor_called = reinterpret_cast<fn_ptr>(dlsym(handle, "is_ctor_called_irelative"));
+ ASSERT_TRUE(is_ctor_called != nullptr) << dlerror();
+ ASSERT_STREQ("false", is_ctor_called());
+
+ is_ctor_called = reinterpret_cast<fn_ptr>(dlsym(handle, "is_ctor_called_jump_slot"));
+ ASSERT_TRUE(is_ctor_called != nullptr) << dlerror();
ASSERT_STREQ("true", is_ctor_called());
dlclose(handle);
}
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index 21681eec9..1004b74e9 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -294,7 +294,7 @@ include $(TEST_PATH)/Android.build.mk
# -----------------------------------------------------------------------------
# Library used by ifunc tests
# -----------------------------------------------------------------------------
-ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),arm64 x86 x86_64))
libtest_ifunc_src_files := \
dlopen_testlib_ifunc.c
@@ -302,6 +302,14 @@ ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
module := libtest_ifunc
build_type := target
build_target := SHARED_LIBRARY
+
+ ifeq ($(TARGET_ARCH),arm64)
+ libtest_ifunc_multilib := 64
+ # TODO: This is a workaround - remove it once gcc
+ # removes its Android ifunc checks
+ libtest_ifunc_cflags := -mglibc
+ endif
+
include $(TEST_PATH)/Android.build.mk
endif
diff --git a/tests/libs/dlopen_testlib_ifunc.c b/tests/libs/dlopen_testlib_ifunc.c
index 48748417d..b68a3dd0f 100644
--- a/tests/libs/dlopen_testlib_ifunc.c
+++ b/tests/libs/dlopen_testlib_ifunc.c
@@ -23,8 +23,17 @@ static void __attribute__((constructor)) init_flag() {
g_flag = 1;
}
+static const char* is_ctor_called() __attribute__ ((ifunc("is_ctor_called_ifun")));
+
const char* foo() __attribute__ ((ifunc ("foo_ifunc")));
-const char* is_ctor_called() __attribute__ ((ifunc("is_ctor_called_ifun")));
+
+// Static linker creates GLOBAL/IFUNC symbol and JUMP_SLOT relocation type for plt segment
+const char* is_ctor_called_jump_slot() __attribute__ ((ifunc("is_ctor_called_ifun")));
+
+const char* is_ctor_called_irelative() {
+ // Call internal ifunc-resolved function with IRELATIVE reloc
+ return is_ctor_called();
+}
const char* return_true() {
return "true";