1e49d1c41SMathieu Desnoyers /* SPDX-License-Identifier: LGPL-2.1-only OR MIT */
2e49d1c41SMathieu Desnoyers /*
3e49d1c41SMathieu Desnoyers  * rseq-x86-thread-pointer.h
4e49d1c41SMathieu Desnoyers  *
5e49d1c41SMathieu Desnoyers  * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6e49d1c41SMathieu Desnoyers  */
7e49d1c41SMathieu Desnoyers 
8e49d1c41SMathieu Desnoyers #ifndef _RSEQ_X86_THREAD_POINTER
9e49d1c41SMathieu Desnoyers #define _RSEQ_X86_THREAD_POINTER
10e49d1c41SMathieu Desnoyers 
11e49d1c41SMathieu Desnoyers #include <features.h>
12e49d1c41SMathieu Desnoyers 
13e49d1c41SMathieu Desnoyers #ifdef __cplusplus
14e49d1c41SMathieu Desnoyers extern "C" {
15e49d1c41SMathieu Desnoyers #endif
16e49d1c41SMathieu Desnoyers 
17e49d1c41SMathieu Desnoyers #if __GNUC_PREREQ (11, 1)
rseq_thread_pointer(void)18e49d1c41SMathieu Desnoyers static inline void *rseq_thread_pointer(void)
19e49d1c41SMathieu Desnoyers {
20e49d1c41SMathieu Desnoyers 	return __builtin_thread_pointer();
21e49d1c41SMathieu Desnoyers }
22e49d1c41SMathieu Desnoyers #else
23e49d1c41SMathieu Desnoyers static inline void *rseq_thread_pointer(void)
24e49d1c41SMathieu Desnoyers {
25e49d1c41SMathieu Desnoyers 	void *__result;
26e49d1c41SMathieu Desnoyers 
27e49d1c41SMathieu Desnoyers # ifdef __x86_64__
28e49d1c41SMathieu Desnoyers 	__asm__ ("mov %%fs:0, %0" : "=r" (__result));
29e49d1c41SMathieu Desnoyers # else
30e49d1c41SMathieu Desnoyers 	__asm__ ("mov %%gs:0, %0" : "=r" (__result));
31e49d1c41SMathieu Desnoyers # endif
32e49d1c41SMathieu Desnoyers 	return __result;
33e49d1c41SMathieu Desnoyers }
34e49d1c41SMathieu Desnoyers #endif /* !GCC 11 */
35e49d1c41SMathieu Desnoyers 
36e49d1c41SMathieu Desnoyers #ifdef __cplusplus
37e49d1c41SMathieu Desnoyers }
38e49d1c41SMathieu Desnoyers #endif
39e49d1c41SMathieu Desnoyers 
40e49d1c41SMathieu Desnoyers #endif
41