15c48b108SAl Viro #include <errno.h> 25c48b108SAl Viro #include <linux/unistd.h> 35c48b108SAl Viro 4*1bbd5f21SAl Viro #include <sys/ptrace.h> 55c48b108SAl Viro #include <sys/syscall.h> 65c48b108SAl Viro #include <unistd.h> 75c48b108SAl Viro 85c48b108SAl Viro #include "sysdep/tls.h" 95c48b108SAl Viro 10*1bbd5f21SAl Viro #ifndef PTRACE_GET_THREAD_AREA 11*1bbd5f21SAl Viro #define PTRACE_GET_THREAD_AREA 25 12*1bbd5f21SAl Viro #endif 13*1bbd5f21SAl Viro 14*1bbd5f21SAl Viro #ifndef PTRACE_SET_THREAD_AREA 15*1bbd5f21SAl Viro #define PTRACE_SET_THREAD_AREA 26 16*1bbd5f21SAl Viro #endif 17*1bbd5f21SAl Viro 185c48b108SAl Viro /* Checks whether host supports TLS, and sets *tls_min according to the value 195c48b108SAl Viro * valid on the host. 205c48b108SAl Viro * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ 21*1bbd5f21SAl Viro void check_host_supports_tls(int *supports_tls, int *tls_min) 22*1bbd5f21SAl Viro { 235c48b108SAl Viro /* Values for x86 and x86_64.*/ 245c48b108SAl Viro int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; 255c48b108SAl Viro int i; 265c48b108SAl Viro 275c48b108SAl Viro for (i = 0; i < ARRAY_SIZE(val); i++) { 285c48b108SAl Viro user_desc_t info; 295c48b108SAl Viro info.entry_number = val[i]; 305c48b108SAl Viro 315c48b108SAl Viro if (syscall(__NR_get_thread_area, &info) == 0) { 325c48b108SAl Viro *tls_min = val[i]; 335c48b108SAl Viro *supports_tls = 1; 345c48b108SAl Viro return; 355c48b108SAl Viro } else { 365c48b108SAl Viro if (errno == EINVAL) 375c48b108SAl Viro continue; 385c48b108SAl Viro else if (errno == ENOSYS) 395c48b108SAl Viro *supports_tls = 0; 405c48b108SAl Viro return; 415c48b108SAl Viro } 425c48b108SAl Viro } 435c48b108SAl Viro 445c48b108SAl Viro *supports_tls = 0; 455c48b108SAl Viro } 46*1bbd5f21SAl Viro 47*1bbd5f21SAl Viro int os_set_thread_area(user_desc_t *info, int pid) 48*1bbd5f21SAl Viro { 49*1bbd5f21SAl Viro int ret; 50*1bbd5f21SAl Viro 51*1bbd5f21SAl Viro ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number, 52*1bbd5f21SAl Viro (unsigned long) info); 53*1bbd5f21SAl Viro if (ret < 0) 54*1bbd5f21SAl Viro ret = -errno; 55*1bbd5f21SAl Viro return ret; 56*1bbd5f21SAl Viro } 57*1bbd5f21SAl Viro 58*1bbd5f21SAl Viro int os_get_thread_area(user_desc_t *info, int pid) 59*1bbd5f21SAl Viro { 60*1bbd5f21SAl Viro int ret; 61*1bbd5f21SAl Viro 62*1bbd5f21SAl Viro ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number, 63*1bbd5f21SAl Viro (unsigned long) info); 64*1bbd5f21SAl Viro if (ret < 0) 65*1bbd5f21SAl Viro ret = -errno; 66*1bbd5f21SAl Viro return ret; 67*1bbd5f21SAl Viro } 68