Merge pull request #4110 from BrzVlad/fix-sgen-win32
[mono.git] / mono / mini / mini-arm-tls.h
index 57d584ffe4e02525d5b35441773b9c88fc684e86..3fa4bef20620202cd3a6348f87101802f6d5a886 100644 (file)
@@ -20,6 +20,9 @@ void mono_fast_set_tls_key_end (void);
 void mono_fast_get_tls_key2_end (void);
 void mono_fast_set_tls_key2_end (void);
 
+#if defined(__linux__) && defined(HAVE_KW_THREAD) && defined(__ARM_EABI__)
+void* __aeabi_read_tp (void);
+#endif
 
 /* Structure that maps a possible  tls implementation to the corresponding thunks */
 typedef struct {
@@ -34,8 +37,9 @@ typedef struct {
 
 
 static MonoTlsImplementation known_tls_implementations [] = {
-#if defined(HAVE_KW_THREAD) && defined(__linux__)
-       { NULL, 0, TRUE, mono_fast_get_tls_key, mono_fast_get_tls_key_end, mono_fast_set_tls_key, mono_fast_set_tls_key_end }
+#if defined(HAVE_KW_THREAD) && defined(__linux__) && defined(__ARM_EABI__)
+       { (guint32[]) {0x0f70ee1d, 0xbf004770}, 8, FALSE, mono_fast_get_tls_key, mono_fast_get_tls_key_end, mono_fast_set_tls_key, mono_fast_set_tls_key_end },
+       { (guint32[]) {0xe3e00a0f, 0xe240f01f}, 8, TRUE, mono_fast_get_tls_key, mono_fast_get_tls_key_end, mono_fast_set_tls_key, mono_fast_set_tls_key_end }
 #elif defined(TARGET_IOS)
        { (guint32[]) {0x1f70ee1d, 0x0103f021, 0x0020f851, 0xbf004770}, 16, FALSE, mono_fast_get_tls_key, mono_fast_get_tls_key_end, mono_fast_set_tls_key, mono_fast_set_tls_key_end }
 #elif defined(TARGET_ANDROID)
@@ -62,16 +66,43 @@ known_kernel_helper (void)
 #endif
 }
 
+static void
+dump_code (guint32 *ptr)
+{
+       char current_impl [256];
+       char hex [16];
+       int i;
+       guint32 page_mask = ~((guint32)mono_pagesize () - 1);
+
+       current_impl [0] = 0;
+       for (i = 0; i < 16; i++) {
+               /* Don't risk page fault since we don't know where the code ends */
+               if (((guint32)&ptr [i] & page_mask) != ((guint32)ptr & page_mask))
+                       break;
+               sprintf (hex, "0x%x ", ptr [i]);
+               strcat (current_impl, hex);
+       }
+
+       g_warning (current_impl);
+}
+
 static MonoTlsImplementation
 mono_arm_get_tls_implementation (void)
 {
+#ifdef MONO_CROSS_COMPILE
+       g_assert_not_reached ();
+#else
        /* Discard thumb bit */
-       guint32* pthread_getspecific_addr = (guint32*) ((guint32)pthread_getspecific & 0xfffffffe);
+#if defined(__linux__) && defined(HAVE_KW_THREAD) && defined(__ARM_EABI__)
+       guint32* check_addr = (guint32*) ((guint32)__aeabi_read_tp & 0xfffffffe);
+#else
+       guint32* check_addr = (guint32*) ((guint32)pthread_getspecific & 0xfffffffe);
+#endif
        int i;
 
        if (!mini_get_debug_options ()->arm_use_fallback_tls) {
                for (i = 0; i < sizeof (known_tls_implementations) / sizeof (MonoTlsImplementation); i++) {
-                       if (memcmp (pthread_getspecific_addr, known_tls_implementations [i].expected_code, known_tls_implementations [i].expected_code_length) == 0) {
+                       if (memcmp (check_addr, known_tls_implementations [i].expected_code, known_tls_implementations [i].expected_code_length) == 0) {
                                if ((known_tls_implementations [i].check_kernel_helper && known_kernel_helper ()) ||
                                                !known_tls_implementations [i].check_kernel_helper)
                                        return known_tls_implementations [i];
@@ -79,7 +110,10 @@ mono_arm_get_tls_implementation (void)
                }
        }
 
-       g_warning ("No fast tls on device. Using fallbacks.\n");
+       g_warning ("No fast tls on device. Using fallbacks. Current implementation : ");
+       dump_code (check_addr);
+
        return (MonoTlsImplementation) { NULL, 0, FALSE, mono_fallback_get_tls_key, NULL, mono_fallback_set_tls_key, NULL };
+#endif
 }
 #endif