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. */ 21void 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 47int 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 58int 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