1 | /* SPDX-License-Identifier: LGPL-2.1-only OR MIT */ |
2 | /* |
3 | * rseq/compiler.h |
4 | * |
5 | * Work-around asm goto compiler bugs. |
6 | * |
7 | * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
8 | */ |
9 | |
10 | #ifndef RSEQ_COMPILER_H |
11 | #define RSEQ_COMPILER_H |
12 | |
13 | /* |
14 | * gcc prior to 4.8.2 miscompiles asm goto. |
15 | * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 |
16 | * |
17 | * gcc prior to 8.1.0 miscompiles asm goto at O1. |
18 | * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103908 |
19 | * |
20 | * clang prior to version 13.0.1 miscompiles asm goto at O2. |
21 | * https://github.com/llvm/llvm-project/issues/52735 |
22 | * |
23 | * Work around these issues by adding a volatile inline asm with |
24 | * memory clobber in the fallthrough after the asm goto and at each |
25 | * label target. Emit this for all compilers in case other similar |
26 | * issues are found in the future. |
27 | */ |
28 | #define rseq_after_asm_goto() asm volatile ("" : : : "memory") |
29 | |
30 | /* Combine two tokens. */ |
31 | #define RSEQ__COMBINE_TOKENS(_tokena, _tokenb) \ |
32 | _tokena##_tokenb |
33 | #define RSEQ_COMBINE_TOKENS(_tokena, _tokenb) \ |
34 | RSEQ__COMBINE_TOKENS(_tokena, _tokenb) |
35 | |
36 | #ifdef __cplusplus |
37 | #define rseq_unqual_scalar_typeof(x) \ |
38 | std::remove_cv<std::remove_reference<decltype(x)>::type>::type |
39 | #else |
40 | #define rseq_scalar_type_to_expr(type) \ |
41 | unsigned type: (unsigned type)0, \ |
42 | signed type: (signed type)0 |
43 | |
44 | /* |
45 | * Use C11 _Generic to express unqualified type from expression. This removes |
46 | * volatile qualifier from expression type. |
47 | */ |
48 | #define rseq_unqual_scalar_typeof(x) \ |
49 | __typeof__( \ |
50 | _Generic((x), \ |
51 | char: (char)0, \ |
52 | rseq_scalar_type_to_expr(char), \ |
53 | rseq_scalar_type_to_expr(short), \ |
54 | rseq_scalar_type_to_expr(int), \ |
55 | rseq_scalar_type_to_expr(long), \ |
56 | rseq_scalar_type_to_expr(long long), \ |
57 | default: (x) \ |
58 | ) \ |
59 | ) |
60 | #endif |
61 | |
62 | #endif /* RSEQ_COMPILER_H_ */ |
63 | |