1 #include <errno.h> 2 #include <linux/unistd.h> 3 4 #include <sys/ptrace.h> 5 #include <sys/syscall.h> 6 #include <unistd.h> 7 8 #include "sysdep/tls.h" 9 10 #ifndef PTRACE_GET_THREAD_AREA 11 #define PTRACE_GET_THREAD_AREA 25 12 #endif 13 14 #ifndef PTRACE_SET_THREAD_AREA 15 #define PTRACE_SET_THREAD_AREA 26 16 #endif 17 18 /* Checks whether host supports TLS, and sets *tls_min according to the value 19 * valid on the host. 20 * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ 21 void check_host_supports_tls(int *supports_tls, int *tls_min) 22 { 23 /* Values for x86 and x86_64.*/ 24 int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; 25 int i; 26 27 for (i = 0; i < ARRAY_SIZE(val); i++) { 28 user_desc_t info; 29 info.entry_number = val[i]; 30 31 if (syscall(__NR_get_thread_area, &info) == 0) { 32 *tls_min = val[i]; 33 *supports_tls = 1; 34 return; 35 } else { 36 if (errno == EINVAL) 37 continue; 38 else if (errno == ENOSYS) 39 *supports_tls = 0; 40 return; 41 } 42 } 43 44 *supports_tls = 0; 45 } 46 47 int os_set_thread_area(user_desc_t *info, int pid) 48 { 49 int ret; 50 51 ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number, 52 (unsigned long) info); 53 if (ret < 0) 54 ret = -errno; 55 return ret; 56 } 57 58 int os_get_thread_area(user_desc_t *info, int pid) 59 { 60 int ret; 61 62 ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number, 63 (unsigned long) info); 64 if (ret < 0) 65 ret = -errno; 66 return ret; 67 } 68