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
Change-Id: I414dd3e82bd47cc03442c5dfc7c279949aec51ed
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index be6565b..a675a4f 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -295,7 +295,7 @@
# -----------------------------------------------------------------------------
# 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
@@ -303,6 +303,14 @@
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 4874841..b68a3dd 100644
--- a/tests/libs/dlopen_testlib_ifunc.c
+++ b/tests/libs/dlopen_testlib_ifunc.c
@@ -23,8 +23,17 @@
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";