OLD | NEW |
1 #include <stdint.h> | 1 #include <stdint.h> |
2 #include <elf.h> | 2 #include <elf.h> |
3 #include "pthread_impl.h" | 3 #include "pthread_impl.h" |
4 #include "libc.h" | 4 #include "libc.h" |
5 | 5 |
6 #define HWCAP_TLS (1 << 15) | 6 #define HWCAP_TLS (1 << 15) |
7 | 7 |
8 extern const unsigned char __attribute__((__visibility__("hidden"))) | 8 extern const unsigned char __attribute__((__visibility__("hidden"))) |
9 » __a_barrier_dummy[], __a_barrier_oldkuser[], | 9 __a_barrier_dummy[], |
10 » __a_barrier_v6[], __a_barrier_v7[], | 10 __a_barrier_oldkuser[], __a_barrier_v6[], __a_barrier_v7[], __a_cas_dummy[], |
11 » __a_cas_dummy[], __a_cas_v6[], __a_cas_v7[], | 11 __a_cas_v6[], __a_cas_v7[], __a_gettp_dummy[]; |
12 » __a_gettp_dummy[]; | |
13 | 12 |
14 #define __a_barrier_kuser 0xffff0fa0 | 13 #define __a_barrier_kuser 0xffff0fa0 |
15 #define __a_cas_kuser 0xffff0fc0 | 14 #define __a_cas_kuser 0xffff0fc0 |
16 #define __a_gettp_kuser 0xffff0fe0 | 15 #define __a_gettp_kuser 0xffff0fe0 |
17 | 16 |
18 extern uintptr_t __attribute__((__visibility__("hidden"))) | 17 extern uintptr_t __attribute__((__visibility__("hidden"))) __a_barrier_ptr, |
19 » __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr; | 18 __a_cas_ptr, __a_gettp_ptr; |
20 | 19 |
21 #define SET(op,ver) (__a_##op##_ptr = \ | 20 #define SET(op, ver) \ |
22 » (uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy) | 21 (__a_##op##_ptr = (uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy) |
23 | 22 |
24 int __set_thread_area(void *p) | 23 int __set_thread_area(void* p) { |
25 { | |
26 #if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7 | 24 #if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7 |
27 » if (__hwcap & HWCAP_TLS) { | 25 if (__hwcap & HWCAP_TLS) { |
28 » » size_t *aux; | 26 size_t* aux; |
29 » » SET(cas, v7); | 27 SET(cas, v7); |
30 » » SET(barrier, v7); | 28 SET(barrier, v7); |
31 » » for (aux=libc.auxv; *aux; aux+=2) { | 29 for (aux = libc.auxv; *aux; aux += 2) { |
32 » » » if (*aux != AT_PLATFORM) continue; | 30 if (*aux != AT_PLATFORM) |
33 » » » const char *s = (void *)aux[1]; | 31 continue; |
34 » » » if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break; | 32 const char* s = (void*)aux[1]; |
35 » » » SET(cas, v6); | 33 if (s[0] != 'v' || s[1] != '6' || s[2] - '0' < 10u) |
36 » » » SET(barrier, v6); | 34 break; |
37 » » » break; | 35 SET(cas, v6); |
38 » » } | 36 SET(barrier, v6); |
39 » } else { | 37 break; |
40 » » int ver = *(int *)0xffff0ffc; | 38 } |
41 » » SET(gettp, kuser); | 39 } else { |
42 » » SET(cas, kuser); | 40 int ver = *(int*)0xffff0ffc; |
43 » » SET(barrier, kuser); | 41 SET(gettp, kuser); |
44 » » if (ver < 2) a_crash(); | 42 SET(cas, kuser); |
45 » » if (ver < 3) SET(barrier, oldkuser); | 43 SET(barrier, kuser); |
46 » } | 44 if (ver < 2) |
| 45 a_crash(); |
| 46 if (ver < 3) |
| 47 SET(barrier, oldkuser); |
| 48 } |
47 #endif | 49 #endif |
48 » return __syscall(0xf0005, p); | 50 return __syscall(0xf0005, p); |
49 } | 51 } |
OLD | NEW |