0001
0002 #include <errno.h>
0003 #include <linux/unistd.h>
0004
0005 #include <sys/ptrace.h>
0006 #include <sys/syscall.h>
0007 #include <unistd.h>
0008
0009 #include <sysdep/tls.h>
0010
0011 #ifndef PTRACE_GET_THREAD_AREA
0012 #define PTRACE_GET_THREAD_AREA 25
0013 #endif
0014
0015 #ifndef PTRACE_SET_THREAD_AREA
0016 #define PTRACE_SET_THREAD_AREA 26
0017 #endif
0018
0019
0020
0021
0022 void check_host_supports_tls(int *supports_tls, int *tls_min)
0023 {
0024
0025 int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64};
0026 int i;
0027
0028 for (i = 0; i < ARRAY_SIZE(val); i++) {
0029 user_desc_t info;
0030 info.entry_number = val[i];
0031
0032 if (syscall(__NR_get_thread_area, &info) == 0) {
0033 *tls_min = val[i];
0034 *supports_tls = 1;
0035 return;
0036 } else {
0037 if (errno == EINVAL)
0038 continue;
0039 else if (errno == ENOSYS)
0040 *supports_tls = 0;
0041 return;
0042 }
0043 }
0044
0045 *supports_tls = 0;
0046 }
0047
0048 int os_set_thread_area(user_desc_t *info, int pid)
0049 {
0050 int ret;
0051
0052 ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number,
0053 (unsigned long) info);
0054 if (ret < 0)
0055 ret = -errno;
0056 return ret;
0057 }
0058
0059 int os_get_thread_area(user_desc_t *info, int pid)
0060 {
0061 int ret;
0062
0063 ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number,
0064 (unsigned long) info);
0065 if (ret < 0)
0066 ret = -errno;
0067 return ret;
0068 }