github.com/afumu/libc@v0.0.6/musl/src/thread/arm/__set_thread_area.c (about)

     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 hidden const unsigned char
     9  	__a_barrier_oldkuser[], __a_barrier_v6[], __a_barrier_v7[],
    10  	__a_cas_v6[], __a_cas_v7[],
    11  	__a_gettp_cp15[];
    12  
    13  #define __a_barrier_kuser 0xffff0fa0
    14  #define __a_barrier_oldkuser (uintptr_t)__a_barrier_oldkuser
    15  #define __a_barrier_v6 (uintptr_t)__a_barrier_v6
    16  #define __a_barrier_v7 (uintptr_t)__a_barrier_v7
    17  
    18  #define __a_cas_kuser 0xffff0fc0
    19  #define __a_cas_v6 (uintptr_t)__a_cas_v6
    20  #define __a_cas_v7 (uintptr_t)__a_cas_v7
    21  
    22  #define __a_gettp_kuser 0xffff0fe0
    23  #define __a_gettp_cp15 (uintptr_t)__a_gettp_cp15
    24  
    25  extern hidden uintptr_t __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
    26  
    27  int __set_thread_area(void *p)
    28  {
    29  #if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
    30  	if (__hwcap & HWCAP_TLS) {
    31  		size_t *aux;
    32  		__a_cas_ptr = __a_cas_v7;
    33  		__a_barrier_ptr = __a_barrier_v7;
    34  		for (aux=libc.auxv; *aux; aux+=2) {
    35  			if (*aux != AT_PLATFORM) continue;
    36  			const char *s = (void *)aux[1];
    37  			if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
    38  			__a_cas_ptr = __a_cas_v6;
    39  			__a_barrier_ptr = __a_barrier_v6;
    40  			break;
    41  		}
    42  	} else {
    43  		int ver = *(int *)0xffff0ffc;
    44  		__a_gettp_ptr = __a_gettp_kuser;
    45  		__a_cas_ptr = __a_cas_kuser;
    46  		__a_barrier_ptr = __a_barrier_kuser;
    47  		if (ver < 2) a_crash();
    48  		if (ver < 3) __a_barrier_ptr = __a_barrier_oldkuser;
    49  	}
    50  #endif
    51  	return __syscall(0xf0005, p);
    52  }