Line data Source code
1 1 : /*
2 : * Copyright (c) 2010-2014 Wind River Systems, Inc.
3 : * Copyright (c) 2025 Siemens AG
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_
9 : #define ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_
10 :
11 : #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_
12 : #error Please do not include toolchain-specific headers directly, use <zephyr/toolchain.h> instead
13 : #endif
14 :
15 : /**
16 : * @file
17 : * @brief Common toolchain abstraction
18 : *
19 : * Macros to abstract compiler capabilities (common to all toolchains).
20 : */
21 :
22 : /* Abstract use of extern keyword for compatibility between C and C++ */
23 : #ifdef __cplusplus
24 : #define EXTERN_C extern "C"
25 : #else
26 0 : #define EXTERN_C extern
27 : #endif
28 :
29 : /* Use TASK_ENTRY_CPP to tag task entry points defined in C++ files. */
30 :
31 : #ifdef __cplusplus
32 : #define TASK_ENTRY_CPP extern "C"
33 : #endif
34 :
35 : #ifndef ZRESTRICT
36 : #ifndef __cplusplus
37 0 : #define ZRESTRICT restrict
38 : #else
39 : #define ZRESTRICT
40 : #endif
41 : #endif
42 :
43 : /*
44 : * Generate a reference to an external symbol.
45 : * The reference indicates to the linker that the symbol is required
46 : * by the module containing the reference and should be included
47 : * in the image if the module is in the image.
48 : *
49 : * The assembler directive ".set" is used to define a local symbol.
50 : * No memory is allocated, and the local symbol does not appear in
51 : * the symbol table.
52 : */
53 :
54 : #ifdef _ASMLANGUAGE
55 : #define REQUIRES(sym) .set sym ## _Requires, sym
56 : #else
57 0 : #define REQUIRES(sym) __asm__ (".set " # sym "_Requires, " # sym "\n\t");
58 : #endif
59 :
60 : #ifdef _ASMLANGUAGE
61 : #define SECTION .section
62 : #endif
63 :
64 : /*
65 : * General directive for assembly code, to align the following symbol, in bytes.
66 : *
67 : * Example:
68 : *
69 : * ALIGN(4)
70 : * test_symbol:
71 : *
72 : * 'test_symbol' will get aligned to 4 bytes.
73 : */
74 :
75 : #if defined(_ASMLANGUAGE) && !defined(_LINKER)
76 :
77 : #if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || \
78 : defined(CONFIG_RISCV) || defined(CONFIG_XTENSA) || defined(CONFIG_MIPS) || \
79 : defined(CONFIG_ARCH_POSIX) || defined(CONFIG_RX)
80 : #define ALIGN(x) .balign x
81 : #elif defined(CONFIG_ARC)
82 : /* .align assembler directive is supported by all ARC toolchains and it is
83 : * implemented in the same way across ARC toolchains.
84 : */
85 : #define ALIGN(x) .align x
86 : #elif defined(CONFIG_SPARC)
87 : #define ALIGN(x) .align x
88 : #else
89 : #error Architecture unsupported
90 : #endif
91 :
92 : #endif /* defined(_ASMLANGUAGE) && !defined(_LINKER) */
93 :
94 : /*
95 : * If the project is being built for speed (i.e. not for minimum size) then
96 : * align functions and branches in executable sections to improve performance.
97 : */
98 :
99 : #ifdef _ASMLANGUAGE
100 :
101 : #if defined(CONFIG_X86)
102 :
103 : #ifdef PERF_OPT
104 : #define PERFOPT_ALIGN .balign 16
105 : #else
106 : #define PERFOPT_ALIGN .balign 1
107 : #endif
108 :
109 : #elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
110 :
111 : #define PERFOPT_ALIGN .balign 4
112 :
113 : #elif defined(CONFIG_ARC)
114 :
115 : /* .align assembler directive is supposed by all ARC toolchains and it is
116 : * implemented in a same way across ARC toolchains.
117 : */
118 : #define PERFOPT_ALIGN .align 4
119 :
120 : #elif defined(CONFIG_RISCV) || defined(CONFIG_XTENSA) || \
121 : defined(CONFIG_MIPS) || defined(CONFIG_RX)
122 : #define PERFOPT_ALIGN .balign 4
123 :
124 : #elif defined(CONFIG_ARCH_POSIX)
125 :
126 : #elif defined(CONFIG_SPARC)
127 :
128 : #define PERFOPT_ALIGN .align 4
129 :
130 : #else
131 :
132 : #error Architecture unsupported
133 :
134 : #endif
135 :
136 : #define GC_SECTION(sym) SECTION .text.##sym, "ax"
137 :
138 : #endif /* _ASMLANGUAGE */
139 :
140 : /* force inlining a function */
141 :
142 : #if !defined(_ASMLANGUAGE)
143 : #ifdef CONFIG_COVERAGE
144 : /*
145 : * The always_inline attribute forces a function to be inlined,
146 : * even ignoring -fno-inline. So for code coverage, do not
147 : * force inlining of these functions to keep their bodies around
148 : * so their number of executions can be counted.
149 : *
150 : * Note that "inline" is kept here for kobject_hash.c and
151 : * priv_stacks_hash.c. These are built without compiler flags
152 : * used for coverage. ALWAYS_INLINE cannot be empty as compiler
153 : * would complain about unused functions. Attaching unused
154 : * attribute would result in their text sections balloon more than
155 : * 10 times in size, as those functions are kept in text section.
156 : * So just keep "inline" here.
157 : */
158 : #define ALWAYS_INLINE inline
159 : #else
160 0 : #define ALWAYS_INLINE inline __attribute__((always_inline))
161 : #endif
162 : #endif
163 :
164 : #define Z_STRINGIFY(x) #x
165 0 : #define STRINGIFY(s) Z_STRINGIFY(s)
166 :
167 : /* concatenate the values of the arguments into one */
168 : #define _DO_CONCAT(x, y) x ## y
169 : #define _CONCAT(x, y) _DO_CONCAT(x, y)
170 :
171 : /* Additionally used as a sentinel by gen_syscalls.py to identify what
172 : * functions are system calls
173 : *
174 : * Note POSIX unit tests don't still generate the system call stubs, so
175 : * until https://github.com/zephyrproject-rtos/zephyr/issues/5006 is
176 : * fixed via possibly #4174, we introduce this hack -- which will
177 : * disallow us to test system calls in POSIX unit testing (currently
178 : * not used).
179 : */
180 : #ifndef ZTEST_UNITTEST
181 : #define __syscall static inline
182 : #define __syscall_always_inline static inline __attribute__((always_inline))
183 : #else
184 : #define __syscall
185 : #define __syscall_always_inline
186 : #endif /* ZTEST_UNITTEST */
187 :
188 : /* Definitions for struct declaration tags. These are sentinel values used by
189 : * parse_syscalls.py to gather a list of names of struct declarations that
190 : * have these tags applied for them.
191 : */
192 :
193 : /* Indicates this is a driver subsystem */
194 : #define __subsystem
195 :
196 : /* Indicates this is a network socket object */
197 : #define __net_socket
198 :
199 : #ifndef BUILD_ASSERT
200 : /* Compile-time assertion that makes the build to fail.
201 : * Common implementation swallows the message.
202 : */
203 : #define BUILD_ASSERT(EXPR, MSG...) \
204 : enum _CONCAT(__build_assert_enum, __COUNTER__) { \
205 : _CONCAT(__build_assert, __COUNTER__) = 1 / !!(EXPR) \
206 : }
207 : #endif
208 :
209 : /*
210 : * This is meant to be used in conjunction with __in_section() and similar
211 : * where scattered structure instances are concatenated together by the linker
212 : * and walked by the code at run time just like a contiguous array of such
213 : * structures.
214 : *
215 : * Assemblers and linkers may insert alignment padding by default whose
216 : * size is larger than the natural alignment for those structures when
217 : * gathering various section segments together, messing up the array walk.
218 : * To prevent this, we need to provide an explicit alignment not to rely
219 : * on the default that might just work by luck.
220 : *
221 : * Alignment statements in linker scripts are not sufficient as
222 : * the assembler may add padding by itself to each segment when switching
223 : * between sections within the same file even if it merges many such segments
224 : * into a single section in the end.
225 : */
226 : #define Z_DECL_ALIGN(type) __aligned(__alignof(type)) type
227 :
228 : /* Check if a pointer is aligned for against a specific byte boundary */
229 0 : #define IS_PTR_ALIGNED_BYTES(ptr, bytes) ((((uintptr_t)ptr) % bytes) == 0)
230 :
231 : /* Check if a pointer is aligned enough for a particular data type. */
232 0 : #define IS_PTR_ALIGNED(ptr, type) IS_PTR_ALIGNED_BYTES(ptr, __alignof(type))
233 :
234 : /** @brief Tag a symbol (e.g. function) to be kept in the binary even though it is not used.
235 : *
236 : * It prevents symbol from being removed by the linker garbage collector. It
237 : * is achieved by adding a pointer to that symbol to the kept memory section.
238 : *
239 : * @param symbol Symbol to keep.
240 : */
241 1 : #define LINKER_KEEP(symbol) \
242 : static const void * const symbol##_ptr __used \
243 : __attribute__((__section__(".symbol_to_keep"))) = (void *)&symbol
244 :
245 : #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_ */
|