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