Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/um/os-Linux/tls.c
26493 views
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 <os.h>
10
#include <sysdep/tls.h>
11
12
#ifndef PTRACE_GET_THREAD_AREA
13
#define PTRACE_GET_THREAD_AREA 25
14
#endif
15
16
#ifndef PTRACE_SET_THREAD_AREA
17
#define PTRACE_SET_THREAD_AREA 26
18
#endif
19
20
/* Checks whether host supports TLS, and sets *tls_min according to the value
21
* valid on the host.
22
* i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
23
void check_host_supports_tls(int *supports_tls, int *tls_min)
24
{
25
/* Values for x86 and x86_64.*/
26
int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64};
27
int i;
28
29
for (i = 0; i < ARRAY_SIZE(val); i++) {
30
user_desc_t info;
31
info.entry_number = val[i];
32
33
if (syscall(__NR_get_thread_area, &info) == 0) {
34
*tls_min = val[i];
35
*supports_tls = 1;
36
return;
37
} else {
38
if (errno == EINVAL)
39
continue;
40
else if (errno == ENOSYS)
41
*supports_tls = 0;
42
return;
43
}
44
}
45
46
*supports_tls = 0;
47
}
48
49
int os_set_thread_area(user_desc_t *info, int pid)
50
{
51
int ret;
52
53
ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number,
54
(unsigned long) info);
55
if (ret < 0)
56
ret = -errno;
57
return ret;
58
}
59
60
int os_get_thread_area(user_desc_t *info, int pid)
61
{
62
int ret;
63
64
ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number,
65
(unsigned long) info);
66
if (ret < 0)
67
ret = -errno;
68
return ret;
69
}
70
71