Improve a safety check when writing data into StatBuffer
[mono.git] / mono / mini / mini-arm-tls.S
1 /*
2  * mini-arm-tls.S: tls getters and setters for arm platforms
3  *
4  * Copyright 2015 Xamarin, Inc.
5  */
6
7 #include <config.h>
8
9 #ifndef MONO_CROSS_COMPILE
10
11         /*
12          * The following thunks fetch the value corresponding to the key/offset
13          * passed in R0. These thunks don't do jumps to external code so execution
14          * within can be tracked. The tls value is returned in R0.
15          */
16
17 .macro DECLARE_GLOBAL_SYMBOL name
18 #ifdef TARGET_MACH
19         .global _\name
20 _\name:
21 #else
22         .global \name
23 \name:
24 #endif
25 .endm
26
27         .text
28 /* no .arch on clang. it only supports armv6+ anyway */
29 #ifndef TARGET_MACH
30         .arch armv5
31 #endif
32         .arm
33         .align 4
34
35 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key
36 #if defined(__linux__)
37         mrc     p15, 0, r1, c13, c0, 3
38 #if defined(HAVE_KW_THREAD)
39         ldr     r0, [r1, r0]
40 #elif defined(TARGET_ANDROID)
41         ldr     r0, [r1, r0, lsl #2]
42 #endif
43         bx      lr
44 #elif defined(TARGET_IOS)
45         mrc     p15, 0, r1, c13, c0, 3
46         bic     r1, r1, #3
47         ldr     r0, [r1, r0, lsl #2]
48         bx      lr
49 #endif
50 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key_end
51
52         /*
53          * The following thunks fetch the value corresponding to the key/offset
54          * passed in R0. These thunks are used in the unlikely cases where we determine
55          * at runtime that the current implementation is not accounted for.
56          */
57
58         .align 4
59 DECLARE_GLOBAL_SYMBOL mono_fallback_get_tls_key
60 #if defined(__linux__) && defined(HAVE_KW_THREAD) && defined(__ARM_EABI__)
61         push    {lr}
62         mov     r1, r0
63         bl      __aeabi_read_tp
64         ldr     r0, [r0, r1]
65         pop     {pc}
66 #elif defined(TARGET_IOS)
67         push    {r7, lr}
68         mov     r7, sp
69         bl      _pthread_getspecific
70         pop     {r7, pc}
71 #elif defined(TARGET_ANDROID)
72         push    {lr}
73         bl      pthread_getspecific
74         pop     {pc}
75 #endif
76         /*
77          * The following thunks set the value corresponding to the key/offset
78          * passed in R0. These thunks don't do jumps to external code so execution
79          * within can be tracked. The tls value is passed in R1.
80          */
81
82         .align 4
83 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key
84 #if defined(__linux__)
85         mrc     p15, 0, r2, c13, c0, 3
86 #if defined(HAVE_KW_THREAD)
87         str     r1, [r2, r0]
88 #elif defined(TARGET_ANDROID)
89         str     r1, [r2, r0, lsl #2]
90 #endif
91         bx      lr
92 #elif defined(TARGET_IOS)
93         mrc     p15, 0, r2, c13, c0, 3
94         bic     r2, r2, #3
95         str     r1, [r2, r0, lsl #2]
96         bx      lr
97 #endif
98 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key_end
99
100         /*
101          * The following thunks set the value corresponding to the key/offset
102          * passed in R0. These thunks are used in the unlikely cases where we determine
103          * at runtime that the current implementation is not accounted for.
104          */
105
106         .align 4
107 DECLARE_GLOBAL_SYMBOL mono_fallback_set_tls_key
108 #if defined(__linux__) && defined(HAVE_KW_THREAD) && defined(__ARM_EABI__)
109         push    {lr}
110         mov     r2, r0
111         bl      __aeabi_read_tp
112         str     r1, [r0, r2]
113         pop     {pc}
114 #elif defined(TARGET_IOS)
115         push    {r7, lr}
116         mov     r7, sp
117         bl      _pthread_setspecific
118         pop     {r7, pc}
119 #elif defined(TARGET_ANDROID)
120         push    {lr}
121         bl      pthread_setspecific
122         pop     {pc}
123 #endif
124
125
126         /* Additional tls getters/setters */
127
128 #if defined(TARGET_ANDROID)
129         .align 4
130 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key2
131         bic     r0, r0, #0x80000000
132         mrc     15, 0, r1, cr13, cr0, #3
133         lsls    r0, r0, #3
134         ldr     r1, [r1, #4]
135         add     r0, r1
136         ldr     r0, [r0, #0x68]
137         bx      lr
138 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key2_end
139
140         /*
141          * In order to use this fast setter we need to make sure that the key was
142          * already set at least once using the pthread api, otherwise it will not
143          * interwork with the api.
144          */
145         .align 4
146 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key2
147         bic     r0, r0, #0x80000000
148         mrc     15, 0, r2, cr13, cr0, #3
149         lsls    r0, r0, #3
150         ldr     r2, [r2, #4]
151         add     r0, r2
152         str     r1, [r0, #0x68]
153         bx      lr
154 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key2_end
155 #endif
156
157 #endif
158