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 // we don't want to have the inline assembly included here 9 #ifndef _NO_INLINE_ASM 10 # define _NO_INLINE_ASM 1 11 #endif 12 13 #include <runtime_loader/runtime_loader.h> 14 15 #include "support/TLS.h" 16 #include "tls.h" 17 18 19 #if !defined(__GNUC__) || (__GNUC__ > 2) 20 21 struct tls_index { 22 unsigned long int module; 23 unsigned long int offset; 24 }; 25 26 27 void* ___tls_get_addr(struct tls_index* ti) __attribute__((__regparm__(1))); 28 29 #endif // GCC2 30 31 32 static int32 gNextSlot = TLS_FIRST_FREE_SLOT; 33 34 35 int32 36 tls_allocate(void) 37 { 38 int32 next = atomic_add(&gNextSlot, 1); 39 if (next >= TLS_MAX_KEYS) 40 return B_NO_MEMORY; 41 42 return next; 43 } 44 45 46 void * 47 tls_get(int32 index) 48 { 49 void *ret; 50 __asm__ __volatile__ ( 51 "movl %%fs:(, %1, 4), %0" 52 : "=r" (ret) : "r" (index)); 53 return ret; 54 } 55 56 57 void ** 58 tls_address(int32 index) 59 { 60 void **ret; 61 __asm__ __volatile__ ( 62 "movl %%fs:0, %0\n\t" 63 "leal (%0, %1, 4), %0\n\t" 64 : "=&r" (ret) : "r" (index)); 65 return ret; 66 } 67 68 69 void 70 tls_set(int32 index, void *value) 71 { 72 __asm__ __volatile__ ( 73 "movl %1, %%fs:(, %0, 4)" 74 : : "r" (index), "r" (value)); 75 } 76 77 78 #if !defined(__GNUC__) || (__GNUC__ > 2) 79 80 81 void* __attribute__((__regparm__(1))) 82 ___tls_get_addr(struct tls_index* ti) 83 { 84 return __gRuntimeLoader->get_tls_address(ti->module, ti->offset); 85 } 86 87 88 #endif // GCC2 89 90