[utils] Add fallback TLS offset scanning to X86 and AMD64.
authorRodrigo Kumpera <kumpera@gmail.com>
Thu, 9 Jul 2015 13:33:52 +0000 (09:33 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Fri, 10 Jul 2015 14:07:33 +0000 (10:07 -0400)
mono/utils/mach-support-amd64.c
mono/utils/mach-support-x86.c

index 825f2a247804321bb05589102e09747231f9f730..47bced480236a5cdcaf66a7f0614104da64599e4 100644 (file)
 #define TLS_VECTOR_OFFSET_10_9 0xe0
 #define TLS_VECTOR_OFFSET_10_11 0x100
 
+/* This is 2 slots less than the known low */
+#define TLS_PROBE_LOW_WATERMARK 0x50
+/* This is 28 slots above the know high, which is more than the known high-low*/
+#define TLS_PROBE_HIGH_WATERMARK 0x200
+
+
 static int tls_vector_offset;
 
 void *
@@ -114,6 +120,7 @@ mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key)
 void
 mono_mach_init (pthread_key_t key)
 {
+       int i;
        void *old_value = pthread_getspecific (key);
        void *canary = (void*)0xDEADBEEFu;
 
@@ -135,6 +142,15 @@ mono_mach_init (pthread_key_t key)
        if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary)
                goto ok;
 
+       /*Fallback to scanning a large range of offsets*/
+       for (i = TLS_PROBE_LOW_WATERMARK; i <= TLS_PROBE_HIGH_WATERMARK; i += 4) {
+               tls_vector_offset = i;
+               if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary) {
+                       g_warning ("Found new TLS offset at %d", i);
+                       goto ok;
+               }
+       }
+
        g_error ("could not discover the mach TLS offset");
 ok:
        pthread_setspecific (key, old_value);
index a74e84f9e7d20ba6c3e405e6cf219aae42e08ab2..c65a7b8cadac99ec59f1b949d71588f09d071c88 100644 (file)
 #define TLS_VECTOR_OFFSET_10_9 0xb0
 #define TLS_VECTOR_OFFSET_10_11 0x100
 
+
+/* This is 2 slots less than the known low */
+#define TLS_PROBE_LOW_WATERMARK 0x40
+/* This is 28 slots above the know high, which is more than the known high-low*/
+#define TLS_PROBE_HIGH_WATERMARK 0x120
+
+
 static int tls_vector_offset;
 
 void *
@@ -112,6 +119,7 @@ mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key)
 void
 mono_mach_init (pthread_key_t key)
 {
+       int i;
        void *old_value = pthread_getspecific (key);
        void *canary = (void*)0xDEADBEEFu;
 
@@ -137,6 +145,15 @@ mono_mach_init (pthread_key_t key)
        if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary)
                goto ok;
 
+       /*Fallback to scanning a large range of offsets*/
+       for (i = TLS_PROBE_LOW_WATERMARK; i <= TLS_PROBE_HIGH_WATERMARK; i += 4) {
+               tls_vector_offset = i;
+               if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary) {
+                       g_warning ("Found new TLS offset at %d", i);
+                       goto ok;
+               }
+       }
+
        g_error ("could not discover the mach TLS offset");
 ok:
        pthread_setspecific (key, old_value);