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