Open Torrekie opened 1 year ago
As far as I heard no jit works on ios, it is better to disable it.
After several patching I could avoid that SIGBUS using METHOD1, but then resulting all pcre2_jit_tests failed
--- a/src/sljit/sljitExecAllocator.c 1645780892.000000000
+++ b/src/sljit/sljitExecAllocator.c 1677493457.634072731
@@ -158,7 +158,62 @@ static SLJIT_INLINE void apple_update_wx
}
#endif /* SLJIT_CONFIG_X86 */
#else /* !TARGET_OS_OSX */
+#define _COMM_PAGE_START_ADDRESS (0x0000000FFFFFC000ULL) /* In TTBR0 */
+#define _COMM_PAGE_APRR_SUPPORT (_COMM_PAGE_START_ADDRESS + 0x10C)
+#define _COMM_PAGE_APPR_WRITE_ENABLE (_COMM_PAGE_START_ADDRESS + 0x110)
+#define _COMM_PAGE_APRR_WRITE_DISABLE (_COMM_PAGE_START_ADDRESS + 0x118)
+
#define SLJIT_MAP_JIT (MAP_JIT)
+#ifdef METHOD1
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
+ apple_update_wx_flags(enable_exec)
+#warning Using https://siguza.github.io/APRR/
+static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec)
+{
+ uint8_t aprr_support = *(volatile uint8_t *)_COMM_PAGE_APRR_SUPPORT;
+ if (aprr_support == 0 || aprr_support > 3) {
+ return;
+ } else if (aprr_support == 1) {
+ __asm__ __volatile__ (
+ "mov x0, %0\n"
+ "ldr x0, [x0]\n"
+ "msr S3_4_c15_c2_7, x0\n"
+ "isb sy\n"
+ :: "r" (enable_exec ? _COMM_PAGE_APRR_WRITE_DISABLE
+ : _COMM_PAGE_APPR_WRITE_ENABLE)
+ : "memory", "x0"
+ );
+ } else {
+ __asm__ __volatile__ (
+ "mov x0, %0\n"
+ "ldr x0, [x0]\n"
+ "msr S3_6_c15_c1_5, x0\n"
+ "isb sy\n"
+ :: "r" (enable_exec ? _COMM_PAGE_APRR_WRITE_DISABLE
+ : _COMM_PAGE_APPR_WRITE_ENABLE)
+ : "memory", "x0"
+ );
+ }
+}
+#elif defined(METHOD2)
+#warning Using mprotect
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
+ update_wx_flags(from, to, enable_exec)
+static SLJIT_INLINE void update_wx_flags(void *from, void *to, int enable_exec)
+{
+ sljit_uw page_mask = (sljit_uw)get_page_alignment();
+ sljit_uw start = (sljit_uw)from;
+ sljit_uw end = (sljit_uw)to;
+ int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE);
+
+ SLJIT_ASSERT(start < end);
+
+ start &= ~page_mask;
+ end = (end + page_mask) & ~page_mask;
+
+ mprotect((void*)start, end - start, prot);
+}
+#endif
#endif /* TARGET_OS_OSX */
#endif /* __APPLE__ && MAP_JIT */
#ifndef SLJIT_UPDATE_WX_FLAGS
iPad:/buildroot/pcre2-10.42 root# .libs/pcre2_jit_test | grep "%"
Successful test ratio: 0% (674 failed)
Invalid UTF8 successful test ratio: 0% (129 failed)
Invalid UTF16 successful test ratio: 0% (39 failed)
Invalid UTF32 successful test ratio: 0% (26 failed)
The last thing I heard, no jit is allowed in iOS, because it hurts monetizing the platform. I also heard jit works on jailbroken devices, but that is special case.
basically, there have JIT support on iOS with dynamic-codesigning
entitlement enabled (which also enabled for Safari.app) and I am pretty sure there used to have iOS JIT support during PCRE 8.x. Actually partial JIT tests passed after my modification but still meeting some weird errors on others. I believe it can work properly if we are able to handle W^X in a better way (https://github.com/qemu/qemu/commit/36195a781c1c7237935b45c30a91686c07a10474 this fork using the exactly same method that I mentioned above to replace previous pthread_jit_write_protect_np
and it do have working JIT on both macOS/iOS)
Sounds interesting. Unfortunately I cannot help since I have no access to any Apple device, but somebody else might know something. Maybe in some apple dev forums.
Retried today and have to say defining SLJIT_WX_EXECUTABLE_ALLOCATOR
and make non-macOS Darwin targets to use POSIX implementation is now having a working JIT outside of sandbox. But this macro doesn’t seems configurable by autoconf script.
so the thing is:
sandbox_apply()
or container-required
), use the pthread_jit_write_protect_np
API (Which exactly same as the APRR hack i commented before), which allows RWX pages being created when MAP_JIT
and dynamic-codesigning
entitlement specified.MAP_JIT
shouldn’t be added, no RWX pages can be used, either allocate two separate region for JIT RW/RX or some mirror mapping like thisJIT (SLJIT_WX_EXECUTABLE_ALLOCATOR
defined, unsandboxed)
iPad:/buildroot/pcre2-10.43 root# ./pcre2_jit_test
Running JIT regression tests
target CPU of SLJIT compiler: ARM-64 64bit (little endian + unaligned)
in 8 bit mode with UTF-8 enabled:
in 16 bit mode with UTF-16 enabled:
in 32 bit mode with UTF-32 enabled:
............................................................
............................................................
............................................................
............................................................
............................................................
............................................................
............................................................
............................................................
............................................................
............................................................
............................................................
............................
All JIT regression tests are successfully passed.
Running invalid-utf8 JIT regression tests
............................................................
............................................................
............
All invalid UTF8 JIT regression tests are successfully passed.
Running invalid-utf16 JIT regression tests
.......................................
All invalid UTF16 JIT regression tests are successfully passed.
Running invalid-utf32 JIT regression tests
..........................
All invalid UTF32 JIT regression tests are successfully passed.
On iOS there's no
pthread_jit*
API provided by Apple, resultingPROT_WRITE
andPROT_EXEC
has been set at same time, causingKERN_PROTECTION_FAILURE