1 /* 2 * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org. 3 * Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include <runtime_loader/runtime_loader.h> 9 10 #include "support/TLS.h" 11 #include "tls.h" 12 13 14 #if !defined(__GNUC__) || (__GNUC__ > 2) 15 16 struct tls_index { 17 unsigned long int module; 18 unsigned long int offset; 19 }; 20 21 22 void* ___tls_get_addr(struct tls_index* ti) __attribute__((__regparm__(1))); 23 24 #endif // GCC2 25 26 27 static int32 gNextSlot = TLS_FIRST_FREE_SLOT; 28 29 30 int32 31 tls_allocate(void) 32 { 33 int32 next = atomic_add(&gNextSlot, 1); 34 if (next >= TLS_MAX_KEYS) 35 return B_NO_MEMORY; 36 37 return next; 38 } 39 40 41 void * 42 tls_get(int32 index) 43 { 44 void *ret; 45 __asm__ __volatile__ ( 46 "movl %%fs:(, %1, 4), %0" 47 : "=r" (ret) : "r" (index)); 48 return ret; 49 } 50 51 52 void ** 53 tls_address(int32 index) 54 { 55 void **ret; 56 __asm__ __volatile__ ( 57 "movl %%fs:0, %0\n\t" 58 "leal (%0, %1, 4), %0\n\t" 59 : "=&r" (ret) : "r" (index)); 60 return ret; 61 } 62 63 64 void 65 tls_set(int32 index, void *value) 66 { 67 __asm__ __volatile__ ( 68 "movl %1, %%fs:(, %0, 4)" 69 : : "r" (index), "r" (value)); 70 } 71 72 73 #if !defined(__GNUC__) || (__GNUC__ > 2) 74 75 76 void* __attribute__((__regparm__(1))) 77 ___tls_get_addr(struct tls_index* ti) 78 { 79 return __gRuntimeLoader->get_tls_address(ti->module, ti->offset); 80 } 81 82 83 #endif // GCC2 84 85