| 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 |