xref: /OK3568_Linux_fs/kernel/include/linux/compiler-gcc.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef __LINUX_COMPILER_TYPES_H
3*4882a593Smuzhiyun #error "Please don't include <linux/compiler-gcc.h> directly, include <linux/compiler.h> instead."
4*4882a593Smuzhiyun #endif
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun /*
7*4882a593Smuzhiyun  * Common definitions for all gcc versions go here.
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun #define GCC_VERSION (__GNUC__ * 10000		\
10*4882a593Smuzhiyun 		     + __GNUC_MINOR__ * 100	\
11*4882a593Smuzhiyun 		     + __GNUC_PATCHLEVEL__)
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 */
14*4882a593Smuzhiyun #if GCC_VERSION < 40900
15*4882a593Smuzhiyun # error Sorry, your version of GCC is too old - please use 4.9 or newer.
16*4882a593Smuzhiyun #elif defined(CONFIG_ARM64) && GCC_VERSION < 50100
17*4882a593Smuzhiyun /*
18*4882a593Smuzhiyun  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63293
19*4882a593Smuzhiyun  * https://lore.kernel.org/r/20210107111841.GN1551@shell.armlinux.org.uk
20*4882a593Smuzhiyun  */
21*4882a593Smuzhiyun # error Sorry, your version of GCC is too old - please use 5.1 or newer.
22*4882a593Smuzhiyun #endif
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun  * This macro obfuscates arithmetic on a variable address so that gcc
26*4882a593Smuzhiyun  * shouldn't recognize the original var, and make assumptions about it.
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * This is needed because the C standard makes it undefined to do
29*4882a593Smuzhiyun  * pointer arithmetic on "objects" outside their boundaries and the
30*4882a593Smuzhiyun  * gcc optimizers assume this is the case. In particular they
31*4882a593Smuzhiyun  * assume such arithmetic does not wrap.
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  * A miscompilation has been observed because of this on PPC.
34*4882a593Smuzhiyun  * To work around it we hide the relationship of the pointer and the object
35*4882a593Smuzhiyun  * using this macro.
36*4882a593Smuzhiyun  *
37*4882a593Smuzhiyun  * Versions of the ppc64 compiler before 4.1 had a bug where use of
38*4882a593Smuzhiyun  * RELOC_HIDE could trash r30. The bug can be worked around by changing
39*4882a593Smuzhiyun  * the inline assembly constraint from =g to =r, in this particular
40*4882a593Smuzhiyun  * case either is valid.
41*4882a593Smuzhiyun  */
42*4882a593Smuzhiyun #define RELOC_HIDE(ptr, off)						\
43*4882a593Smuzhiyun ({									\
44*4882a593Smuzhiyun 	unsigned long __ptr;						\
45*4882a593Smuzhiyun 	__asm__ ("" : "=r"(__ptr) : "0"(ptr));				\
46*4882a593Smuzhiyun 	(typeof(ptr)) (__ptr + (off));					\
47*4882a593Smuzhiyun })
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #ifdef CONFIG_RETPOLINE
50*4882a593Smuzhiyun #define __noretpoline __attribute__((__indirect_branch__("keep")))
51*4882a593Smuzhiyun #endif
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun #if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
58*4882a593Smuzhiyun #define __latent_entropy __attribute__((latent_entropy))
59*4882a593Smuzhiyun #endif
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /*
62*4882a593Smuzhiyun  * calling noreturn functions, __builtin_unreachable() and __builtin_trap()
63*4882a593Smuzhiyun  * confuse the stack allocation in gcc, leading to overly large stack
64*4882a593Smuzhiyun  * frames, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365
65*4882a593Smuzhiyun  *
66*4882a593Smuzhiyun  * Adding an empty inline assembly before it works around the problem
67*4882a593Smuzhiyun  */
68*4882a593Smuzhiyun #define barrier_before_unreachable() asm volatile("")
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /*
71*4882a593Smuzhiyun  * Mark a position in code as unreachable.  This can be used to
72*4882a593Smuzhiyun  * suppress control flow warnings after asm blocks that transfer
73*4882a593Smuzhiyun  * control elsewhere.
74*4882a593Smuzhiyun  */
75*4882a593Smuzhiyun #define unreachable() \
76*4882a593Smuzhiyun 	do {					\
77*4882a593Smuzhiyun 		annotate_unreachable();		\
78*4882a593Smuzhiyun 		barrier_before_unreachable();	\
79*4882a593Smuzhiyun 		__builtin_unreachable();	\
80*4882a593Smuzhiyun 	} while (0)
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun #if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__)
83*4882a593Smuzhiyun #define __randomize_layout __attribute__((randomize_layout))
84*4882a593Smuzhiyun #define __no_randomize_layout __attribute__((no_randomize_layout))
85*4882a593Smuzhiyun /* This anon struct can add padding, so only enable it under randstruct. */
86*4882a593Smuzhiyun #define randomized_struct_fields_start	struct {
87*4882a593Smuzhiyun #define randomized_struct_fields_end	} __randomize_layout;
88*4882a593Smuzhiyun #endif
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /*
91*4882a593Smuzhiyun  * GCC 'asm goto' miscompiles certain code sequences:
92*4882a593Smuzhiyun  *
93*4882a593Smuzhiyun  *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
94*4882a593Smuzhiyun  *
95*4882a593Smuzhiyun  * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
96*4882a593Smuzhiyun  *
97*4882a593Smuzhiyun  * (asm goto is automatically volatile - the naming reflects this.)
98*4882a593Smuzhiyun  */
99*4882a593Smuzhiyun #define asm_volatile_goto(x...)	do { asm goto(x); asm (""); } while (0)
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun /*
102*4882a593Smuzhiyun  * sparse (__CHECKER__) pretends to be gcc, but can't do constant
103*4882a593Smuzhiyun  * folding in __builtin_bswap*() (yet), so don't set these for it.
104*4882a593Smuzhiyun  */
105*4882a593Smuzhiyun #if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) && !defined(__CHECKER__)
106*4882a593Smuzhiyun #define __HAVE_BUILTIN_BSWAP32__
107*4882a593Smuzhiyun #define __HAVE_BUILTIN_BSWAP64__
108*4882a593Smuzhiyun #define __HAVE_BUILTIN_BSWAP16__
109*4882a593Smuzhiyun #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun #if GCC_VERSION >= 70000
112*4882a593Smuzhiyun #define KASAN_ABI_VERSION 5
113*4882a593Smuzhiyun #elif GCC_VERSION >= 50000
114*4882a593Smuzhiyun #define KASAN_ABI_VERSION 4
115*4882a593Smuzhiyun #elif GCC_VERSION >= 40902
116*4882a593Smuzhiyun #define KASAN_ABI_VERSION 3
117*4882a593Smuzhiyun #endif
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun #if __has_attribute(__no_sanitize_address__)
120*4882a593Smuzhiyun #define __no_sanitize_address __attribute__((no_sanitize_address))
121*4882a593Smuzhiyun #else
122*4882a593Smuzhiyun #define __no_sanitize_address
123*4882a593Smuzhiyun #endif
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun #if defined(__SANITIZE_THREAD__) && __has_attribute(__no_sanitize_thread__)
126*4882a593Smuzhiyun #define __no_sanitize_thread __attribute__((no_sanitize_thread))
127*4882a593Smuzhiyun #else
128*4882a593Smuzhiyun #define __no_sanitize_thread
129*4882a593Smuzhiyun #endif
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun #if __has_attribute(__no_sanitize_undefined__)
132*4882a593Smuzhiyun #define __no_sanitize_undefined __attribute__((no_sanitize_undefined))
133*4882a593Smuzhiyun #else
134*4882a593Smuzhiyun #define __no_sanitize_undefined
135*4882a593Smuzhiyun #endif
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun #if defined(CONFIG_KCOV) && __has_attribute(__no_sanitize_coverage__)
138*4882a593Smuzhiyun #define __no_sanitize_coverage __attribute__((no_sanitize_coverage))
139*4882a593Smuzhiyun #else
140*4882a593Smuzhiyun #define __no_sanitize_coverage
141*4882a593Smuzhiyun #endif
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #if GCC_VERSION >= 50100
144*4882a593Smuzhiyun #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
145*4882a593Smuzhiyun #endif
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun /*
148*4882a593Smuzhiyun  * Turn individual warnings and errors on and off locally, depending
149*4882a593Smuzhiyun  * on version.
150*4882a593Smuzhiyun  */
151*4882a593Smuzhiyun #define __diag_GCC(version, severity, s) \
152*4882a593Smuzhiyun 	__diag_GCC_ ## version(__diag_GCC_ ## severity s)
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /* Severity used in pragma directives */
155*4882a593Smuzhiyun #define __diag_GCC_ignore	ignored
156*4882a593Smuzhiyun #define __diag_GCC_warn		warning
157*4882a593Smuzhiyun #define __diag_GCC_error	error
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun #define __diag_str1(s)		#s
160*4882a593Smuzhiyun #define __diag_str(s)		__diag_str1(s)
161*4882a593Smuzhiyun #define __diag(s)		_Pragma(__diag_str(GCC diagnostic s))
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun #if GCC_VERSION >= 80000
164*4882a593Smuzhiyun #define __diag_GCC_8(s)		__diag(s)
165*4882a593Smuzhiyun #else
166*4882a593Smuzhiyun #define __diag_GCC_8(s)
167*4882a593Smuzhiyun #endif
168