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