VirtualBox

source: vbox/trunk/include/iprt/cdefs.h@ 100339

Last change on this file since 100339 was 100106, checked in by vboxsync, 19 months ago

include/iprt/cdefs.h: Use brk #0xf000 for RT_BREAKPOINT() instead of brk #0x1 on ARM. lldb will detect this and set the PC to after the brk instruction allowing the thread to continue execution instead of looping endlessly on the brk instruction. Helpful for continuing after assertions happening while running under lldb

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 205.1 KB
Line 
1/** @file
2 * IPRT - Common C and C++ definitions.
3 */
4
5/*
6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef IPRT_INCLUDED_cdefs_h
37#define IPRT_INCLUDED_cdefs_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42
43/** @defgroup grp_rt_cdefs IPRT Common Definitions and Macros
44 * @{
45 */
46
47/** @def RT_C_DECLS_BEGIN
48 * Used to start a block of function declarations which are shared
49 * between C and C++ program.
50 */
51
52/** @def RT_C_DECLS_END
53 * Used to end a block of function declarations which are shared
54 * between C and C++ program.
55 */
56
57#if defined(__cplusplus)
58# define RT_C_DECLS_BEGIN extern "C" {
59# define RT_C_DECLS_END }
60#else
61# define RT_C_DECLS_BEGIN
62# define RT_C_DECLS_END
63#endif
64
65
66/*
67 * Shut up DOXYGEN warnings and guide it properly thru the code.
68 */
69#ifdef DOXYGEN_RUNNING
70# define __AMD64__
71# define __X86__
72# define RT_ARCH_AMD64
73# define RT_ARCH_X86
74# define RT_ARCH_SPARC
75# define RT_ARCH_SPARC64
76# define RT_ARCH_ARM32
77# define RT_ARCH_ARM64
78# define IN_RING0
79# define IN_RING3
80# define IN_RC
81# define IN_RT_RC
82# define IN_RT_R0
83# define IN_RT_R3
84# define IN_RT_STATIC
85# define RT_STRICT
86# define RT_NO_STRICT
87# define RT_LOCK_STRICT
88# define RT_LOCK_NO_STRICT
89# define RT_LOCK_STRICT_ORDER
90# define RT_LOCK_NO_STRICT_ORDER
91# define RT_BREAKPOINT
92# define RT_NO_DEPRECATED_MACROS
93# define RT_EXCEPTIONS_ENABLED
94# define RT_BIG_ENDIAN
95# define RT_LITTLE_ENDIAN
96# define RT_COMPILER_GROKS_64BIT_BITFIELDS
97# define RT_COMPILER_WITH_80BIT_LONG_DOUBLE
98# define RT_COMPILER_WITH_128BIT_LONG_DOUBLE
99# define RT_COMPILER_WITH_128BIT_INT_TYPES
100# define RT_NO_VISIBILITY_HIDDEN
101# define RT_GCC_SUPPORTS_VISIBILITY_HIDDEN
102# define RT_COMPILER_SUPPORTS_VA_ARGS
103# define RT_COMPILER_SUPPORTS_LAMBDA
104#endif /* DOXYGEN_RUNNING */
105
106/** @def RT_ARCH_X86
107 * Indicates that we're compiling for the X86 architecture.
108 */
109
110/** @def RT_ARCH_AMD64
111 * Indicates that we're compiling for the AMD64 architecture.
112 */
113
114/** @def RT_ARCH_SPARC
115 * Indicates that we're compiling for the SPARC V8 architecture (32-bit).
116 */
117
118/** @def RT_ARCH_SPARC64
119 * Indicates that we're compiling for the SPARC V9 architecture (64-bit).
120 */
121
122/** @def RT_ARCH_ARM32
123 * Indicates that we're compiling for the 32-bit ARM architecture, the value
124 * is the version (i.e. 6 for ARMv6).
125 */
126
127/** @def RT_ARCH_ARM64
128 * Indicates that we're compiling for the 64-bit ARM architecture.
129 */
130
131#if !defined(RT_ARCH_X86) \
132 && !defined(RT_ARCH_AMD64) \
133 && !defined(RT_ARCH_SPARC) \
134 && !defined(RT_ARCH_SPARC64) \
135 && !defined(RT_ARCH_ARM32) \
136 && !defined(RT_ARCH_ARM64)
137# if defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || defined(__AMD64__)
138# define RT_ARCH_AMD64
139# elif defined(__i386__) || defined(_M_IX86) || defined(__X86__)
140# define RT_ARCH_X86
141# elif defined(__sparcv9)
142# define RT_ARCH_SPARC64
143# elif defined(__sparc__)
144# define RT_ARCH_SPARC
145# elif defined(__arm64__) || defined(__aarch64__)
146# define RT_ARCH_ARM64 __ARM_ARCH
147# elif defined(__arm__)
148# define RT_ARCH_ARM32 __ARM_ARCH
149# elif defined(__arm32__)
150# define RT_ARCH_ARM32 __ARM_ARCH
151# else /* PORTME: append test for new archs. */
152# error "Check what predefined macros your compiler uses to indicate architecture."
153# endif
154/* PORTME: append new archs checks. */
155#elif defined(RT_ARCH_X86) && defined(RT_ARCH_AMD64)
156# error "Both RT_ARCH_X86 and RT_ARCH_AMD64 cannot be defined at the same time!"
157#elif defined(RT_ARCH_X86) && defined(RT_ARCH_SPARC)
158# error "Both RT_ARCH_X86 and RT_ARCH_SPARC cannot be defined at the same time!"
159#elif defined(RT_ARCH_X86) && defined(RT_ARCH_SPARC64)
160# error "Both RT_ARCH_X86 and RT_ARCH_SPARC64 cannot be defined at the same time!"
161#elif defined(RT_ARCH_AMD64) && defined(RT_ARCH_SPARC)
162# error "Both RT_ARCH_AMD64 and RT_ARCH_SPARC cannot be defined at the same time!"
163#elif defined(RT_ARCH_AMD64) && defined(RT_ARCH_SPARC64)
164# error "Both RT_ARCH_AMD64 and RT_ARCH_SPARC64 cannot be defined at the same time!"
165#elif defined(RT_ARCH_SPARC) && defined(RT_ARCH_SPARC64)
166# error "Both RT_ARCH_SPARC and RT_ARCH_SPARC64 cannot be defined at the same time!"
167#elif defined(RT_ARCH_ARM32) && defined(RT_ARCH_AMD64)
168# error "Both RT_ARCH_ARM32 and RT_ARCH_AMD64 cannot be defined at the same time!"
169#elif defined(RT_ARCH_ARM32) && defined(RT_ARCH_X86)
170# error "Both RT_ARCH_ARM32 and RT_ARCH_X86 cannot be defined at the same time!"
171#elif defined(RT_ARCH_ARM32) && defined(RT_ARCH_SPARC64)
172# error "Both RT_ARCH_ARM32 and RT_ARCH_SPARC64 cannot be defined at the same time!"
173#elif defined(RT_ARCH_ARM32) && defined(RT_ARCH_SPARC)
174# error "Both RT_ARCH_ARM32 and RT_ARCH_SPARC cannot be defined at the same time!"
175#elif defined(RT_ARCH_ARM64) && defined(RT_ARCH_AMD64)
176# error "Both RT_ARCH_ARM64 and RT_ARCH_AMD64 cannot be defined at the same time!"
177#elif defined(RT_ARCH_ARM64) && defined(RT_ARCH_X86)
178# error "Both RT_ARCH_ARM64 and RT_ARCH_X86 cannot be defined at the same time!"
179#elif defined(RT_ARCH_ARM64) && defined(RT_ARCH_SPARC64)
180# error "Both RT_ARCH_ARM64 and RT_ARCH_SPARC64 cannot be defined at the same time!"
181#elif defined(RT_ARCH_ARM64) && defined(RT_ARCH_SPARC)
182# error "Both RT_ARCH_ARM64 and RT_ARCH_SPARC cannot be defined at the same time!"
183#elif defined(RT_ARCH_ARM64) && defined(RT_ARCH_ARM32)
184# error "Both RT_ARCH_ARM64 and RT_ARCH_ARM32 cannot be defined at the same time!"
185#endif
186#ifdef RT_ARCH_ARM
187# error "RT_ARCH_ARM is now RT_ARCH_ARM32!"
188#endif
189
190/* Final check (PORTME). */
191#if (defined(RT_ARCH_X86) != 0) \
192 + (defined(RT_ARCH_AMD64) != 0) \
193 + (defined(RT_ARCH_SPARC) != 0) \
194 + (defined(RT_ARCH_SPARC64) != 0) \
195 + (defined(RT_ARCH_ARM32) != 0) \
196 + (defined(RT_ARCH_ARM64) != 0) \
197 != 1
198# error "Exactly one RT_ARCH_XXX macro shall be defined"
199#endif
200
201/** @def RT_CPLUSPLUS_PREREQ
202 * Require a minimum __cplusplus value, simplifying dealing with non-C++ code.
203 *
204 * @param a_Min The minimum version, e.g. 201100.
205 */
206#ifdef __cplusplus
207# define RT_CPLUSPLUS_PREREQ(a_Min) (__cplusplus >= (a_Min))
208#else
209# define RT_CPLUSPLUS_PREREQ(a_Min) (0)
210#endif
211
212/** @def RT_GNUC_PREREQ
213 * Shorter than fiddling with __GNUC__ and __GNUC_MINOR__.
214 *
215 * @param a_MinMajor Minimum major version
216 * @param a_MinMinor The minor version number part.
217 */
218#define RT_GNUC_PREREQ(a_MinMajor, a_MinMinor) RT_GNUC_PREREQ_EX(a_MinMajor, a_MinMinor, 0)
219/** @def RT_GNUC_PREREQ_EX
220 * Simplified way of checking __GNUC__ and __GNUC_MINOR__ regardless of actual
221 * compiler used, returns @a a_OtherRet for other compilers.
222 *
223 * @param a_MinMajor Minimum major version
224 * @param a_MinMinor The minor version number part.
225 * @param a_OtherRet What to return for non-GCC compilers.
226 */
227#if defined(__GNUC__) && defined(__GNUC_MINOR__)
228# define RT_GNUC_PREREQ_EX(a_MinMajor, a_MinMinor, a_OtherRet) \
229 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((a_MinMajor) << 16) + (a_MinMinor))
230#else
231# define RT_GNUC_PREREQ_EX(a_MinMajor, a_MinMinor, a_OtherRet) (a_OtherRet)
232#endif
233
234/** @def RT_MSC_PREREQ
235 * Convenient way of checking _MSC_VER regardless of actual compiler used
236 * (returns false if not MSC).
237 *
238 * @param a_MinVer Preferably a RT_MSC_VER_XXX value.
239 */
240#define RT_MSC_PREREQ(a_MinVer) RT_MSC_PREREQ_EX(a_MinVer, 0)
241/** @def RT_MSC_PREREQ_EX
242 * Convenient way of checking _MSC_VER regardless of actual compiler used,
243 * returns @a a_OtherRet for other compilers.
244 *
245 * @param a_MinVer Preferably a RT_MSC_VER_XXX value.
246 * @param a_OtherRet What to return for non-MSC compilers.
247 */
248#if defined(_MSC_VER)
249# define RT_MSC_PREREQ_EX(a_MinVer, a_OtherRet) ( (_MSC_VER) >= (a_MinVer) )
250#else
251# define RT_MSC_PREREQ_EX(a_MinVer, a_OtherRet) (a_OtherRet)
252#endif
253/** @name RT_MSC_VER_XXX - _MSC_VER values to use with RT_MSC_PREREQ.
254 * @remarks The VCxxx values are derived from the CRT DLLs shipping with the
255 * compilers.
256 * @{ */
257#define RT_MSC_VER_VC50 (1100) /**< Visual C++ 5.0. */
258#define RT_MSC_VER_VC60 (1200) /**< Visual C++ 6.0. */
259#define RT_MSC_VER_VC70 (1300) /**< Visual C++ 7.0. */
260#define RT_MSC_VER_VC70 (1300) /**< Visual C++ 7.0. */
261#define RT_MSC_VER_VS2003 (1310) /**< Visual Studio 2003, aka Visual C++ 7.1. */
262#define RT_MSC_VER_VC71 RT_MSC_VER_VS2003 /**< Visual C++ 7.1, aka Visual Studio 2003. */
263#define RT_MSC_VER_VS2005 (1400) /**< Visual Studio 2005. */
264#define RT_MSC_VER_VC80 RT_MSC_VER_VS2005 /**< Visual C++ 8.0, aka Visual Studio 2008. */
265#define RT_MSC_VER_VS2008 (1500) /**< Visual Studio 2008. */
266#define RT_MSC_VER_VC90 RT_MSC_VER_VS2008 /**< Visual C++ 9.0, aka Visual Studio 2008. */
267#define RT_MSC_VER_VS2010 (1600) /**< Visual Studio 2010. */
268#define RT_MSC_VER_VC100 RT_MSC_VER_VS2010 /**< Visual C++ 10.0, aka Visual Studio 2010. */
269#define RT_MSC_VER_VS2012 (1700) /**< Visual Studio 2012. */
270#define RT_MSC_VER_VC110 RT_MSC_VER_VS2012 /**< Visual C++ 11.0, aka Visual Studio 2012. */
271#define RT_MSC_VER_VS2013 (1800) /**< Visual Studio 2013. */
272#define RT_MSC_VER_VC120 RT_MSC_VER_VS2013 /**< Visual C++ 12.0, aka Visual Studio 2013. */
273#define RT_MSC_VER_VS2015 (1900) /**< Visual Studio 2015. */
274#define RT_MSC_VER_VC140 RT_MSC_VER_VS2015 /**< Visual C++ 14.0, aka Visual Studio 2015. */
275#define RT_MSC_VER_VS2017 (1910) /**< Visual Studio 2017. */
276#define RT_MSC_VER_VC141 RT_MSC_VER_VS2017 /**< Visual C++ 14.1, aka Visual Studio 2017. */
277#define RT_MSC_VER_VS2019 (1920) /**< Visual Studio 2019. */
278#define RT_MSC_VER_VC142 RT_MSC_VER_VS2019 /**< Visual C++ 14.2, aka Visual Studio 2019. */
279#define RT_MSC_VER_VS2019_U6 (1926) /**< Visual Studio 2019, update 6. */
280#define RT_MSC_VER_VC142_U6 RT_MSC_VER_VS2019_U6 /**< Visual C++ 14.2 update 6. */
281#define RT_MSC_VER_VS2019_U8 (1928) /**< Visual Studio 2019, update 8. */
282#define RT_MSC_VER_VC142_U8 RT_MSC_VER_VS2019_U8 /**< Visual C++ 14.2 update 8. */
283#define RT_MSC_VER_VS2019_U11 (1929) /**< Visual Studio 2019, update 11. */
284#define RT_MSC_VER_VC142_U11 RT_MSC_VER_VS2019_U11 /**< Visual C++ 14.2 update 11. */
285/** @} */
286
287/** @def RT_CLANG_PREREQ
288 * Shorter than fiddling with __clang_major__ and __clang_minor__.
289 *
290 * @param a_MinMajor Minimum major version
291 * @param a_MinMinor The minor version number part.
292 */
293#define RT_CLANG_PREREQ(a_MinMajor, a_MinMinor) RT_CLANG_PREREQ_EX(a_MinMajor, a_MinMinor, 0)
294/** @def RT_CLANG_PREREQ_EX
295 * Simplified way of checking __clang_major__ and __clang_minor__ regardless of
296 * actual compiler used, returns @a a_OtherRet for other compilers.
297 *
298 * @param a_MinMajor Minimum major version
299 * @param a_MinMinor The minor version number part.
300 * @param a_OtherRet What to return for non-GCC compilers.
301 */
302#if defined(__clang_major__) && defined(__clang_minor__)
303# define RT_CLANG_PREREQ_EX(a_MinMajor, a_MinMinor, a_OtherRet) \
304 ((__clang_major__ << 16) + __clang_minor__ >= ((a_MinMajor) << 16) + (a_MinMinor))
305#else
306# define RT_CLANG_PREREQ_EX(a_MinMajor, a_MinMinor, a_OtherRet) (a_OtherRet)
307#endif
308/** @def RT_CLANG_HAS_FEATURE
309 * Wrapper around clang's __has_feature().
310 *
311 * @param a_Feature The feature to check for.
312 */
313#if defined(__clang_major__) && defined(__clang_minor__) && defined(__has_feature)
314# define RT_CLANG_HAS_FEATURE(a_Feature) (__has_feature(a_Feature))
315#else
316# define RT_CLANG_HAS_FEATURE(a_Feature) (0)
317#endif
318
319
320#if !defined(__X86__) && !defined(__AMD64__) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
321# if defined(RT_ARCH_AMD64)
322/** Indicates that we're compiling for the AMD64 architecture.
323 * @deprecated
324 */
325# define __AMD64__
326# elif defined(RT_ARCH_X86)
327/** Indicates that we're compiling for the X86 architecture.
328 * @deprecated
329 */
330# define __X86__
331# else
332# error "Check what predefined macros your compiler uses to indicate architecture."
333# endif
334#elif defined(__X86__) && defined(__AMD64__)
335# error "Both __X86__ and __AMD64__ cannot be defined at the same time!"
336#elif defined(__X86__) && !defined(RT_ARCH_X86)
337# error "__X86__ without RT_ARCH_X86!"
338#elif defined(__AMD64__) && !defined(RT_ARCH_AMD64)
339# error "__AMD64__ without RT_ARCH_AMD64!"
340#endif
341
342/** @def RT_BIG_ENDIAN
343 * Defined if the architecture is big endian. */
344/** @def RT_LITTLE_ENDIAN
345 * Defined if the architecture is little endian. */
346#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) || defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
347# define RT_LITTLE_ENDIAN
348#elif defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
349# define RT_BIG_ENDIAN
350#else
351# error "PORTME: architecture endianess"
352#endif
353#if defined(RT_BIG_ENDIAN) && defined(RT_LITTLE_ENDIAN)
354# error "Both RT_BIG_ENDIAN and RT_LITTLE_ENDIAN are defined"
355#endif
356
357
358/** @def IN_RING0
359 * Used to indicate that we're compiling code which is running
360 * in Ring-0 Host Context.
361 */
362
363/** @def IN_RING3
364 * Used to indicate that we're compiling code which is running
365 * in Ring-3 Host Context.
366 */
367
368/** @def IN_RC
369 * Used to indicate that we're compiling code which is running
370 * in the Raw-mode Context (implies R0).
371 */
372#if !defined(IN_RING3) && !defined(IN_RING0) && !defined(IN_RC)
373# error "You must define which context the compiled code should run in; IN_RING3, IN_RING0 or IN_RC"
374#endif
375#if (defined(IN_RING3) && (defined(IN_RING0) || defined(IN_RC)) ) \
376 || (defined(IN_RING0) && (defined(IN_RING3) || defined(IN_RC)) ) \
377 || (defined(IN_RC) && (defined(IN_RING3) || defined(IN_RING0)) )
378# error "Only one of the IN_RING3, IN_RING0, IN_RC defines should be defined."
379#endif
380
381
382/** @def ARCH_BITS
383 * Defines the bit count of the current context.
384 */
385#if !defined(ARCH_BITS) || defined(DOXYGEN_RUNNING)
386# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC64) || defined(RT_ARCH_ARM64) || defined(DOXYGEN_RUNNING)
387# define ARCH_BITS 64
388# elif !defined(__I86__) || !defined(__WATCOMC__)
389# define ARCH_BITS 32
390# else
391# define ARCH_BITS 16
392# endif
393#endif
394
395/* ARCH_BITS validation (PORTME). */
396#if ARCH_BITS == 64
397 #if defined(RT_ARCH_X86) || defined(RT_ARCH_SPARC) || defined(RT_ARCH_ARM32)
398 # error "ARCH_BITS=64 but non-64-bit RT_ARCH_XXX defined."
399 #endif
400 #if !defined(RT_ARCH_AMD64) && !defined(RT_ARCH_SPARC64) && !defined(RT_ARCH_ARM64)
401 # error "ARCH_BITS=64 but no 64-bit RT_ARCH_XXX defined."
402 #endif
403
404#elif ARCH_BITS == 32
405 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC64) || defined(RT_ARCH_ARM64)
406 # error "ARCH_BITS=32 but non-32-bit RT_ARCH_XXX defined."
407 #endif
408 #if !defined(RT_ARCH_X86) && !defined(RT_ARCH_SPARC) && !defined(RT_ARCH_ARM32)
409 # error "ARCH_BITS=32 but no 32-bit RT_ARCH_XXX defined."
410 #endif
411
412#elif ARCH_BITS == 16
413 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64) || defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
414 # error "ARCH_BITS=16 but non-16-bit RT_ARCH_XX defined."
415 #endif
416 #if !defined(RT_ARCH_X86)
417 # error "ARCH_BITS=16 but RT_ARCH_X86 isn't defined."
418 #endif
419
420#else
421# error "Unsupported ARCH_BITS value!"
422#endif
423
424/** @def HC_ARCH_BITS
425 * Defines the host architecture bit count.
426 */
427#if !defined(HC_ARCH_BITS) || defined(DOXYGEN_RUNNING)
428# if !defined(IN_RC) || defined(DOXYGEN_RUNNING)
429# define HC_ARCH_BITS ARCH_BITS
430# else
431# define HC_ARCH_BITS 32
432# endif
433#endif
434
435/** @def GC_ARCH_BITS
436 * Defines the guest architecture bit count.
437 */
438#if !defined(GC_ARCH_BITS) || defined(DOXYGEN_RUNNING)
439# if defined(VBOX_WITH_64_BITS_GUESTS) || defined(DOXYGEN_RUNNING)
440# define GC_ARCH_BITS 64
441# else
442# define GC_ARCH_BITS 32
443# endif
444#endif
445
446/** @def R3_ARCH_BITS
447 * Defines the host ring-3 architecture bit count.
448 */
449#if !defined(R3_ARCH_BITS) || defined(DOXYGEN_RUNNING)
450# ifdef IN_RING3
451# define R3_ARCH_BITS ARCH_BITS
452# else
453# define R3_ARCH_BITS HC_ARCH_BITS
454# endif
455#endif
456
457/** @def R0_ARCH_BITS
458 * Defines the host ring-0 architecture bit count.
459 */
460#if !defined(R0_ARCH_BITS) || defined(DOXYGEN_RUNNING)
461# ifdef IN_RING0
462# define R0_ARCH_BITS ARCH_BITS
463# else
464# define R0_ARCH_BITS HC_ARCH_BITS
465# endif
466#endif
467
468
469
470/** @name RT_OPSYS_XXX - Operative System Identifiers.
471 * These are the value that the RT_OPSYS \#define can take. @{
472 */
473/** Unknown OS. */
474#define RT_OPSYS_UNKNOWN 0
475/** OS Agnostic. */
476#define RT_OPSYS_AGNOSTIC 1
477/** Darwin - aka Mac OS X. */
478#define RT_OPSYS_DARWIN 2
479/** DragonFly BSD. */
480#define RT_OPSYS_DRAGONFLY 3
481/** DOS. */
482#define RT_OPSYS_DOS 4
483/** FreeBSD. */
484#define RT_OPSYS_FREEBSD 5
485/** Haiku. */
486#define RT_OPSYS_HAIKU 6
487/** Linux. */
488#define RT_OPSYS_LINUX 7
489/** L4. */
490#define RT_OPSYS_L4 8
491/** Minix. */
492#define RT_OPSYS_MINIX 9
493/** NetBSD. */
494#define RT_OPSYS_NETBSD 11
495/** Netware. */
496#define RT_OPSYS_NETWARE 12
497/** NT (native). */
498#define RT_OPSYS_NT 13
499/** OpenBSD. */
500#define RT_OPSYS_OPENBSD 14
501/** OS/2. */
502#define RT_OPSYS_OS2 15
503/** Plan 9. */
504#define RT_OPSYS_PLAN9 16
505/** QNX. */
506#define RT_OPSYS_QNX 17
507/** Solaris. */
508#define RT_OPSYS_SOLARIS 18
509/** UEFI. */
510#define RT_OPSYS_UEFI 19
511/** Windows. */
512#define RT_OPSYS_WINDOWS 20
513/** The max RT_OPSYS_XXX value (exclusive). */
514#define RT_OPSYS_MAX 21
515/** @} */
516
517/** @def RT_OPSYS
518 * Indicates which OS we're targeting. It's a \#define with is
519 * assigned one of the RT_OPSYS_XXX defines above.
520 *
521 * So to test if we're on FreeBSD do the following:
522 * @code
523 * #if RT_OPSYS == RT_OPSYS_FREEBSD
524 * some_funky_freebsd_specific_stuff();
525 * #endif
526 * @endcode
527 */
528
529/*
530 * Set RT_OPSYS_XXX according to RT_OS_XXX.
531 *
532 * Search: #define RT_OPSYS_([A-Z0-9]+) .*
533 * Replace: # elif defined(RT_OS_\1)\n# define RT_OPSYS RT_OPSYS_\1
534 */
535#ifndef RT_OPSYS
536# if defined(RT_OS_UNKNOWN) || defined(DOXYGEN_RUNNING)
537# define RT_OPSYS RT_OPSYS_UNKNOWN
538# elif defined(RT_OS_AGNOSTIC)
539# define RT_OPSYS RT_OPSYS_AGNOSTIC
540# elif defined(RT_OS_DARWIN)
541# define RT_OPSYS RT_OPSYS_DARWIN
542# elif defined(RT_OS_DRAGONFLY)
543# define RT_OPSYS RT_OPSYS_DRAGONFLY
544# elif defined(RT_OS_DOS)
545# define RT_OPSYS RT_OPSYS_DOS
546# elif defined(RT_OS_FREEBSD)
547# define RT_OPSYS RT_OPSYS_FREEBSD
548# elif defined(RT_OS_HAIKU)
549# define RT_OPSYS RT_OPSYS_HAIKU
550# elif defined(RT_OS_LINUX)
551# define RT_OPSYS RT_OPSYS_LINUX
552# elif defined(RT_OS_L4)
553# define RT_OPSYS RT_OPSYS_L4
554# elif defined(RT_OS_MINIX)
555# define RT_OPSYS RT_OPSYS_MINIX
556# elif defined(RT_OS_NETBSD)
557# define RT_OPSYS RT_OPSYS_NETBSD
558# elif defined(RT_OS_NETWARE)
559# define RT_OPSYS RT_OPSYS_NETWARE
560# elif defined(RT_OS_NT)
561# define RT_OPSYS RT_OPSYS_NT
562# elif defined(RT_OS_OPENBSD)
563# define RT_OPSYS RT_OPSYS_OPENBSD
564# elif defined(RT_OS_OS2)
565# define RT_OPSYS RT_OPSYS_OS2
566# elif defined(RT_OS_PLAN9)
567# define RT_OPSYS RT_OPSYS_PLAN9
568# elif defined(RT_OS_QNX)
569# define RT_OPSYS RT_OPSYS_QNX
570# elif defined(RT_OS_SOLARIS)
571# define RT_OPSYS RT_OPSYS_SOLARIS
572# elif defined(RT_OS_UEFI)
573# define RT_OPSYS RT_OPSYS_UEFI
574# elif defined(RT_OS_WINDOWS)
575# define RT_OPSYS RT_OPSYS_WINDOWS
576# endif
577#endif
578
579/*
580 * Guess RT_OPSYS based on compiler predefined macros.
581 */
582#ifndef RT_OPSYS
583# if defined(__APPLE__)
584# define RT_OPSYS RT_OPSYS_DARWIN
585# elif defined(__DragonFly__)
586# define RT_OPSYS RT_OPSYS_DRAGONFLY
587# elif defined(__FreeBSD__) /*??*/
588# define RT_OPSYS RT_OPSYS_FREEBSD
589# elif defined(__gnu_linux__)
590# define RT_OPSYS RT_OPSYS_LINUX
591# elif defined(__NetBSD__) /*??*/
592# define RT_OPSYS RT_OPSYS_NETBSD
593# elif defined(__OpenBSD__) /*??*/
594# define RT_OPSYS RT_OPSYS_OPENBSD
595# elif defined(__OS2__)
596# define RT_OPSYS RT_OPSYS_OS2
597# elif defined(__sun__) || defined(__SunOS__) || defined(__sun) || defined(__SunOS)
598# define RT_OPSYS RT_OPSYS_SOLARIS
599# elif defined(_WIN32) || defined(_WIN64)
600# define RT_OPSYS RT_OPSYS_WINDOWS
601# elif defined(MSDOS) || defined(_MSDOS) || defined(DOS16RM) /* OW+MSC || MSC || DMC */
602# define RT_OPSYS RT_OPSYS_DOS
603# else
604# error "Port Me"
605# endif
606#endif
607
608#if RT_OPSYS < RT_OPSYS_UNKNOWN || RT_OPSYS >= RT_OPSYS_MAX
609# error "Invalid RT_OPSYS value."
610#endif
611
612/*
613 * Do some consistency checks.
614 *
615 * Search: #define RT_OPSYS_([A-Z0-9]+) .*
616 * Replace: #if defined(RT_OS_\1) && RT_OPSYS != RT_OPSYS_\1\n# error RT_OPSYS vs RT_OS_\1\n#endif
617 */
618#if defined(RT_OS_UNKNOWN) && RT_OPSYS != RT_OPSYS_UNKNOWN
619# error RT_OPSYS vs RT_OS_UNKNOWN
620#endif
621#if defined(RT_OS_AGNOSTIC) && RT_OPSYS != RT_OPSYS_AGNOSTIC
622# error RT_OPSYS vs RT_OS_AGNOSTIC
623#endif
624#if defined(RT_OS_DARWIN) && RT_OPSYS != RT_OPSYS_DARWIN
625# error RT_OPSYS vs RT_OS_DARWIN
626#endif
627#if defined(RT_OS_DRAGONFLY) && RT_OPSYS != RT_OPSYS_DRAGONFLY
628# error RT_OPSYS vs RT_OS_DRAGONFLY
629#endif
630#if defined(RT_OS_DOS) && RT_OPSYS != RT_OPSYS_DOS
631# error RT_OPSYS vs RT_OS_DOS
632#endif
633#if defined(RT_OS_FREEBSD) && RT_OPSYS != RT_OPSYS_FREEBSD
634# error RT_OPSYS vs RT_OS_FREEBSD
635#endif
636#if defined(RT_OS_HAIKU) && RT_OPSYS != RT_OPSYS_HAIKU
637# error RT_OPSYS vs RT_OS_HAIKU
638#endif
639#if defined(RT_OS_LINUX) && RT_OPSYS != RT_OPSYS_LINUX
640# error RT_OPSYS vs RT_OS_LINUX
641#endif
642#if defined(RT_OS_L4) && RT_OPSYS != RT_OPSYS_L4
643# error RT_OPSYS vs RT_OS_L4
644#endif
645#if defined(RT_OS_MINIX) && RT_OPSYS != RT_OPSYS_MINIX
646# error RT_OPSYS vs RT_OS_MINIX
647#endif
648#if defined(RT_OS_NETBSD) && RT_OPSYS != RT_OPSYS_NETBSD
649# error RT_OPSYS vs RT_OS_NETBSD
650#endif
651#if defined(RT_OS_NETWARE) && RT_OPSYS != RT_OPSYS_NETWARE
652# error RT_OPSYS vs RT_OS_NETWARE
653#endif
654#if defined(RT_OS_NT) && RT_OPSYS != RT_OPSYS_NT
655# error RT_OPSYS vs RT_OS_NT
656#endif
657#if defined(RT_OS_OPENBSD) && RT_OPSYS != RT_OPSYS_OPENBSD
658# error RT_OPSYS vs RT_OS_OPENBSD
659#endif
660#if defined(RT_OS_OS2) && RT_OPSYS != RT_OPSYS_OS2
661# error RT_OPSYS vs RT_OS_OS2
662#endif
663#if defined(RT_OS_PLAN9) && RT_OPSYS != RT_OPSYS_PLAN9
664# error RT_OPSYS vs RT_OS_PLAN9
665#endif
666#if defined(RT_OS_QNX) && RT_OPSYS != RT_OPSYS_QNX
667# error RT_OPSYS vs RT_OS_QNX
668#endif
669#if defined(RT_OS_SOLARIS) && RT_OPSYS != RT_OPSYS_SOLARIS
670# error RT_OPSYS vs RT_OS_SOLARIS
671#endif
672#if defined(RT_OS_UEFI) && RT_OPSYS != RT_OPSYS_UEFI
673# error RT_OPSYS vs RT_OS_UEFI
674#endif
675#if defined(RT_OS_WINDOWS) && RT_OPSYS != RT_OPSYS_WINDOWS
676# error RT_OPSYS vs RT_OS_WINDOWS
677#endif
678
679/*
680 * Make sure the RT_OS_XXX macro is defined.
681 *
682 * Search: #define RT_OPSYS_([A-Z0-9]+) .*
683 * Replace: #elif RT_OPSYS == RT_OPSYS_\1\n# ifndef RT_OS_\1\n# define RT_OS_\1\n# endif
684 */
685#if RT_OPSYS == RT_OPSYS_UNKNOWN
686# ifndef RT_OS_UNKNOWN
687# define RT_OS_UNKNOWN
688# endif
689#elif RT_OPSYS == RT_OPSYS_AGNOSTIC
690# ifndef RT_OS_AGNOSTIC
691# define RT_OS_AGNOSTIC
692# endif
693#elif RT_OPSYS == RT_OPSYS_DARWIN
694# ifndef RT_OS_DARWIN
695# define RT_OS_DARWIN
696# endif
697#elif RT_OPSYS == RT_OPSYS_DRAGONFLY
698# ifndef RT_OS_DRAGONFLY
699# define RT_OS_DRAGONFLY
700# endif
701#elif RT_OPSYS == RT_OPSYS_DOS
702# ifndef RT_OS_DOS
703# define RT_OS_DOS
704# endif
705#elif RT_OPSYS == RT_OPSYS_FREEBSD
706# ifndef RT_OS_FREEBSD
707# define RT_OS_FREEBSD
708# endif
709#elif RT_OPSYS == RT_OPSYS_HAIKU
710# ifndef RT_OS_HAIKU
711# define RT_OS_HAIKU
712# endif
713#elif RT_OPSYS == RT_OPSYS_LINUX
714# ifndef RT_OS_LINUX
715# define RT_OS_LINUX
716# endif
717#elif RT_OPSYS == RT_OPSYS_L4
718# ifndef RT_OS_L4
719# define RT_OS_L4
720# endif
721#elif RT_OPSYS == RT_OPSYS_MINIX
722# ifndef RT_OS_MINIX
723# define RT_OS_MINIX
724# endif
725#elif RT_OPSYS == RT_OPSYS_NETBSD
726# ifndef RT_OS_NETBSD
727# define RT_OS_NETBSD
728# endif
729#elif RT_OPSYS == RT_OPSYS_NETWARE
730# ifndef RT_OS_NETWARE
731# define RT_OS_NETWARE
732# endif
733#elif RT_OPSYS == RT_OPSYS_NT
734# ifndef RT_OS_NT
735# define RT_OS_NT
736# endif
737#elif RT_OPSYS == RT_OPSYS_OPENBSD
738# ifndef RT_OS_OPENBSD
739# define RT_OS_OPENBSD
740# endif
741#elif RT_OPSYS == RT_OPSYS_OS2
742# ifndef RT_OS_OS2
743# define RT_OS_OS2
744# endif
745#elif RT_OPSYS == RT_OPSYS_PLAN9
746# ifndef RT_OS_PLAN9
747# define RT_OS_PLAN9
748# endif
749#elif RT_OPSYS == RT_OPSYS_QNX
750# ifndef RT_OS_QNX
751# define RT_OS_QNX
752# endif
753#elif RT_OPSYS == RT_OPSYS_SOLARIS
754# ifndef RT_OS_SOLARIS
755# define RT_OS_SOLARIS
756# endif
757#elif RT_OPSYS == RT_OPSYS_UEFI
758# ifndef RT_OS_UEFI
759# define RT_OS_UEFI
760# endif
761#elif RT_OPSYS == RT_OPSYS_WINDOWS
762# ifndef RT_OS_WINDOWS
763# define RT_OS_WINDOWS
764# endif
765#else
766# error "Bad RT_OPSYS value."
767#endif
768
769
770/**
771 * Checks whether the given OpSys uses DOS-style paths or not.
772 *
773 * By DOS-style paths we include drive lettering and UNC paths.
774 *
775 * @returns true / false
776 * @param a_OpSys The RT_OPSYS_XXX value to check, will be reference
777 * multiple times.
778 */
779#define RT_OPSYS_USES_DOS_PATHS(a_OpSys) \
780 ( (a_OpSys) == RT_OPSYS_WINDOWS \
781 || (a_OpSys) == RT_OPSYS_OS2 \
782 || (a_OpSys) == RT_OPSYS_DOS )
783
784
785
786/** @def CTXTYPE
787 * Declare a type differently in GC, R3 and R0.
788 *
789 * @param a_GCType The GC type.
790 * @param a_R3Type The R3 type.
791 * @param a_R0Type The R0 type.
792 * @remark For pointers used only in one context use RCPTRTYPE(), R3R0PTRTYPE(), R3PTRTYPE() or R0PTRTYPE().
793 */
794#if defined(IN_RC) && !defined(DOXYGEN_RUNNING)
795# define CTXTYPE(a_GCType, a_R3Type, a_R0Type) a_GCType
796#elif defined(IN_RING3) || defined(DOXYGEN_RUNNING)
797# define CTXTYPE(a_GCType, a_R3Type, a_R0Type) a_R3Type
798#else
799# define CTXTYPE(a_GCType, a_R3Type, a_R0Type) a_R0Type
800#endif
801
802/** @def CTX_EXPR
803 * Expression selector for avoiding \#ifdef's.
804 *
805 * @param a_R3Expr The R3 expression.
806 * @param a_R0Expr The R0 expression.
807 * @param a_RCExpr The RC expression.
808 */
809#if defined(IN_RC) && !defined(DOXYGEN_RUNNING)
810# define CTX_EXPR(a_R3Expr, a_R0Expr, a_RCExpr) a_RCExpr
811#elif defined(IN_RING0) && !defined(DOXYGEN_RUNNING)
812# define CTX_EXPR(a_R3Expr, a_R0Expr, a_RCExpr) a_R0Expr
813#else
814# define CTX_EXPR(a_R3Expr, a_R0Expr, a_RCExpr) a_R3Expr
815#endif
816
817/** @def RCPTRTYPE
818 * Declare a pointer which is used in the raw mode context but appears in structure(s) used by
819 * both HC and RC. The main purpose is to make sure structures have the same
820 * size when built for different architectures.
821 *
822 * @param a_RCType The RC type.
823 */
824#define RCPTRTYPE(a_RCType) CTXTYPE(a_RCType, RTRCPTR, RTRCPTR)
825
826/** @def RGPTRTYPE
827 * This will become RCPTRTYPE once we've converted all uses of RCPTRTYPE to this.
828 *
829 * @param a_RCType The RC type.
830 */
831#define RGPTRTYPE(a_RCType) CTXTYPE(a_RCType, RTGCPTR, RTGCPTR)
832
833/** @def R3R0PTRTYPE
834 * Declare a pointer which is used in HC, is explicitly valid in ring 3 and 0,
835 * but appears in structure(s) used by both HC and GC. The main purpose is to
836 * make sure structures have the same size when built for different architectures.
837 *
838 * @param a_R3R0Type The R3R0 type.
839 * @remarks This used to be called HCPTRTYPE.
840 */
841#define R3R0PTRTYPE(a_R3R0Type) CTXTYPE(RTHCPTR, a_R3R0Type, a_R3R0Type)
842
843/** @def R3PTRTYPE
844 * Declare a pointer which is used in R3 but appears in structure(s) used by
845 * both HC and GC. The main purpose is to make sure structures have the same
846 * size when built for different architectures.
847 *
848 * @param a_R3Type The R3 type.
849 */
850#define R3PTRTYPE(a_R3Type) CTXTYPE(RTHCUINTPTR, a_R3Type, RTHCUINTPTR)
851
852/** @def R0PTRTYPE
853 * Declare a pointer which is used in R0 but appears in structure(s) used by
854 * both HC and GC. The main purpose is to make sure structures have the same
855 * size when built for different architectures.
856 *
857 * @param a_R0Type The R0 type.
858 */
859#define R0PTRTYPE(a_R0Type) CTXTYPE(RTHCUINTPTR, RTHCUINTPTR, a_R0Type)
860
861/** @def CTXSUFF
862 * Adds the suffix of the current context to the passed in
863 * identifier name. The suffix is HC or GC.
864 *
865 * This is macro should only be used in shared code to avoid a forest of ifdefs.
866 * @param a_Var Identifier name.
867 * @deprecated Use CTX_SUFF. Do NOT use this for new code.
868 */
869/** @def OTHERCTXSUFF
870 * Adds the suffix of the other context to the passed in
871 * identifier name. The suffix is HC or GC.
872 *
873 * This is macro should only be used in shared code to avoid a forest of ifdefs.
874 * @param a_Var Identifier name.
875 * @deprecated Use CTX_SUFF. Do NOT use this for new code.
876 */
877#if defined(IN_RC) && !defined(DOXYGEN_RUNNING)
878# define CTXSUFF(a_Var) a_Var##GC
879# define OTHERCTXSUFF(a_Var) a_Var##HC
880#else
881# define CTXSUFF(a_Var) a_Var##HC
882# define OTHERCTXSUFF(a_Var) a_Var##GC
883#endif
884
885/** @def CTXALLSUFF
886 * Adds the suffix of the current context to the passed in
887 * identifier name. The suffix is R3, R0 or GC.
888 *
889 * This is macro should only be used in shared code to avoid a forest of ifdefs.
890 * @param a_Var Identifier name.
891 * @deprecated Use CTX_SUFF. Do NOT use this for new code.
892 */
893#if defined(IN_RC) && !defined(DOXYGEN_RUNNING)
894# define CTXALLSUFF(a_Var) a_Var##GC
895#elif defined(IN_RING0) && !defined(DOXYGEN_RUNNING)
896# define CTXALLSUFF(a_Var) a_Var##R0
897#else
898# define CTXALLSUFF(a_Var) a_Var##R3
899#endif
900
901/** @def CTX_SUFF
902 * Adds the suffix of the current context to the passed in
903 * identifier name. The suffix is R3, R0 or RC.
904 *
905 * This is macro should only be used in shared code to avoid a forest of ifdefs.
906 * @param a_Var Identifier name.
907 *
908 * @remark This will replace CTXALLSUFF and CTXSUFF before long.
909 */
910#if defined(IN_RC) && !defined(DOXYGEN_RUNNING)
911# define CTX_SUFF(a_Var) a_Var##RC
912#elif defined(IN_RING0) && !defined(DOXYGEN_RUNNING)
913# define CTX_SUFF(a_Var) a_Var##R0
914#else
915# define CTX_SUFF(a_Var) a_Var##R3
916#endif
917
918/** @def CTX_SUFF_Z
919 * Adds the suffix of the current context to the passed in
920 * identifier name, combining RC and R0 into RZ.
921 * The suffix thus is R3 or RZ.
922 *
923 * This is macro should only be used in shared code to avoid a forest of ifdefs.
924 * @param a_Var Identifier name.
925 *
926 * @remark This will replace CTXALLSUFF and CTXSUFF before long.
927 */
928#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
929# define CTX_SUFF_Z(a_Var) a_Var##R3
930#else
931# define CTX_SUFF_Z(a_Var) a_Var##RZ
932#endif
933
934
935/** @def CTXMID
936 * Adds the current context as a middle name of an identifier name
937 * The middle name is HC or GC.
938 *
939 * This is macro should only be used in shared code to avoid a forest of ifdefs.
940 * @param a_First First name.
941 * @param a_Last Surname.
942 */
943/** @def OTHERCTXMID
944 * Adds the other context as a middle name of an identifier name
945 * The middle name is HC or GC.
946 *
947 * This is macro should only be used in shared code to avoid a forest of ifdefs.
948 * @param a_First First name.
949 * @param a_Last Surname.
950 * @deprecated use CTX_MID or CTX_MID_Z
951 */
952#if defined(IN_RC) && !defined(DOXYGEN_RUNNING)
953# define CTXMID(a_First, a_Last) a_First##GC##a_Last
954# define OTHERCTXMID(a_First, a_Last) a_First##HC##a_Last
955#else
956# define CTXMID(a_First, a_Last) a_First##HC##a_Last
957# define OTHERCTXMID(a_First, a_Last) a_First##GC##a_Last
958#endif
959
960/** @def CTXALLMID
961 * Adds the current context as a middle name of an identifier name.
962 * The middle name is R3, R0 or GC.
963 *
964 * This is macro should only be used in shared code to avoid a forest of ifdefs.
965 * @param a_First First name.
966 * @param a_Last Surname.
967 * @deprecated use CTX_MID or CTX_MID_Z
968 */
969#if defined(IN_RC) && !defined(DOXYGEN_RUNNING)
970# define CTXALLMID(a_First, a_Last) a_First##GC##a_Last
971#elif defined(IN_RING0) && !defined(DOXYGEN_RUNNING)
972# define CTXALLMID(a_First, a_Last) a_First##R0##a_Last
973#else
974# define CTXALLMID(a_First, a_Last) a_First##R3##a_Last
975#endif
976
977/** @def CTX_MID
978 * Adds the current context as a middle name of an identifier name.
979 * The middle name is R3, R0 or RC.
980 *
981 * This is macro should only be used in shared code to avoid a forest of ifdefs.
982 * @param a_First First name.
983 * @param a_Last Surname.
984 */
985#if defined(IN_RC) && !defined(DOXYGEN_RUNNING)
986# define CTX_MID(a_First, a_Last) a_First##RC##a_Last
987#elif defined(IN_RING0) && !defined(DOXYGEN_RUNNING)
988# define CTX_MID(a_First, a_Last) a_First##R0##a_Last
989#else
990# define CTX_MID(a_First, a_Last) a_First##R3##a_Last
991#endif
992
993/** @def CTX_MID_Z
994 * Adds the current context as a middle name of an identifier name, combining RC
995 * and R0 into RZ.
996 * The middle name thus is either R3 or RZ.
997 *
998 * This is macro should only be used in shared code to avoid a forest of ifdefs.
999 * @param a_First First name.
1000 * @param a_Last Surname.
1001 */
1002#ifdef IN_RING3
1003# define CTX_MID_Z(a_First, a_Last) a_First##R3##a_Last
1004#else
1005# define CTX_MID_Z(a_First, a_Last) a_First##RZ##a_Last
1006#endif
1007
1008
1009/** @def R3STRING
1010 * A macro which in GC and R0 will return a dummy string while in R3 it will return
1011 * the parameter.
1012 *
1013 * This is typically used to wrap description strings in structures shared
1014 * between R3, R0 and/or GC. The intention is to avoid the \#ifdef IN_RING3 mess.
1015 *
1016 * @param a_pR3String The R3 string. Only referenced in R3.
1017 * @see R0STRING and GCSTRING
1018 */
1019#ifdef IN_RING3
1020# define R3STRING(a_pR3String) (a_pR3String)
1021#else
1022# define R3STRING(a_pR3String) ("<R3_STRING>")
1023#endif
1024
1025/** @def R0STRING
1026 * A macro which in GC and R3 will return a dummy string while in R0 it will return
1027 * the parameter.
1028 *
1029 * This is typically used to wrap description strings in structures shared
1030 * between R3, R0 and/or GC. The intention is to avoid the \#ifdef IN_RING0 mess.
1031 *
1032 * @param a_pR0String The R0 string. Only referenced in R0.
1033 * @see R3STRING and GCSTRING
1034 */
1035#ifdef IN_RING0
1036# define R0STRING(a_pR0String) (a_pR0String)
1037#else
1038# define R0STRING(a_pR0String) ("<R0_STRING>")
1039#endif
1040
1041/** @def RCSTRING
1042 * A macro which in R3 and R0 will return a dummy string while in RC it will return
1043 * the parameter.
1044 *
1045 * This is typically used to wrap description strings in structures shared
1046 * between R3, R0 and/or RC. The intention is to avoid the \#ifdef IN_RC mess.
1047 *
1048 * @param a_pRCString The RC string. Only referenced in RC.
1049 * @see R3STRING, R0STRING
1050 */
1051#ifdef IN_RC
1052# define RCSTRING(a_pRCString) (a_pRCString)
1053#else
1054# define RCSTRING(a_pRCString) ("<RC_STRING>")
1055#endif
1056
1057
1058/** @def RT_NOTHING
1059 * A macro that expands to nothing.
1060 * This is primarily intended as a dummy argument for macros to avoid the
1061 * undefined behavior passing empty arguments to an macro (ISO C90 and C++98,
1062 * gcc v4.4 warns about it).
1063 */
1064#define RT_NOTHING
1065
1066/** @def RT_GCC_EXTENSION
1067 * Macro for shutting up GCC warnings about using language extensions. */
1068#ifdef __GNUC__
1069# define RT_GCC_EXTENSION __extension__
1070#else
1071# define RT_GCC_EXTENSION
1072#endif
1073
1074/** @def RT_GCC_NO_WARN_DEPRECATED_BEGIN
1075 * Used to start a block of code where GCC and Clang should not warn about
1076 * deprecated declarations. */
1077/** @def RT_GCC_NO_WARN_DEPRECATED_END
1078 * Used to end a block of code where GCC and Clang should not warn about
1079 * deprecated declarations. */
1080#if RT_CLANG_PREREQ(4, 0)
1081# define RT_GCC_NO_WARN_DEPRECATED_BEGIN \
1082 _Pragma("clang diagnostic push") \
1083 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1084# define RT_GCC_NO_WARN_DEPRECATED_END \
1085 _Pragma("clang diagnostic pop")
1086
1087#elif RT_GNUC_PREREQ(4, 6)
1088# define RT_GCC_NO_WARN_DEPRECATED_BEGIN \
1089 _Pragma("GCC diagnostic push") \
1090 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1091# define RT_GCC_NO_WARN_DEPRECATED_END \
1092 _Pragma("GCC diagnostic pop")
1093#else
1094# define RT_GCC_NO_WARN_DEPRECATED_BEGIN
1095# define RT_GCC_NO_WARN_DEPRECATED_END
1096#endif
1097
1098/** @def RT_GCC_NO_WARN_CONVERSION_BEGIN
1099 * Used to start a block of code where GCC should not warn about implicit
1100 * conversions that may alter a value. */
1101#if RT_GNUC_PREREQ(4, 6)
1102# define RT_GCC_NO_WARN_CONVERSION_BEGIN \
1103 _Pragma("GCC diagnostic push") \
1104 _Pragma("GCC diagnostic ignored \"-Wconversion\"")
1105/** @def RT_GCC_NO_WARN_CONVERSION_END
1106 * Used to end a block of code where GCC should not warn about implicit
1107 * conversions that may alter a value. */
1108# define RT_GCC_NO_WARN_CONVERSION_END \
1109 _Pragma("GCC diagnostic pop")
1110#else
1111# define RT_GCC_NO_WARN_CONVERSION_BEGIN
1112# define RT_GCC_NO_WARN_CONVERSION_END
1113#endif
1114
1115/** @def RT_COMPILER_GROKS_64BIT_BITFIELDS
1116 * Macro that is defined if the compiler understands 64-bit bitfields. */
1117#if !defined(RT_OS_OS2) || (!defined(__IBMC__) && !defined(__IBMCPP__))
1118# if !defined(__WATCOMC__) /* watcom compiler doesn't grok it either. */
1119# define RT_COMPILER_GROKS_64BIT_BITFIELDS
1120# endif
1121#endif
1122
1123/** @def RT_COMPILER_LONG_DOUBLE_BITS
1124 * Number of relevant bits in the long double type: 64, 80 or 128 */
1125/** @def RT_COMPILER_WITH_64BIT_LONG_DOUBLE
1126 * Macro that is defined if the compiler implements long double as the
1127 * IEEE precision floating. */
1128/** @def RT_COMPILER_WITH_80BIT_LONG_DOUBLE
1129 * Macro that is defined if the compiler implements long double as the
1130 * IEEE extended precision floating. */
1131/** @def RT_COMPILER_WITH_128BIT_LONG_DOUBLE
1132* Macro that is defined if the compiler implements long double as the
1133* IEEE quadruple precision floating (128-bit).
1134* @note Currently not able to detect this, so must be explicitly defined. */
1135#if defined(__LDBL_MANT_DIG__) /* GCC & clang have this defined and should be more reliable. */
1136# if __LDBL_MANT_DIG__ == 53
1137# define RT_COMPILER_LONG_DOUBLE_BITS 64
1138# define RT_COMPILER_WITH_64BIT_LONG_DOUBLE
1139# undef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
1140# undef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
1141# elif __LDBL_MANT_DIG__ == 64
1142# define RT_COMPILER_LONG_DOUBLE_BITS 80
1143# undef RT_COMPILER_WITH_64BIT_LONG_DOUBLE
1144# define RT_COMPILER_WITH_80BIT_LONG_DOUBLE
1145# undef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
1146# elif __LDBL_MANT_DIG__ == 113
1147# define RT_COMPILER_LONG_DOUBLE_BITS 128
1148# undef RT_COMPILER_WITH_64BIT_LONG_DOUBLE
1149# undef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
1150# define RT_COMPILER_WITH_128BIT_LONG_DOUBLE
1151# else
1152# error "Port me!"
1153# endif
1154#elif defined(RT_OS_WINDOWS) || defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) /* the M1 arm64 at least */
1155# define RT_COMPILER_LONG_DOUBLE_BITS 64
1156# define RT_COMPILER_WITH_64BIT_LONG_DOUBLE
1157# undef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
1158# undef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
1159#elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
1160# define RT_COMPILER_LONG_DOUBLE_BITS 80
1161# undef RT_COMPILER_WITH_64BIT_LONG_DOUBLE
1162# define RT_COMPILER_WITH_80BIT_LONG_DOUBLE
1163# undef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
1164#elif defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
1165# define RT_COMPILER_LONG_DOUBLE_BITS 128
1166# undef RT_COMPILER_WITH_64BIT_LONG_DOUBLE
1167# undef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
1168# define RT_COMPILER_WITH_128BIT_LONG_DOUBLE
1169#else
1170# error "Port me!"
1171#endif
1172
1173
1174/*
1175 * The cl.exe frontend emulation of parfait is incorrect and
1176 * it still defines __SIZEOF_INT128__ despite msvc not supporting this
1177 * type and our code relying on the uint18_t type being a struct
1178 * in inline assembler code.
1179 */
1180#if defined(_MSC_VER) && defined(VBOX_WITH_PARFAIT)
1181# undef __SIZEOF_INT128__
1182#endif
1183
1184
1185/** @def RT_COMPILER_WITH_128BIT_INT_TYPES
1186 * Defined when uint128_t and int128_t are native integer types. If
1187 * undefined, they are structure with Hi & Lo members. */
1188#if defined(__SIZEOF_INT128__) || (defined(__GNUC__) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_ARM64)))
1189# define RT_COMPILER_WITH_128BIT_INT_TYPES
1190#endif
1191
1192/** @def RT_EXCEPTIONS_ENABLED
1193 * Defined when C++ exceptions are enabled.
1194 */
1195#if !defined(RT_EXCEPTIONS_ENABLED) \
1196 && defined(__cplusplus) \
1197 && ( (defined(_MSC_VER) && defined(_CPPUNWIND)) \
1198 || (defined(__GNUC__) && defined(__EXCEPTIONS)))
1199# define RT_EXCEPTIONS_ENABLED
1200#endif
1201
1202/** @def DECL_NOTHROW
1203 * How to declare a function which does not throw C++ exceptions.
1204 *
1205 * @param a_Type The return type.
1206 *
1207 * @note This macro can be combined with other macros, for example
1208 * @code
1209 * RTR3DECL(DECL_NOTHROW(void)) foo(void);
1210 * @endcode
1211 *
1212 * @note GCC is currently restricted to 4.2+ given the ominous comments on
1213 * RT_NOTHROW_PROTO.
1214 */
1215#ifdef __cplusplus
1216# if RT_MSC_PREREQ(RT_MSC_VER_VS2015) /*?*/
1217# define DECL_NOTHROW(a_Type) __declspec(nothrow) a_Type
1218# elif RT_CLANG_PREREQ(6,0) || RT_GNUC_PREREQ(4,2)
1219# define DECL_NOTHROW(a_Type) __attribute__((__nothrow__)) a_Type
1220# else
1221# define DECL_NOTHROW(a_Type) a_Type
1222# endif
1223#else
1224# define DECL_NOTHROW(a_Type) a_Type
1225#endif
1226
1227/** @def RT_NOTHROW_PROTO
1228 * Function does not throw any C++ exceptions, prototype edition.
1229 *
1230 * How to express that a function doesn't throw C++ exceptions and the compiler
1231 * can thus save itself the bother of trying to catch any of them and generate
1232 * unwind info. Put this between the closing parenthesis and the semicolon in
1233 * function prototypes (and implementation if C++).
1234 *
1235 * @note This translates to 'noexcept' when compiling in newer C++ mode.
1236 *
1237 * @remarks The use of the nothrow attribute with GCC is because old compilers
1238 * (4.1.1, 32-bit) leaking the nothrow into global space or something
1239 * when used with RTDECL or similar. Using this forces us to have two
1240 * macros, as the nothrow attribute is not for the function definition.
1241 */
1242/** @def RT_NOTHROW_DEF
1243 * Function does not throw any C++ exceptions, definition edition.
1244 *
1245 * The counter part to RT_NOTHROW_PROTO that is added to the function
1246 * definition.
1247 */
1248#ifdef RT_EXCEPTIONS_ENABLED
1249# if RT_MSC_PREREQ_EX(RT_MSC_VER_VS2015, 0) \
1250 || RT_CLANG_HAS_FEATURE(cxx_noexcept) \
1251 || (RT_GNUC_PREREQ(7, 0) && __cplusplus >= 201100)
1252# define RT_NOTHROW_PROTO noexcept
1253# define RT_NOTHROW_DEF noexcept
1254# elif defined(__GNUC__)
1255# if RT_GNUC_PREREQ(3, 3)
1256# define RT_NOTHROW_PROTO __attribute__((__nothrow__))
1257# else
1258# define RT_NOTHROW_PROTO
1259# endif
1260# define RT_NOTHROW_DEF /* Would need a DECL_NO_THROW like __declspec(nothrow), which we wont do at this point. */
1261# else
1262# define RT_NOTHROW_PROTO throw()
1263# define RT_NOTHROW_DEF throw()
1264# endif
1265#else
1266# define RT_NOTHROW_PROTO
1267# define RT_NOTHROW_DEF
1268#endif
1269/** @def RT_NOTHROW_PROTO
1270 * @deprecated Use RT_NOTHROW_PROTO. */
1271#define RT_NO_THROW_PROTO RT_NOTHROW_PROTO
1272/** @def RT_NOTHROW_DEF
1273 * @deprecated Use RT_NOTHROW_DEF. */
1274#define RT_NO_THROW_DEF RT_NOTHROW_DEF
1275
1276/** @def RT_THROW
1277 * How to express that a method or function throws a type of exceptions. Some
1278 * compilers does not want this kind of information and will warning about it.
1279 *
1280 * @param a_Type The type exception.
1281 *
1282 * @remarks If the actual throwing is done from the header, enclose it by
1283 * \#ifdef RT_EXCEPTIONS_ENABLED ... \#else ... \#endif so the header
1284 * compiles cleanly without exceptions enabled.
1285 *
1286 * Do NOT use this for the actual throwing of exceptions!
1287 */
1288#ifdef RT_EXCEPTIONS_ENABLED
1289# if (__cplusplus + 0) >= 201700
1290# define RT_THROW(a_Type) noexcept(false)
1291# elif RT_MSC_PREREQ_EX(RT_MSC_VER_VC71, 0)
1292# define RT_THROW(a_Type)
1293# elif RT_GNUC_PREREQ(7, 0)
1294# define RT_THROW(a_Type)
1295# else
1296# define RT_THROW(a_Type) throw(a_Type)
1297# endif
1298#else
1299# define RT_THROW(a_Type)
1300#endif
1301
1302
1303/** @def RT_OVERRIDE
1304 * Wrapper for the C++11 override keyword.
1305 *
1306 * @remarks Recognized by g++ starting 4.7, however causes pedantic warnings
1307 * when used without officially enabling the C++11 features.
1308 */
1309#ifdef __cplusplus
1310# if RT_MSC_PREREQ_EX(RT_MSC_VER_VS2012, 0)
1311# define RT_OVERRIDE override
1312# elif RT_GNUC_PREREQ(4, 7)
1313# if __cplusplus >= 201100
1314# define RT_OVERRIDE override
1315# else
1316# define RT_OVERRIDE
1317# endif
1318# else
1319# define RT_OVERRIDE
1320# endif
1321#else
1322# define RT_OVERRIDE
1323#endif
1324
1325/** @def RT_NOEXCEPT
1326 * Wrapper for the C++11 noexcept keyword (only true form).
1327 * @note use RT_NOTHROW instead.
1328 */
1329/** @def RT_NOEXCEPT_EX
1330 * Wrapper for the C++11 noexcept keyword with expression.
1331 * @param a_Expr The expression.
1332 */
1333#ifdef __cplusplus
1334# if (RT_MSC_PREREQ_EX(RT_MSC_VER_VS2015, 0) && defined(RT_EXCEPTIONS_ENABLED)) \
1335 || RT_CLANG_HAS_FEATURE(cxx_noexcept) \
1336 || (RT_GNUC_PREREQ(7, 0) && __cplusplus >= 201100)
1337# define RT_NOEXCEPT noexcept
1338# define RT_NOEXCEPT_EX(a_Expr) noexcept(a_Expr)
1339# else
1340# define RT_NOEXCEPT
1341# define RT_NOEXCEPT_EX(a_Expr)
1342# endif
1343#else
1344# define RT_NOEXCEPT
1345# define RT_NOEXCEPT_EX(a_Expr)
1346#endif
1347
1348/** @def RT_ALIGNAS_VAR
1349 * Wrapper for the C++ alignas keyword when used on variables.
1350 *
1351 * This must be put before the storage class and type.
1352 *
1353 * @param a_cbAlign The alignment. Must be power of two.
1354 * @note If C++11 is not enabled/detectable, alternatives will be used where
1355 * available. */
1356/** @def RT_ALIGNAS_TYPE
1357 * Wrapper for the C++ alignas keyword when used on types.
1358 *
1359 * When using struct, this must follow the struct keyword.
1360 *
1361 * @param a_cbAlign The alignment. Must be power of two.
1362 * @note If C++11 is not enabled/detectable, alternatives will be used where
1363 * available. */
1364/** @def RT_ALIGNAS_MEMB
1365 * Wrapper for the C++ alignas keyword when used on structure members.
1366 *
1367 * This must be put before the variable type.
1368 *
1369 * @param a_cbAlign The alignment. Must be power of two.
1370 * @note If C++11 is not enabled/detectable, alternatives will be used where
1371 * available. */
1372#ifdef __cplusplus
1373# if __cplusplus >= 201100 || defined(DOXYGEN_RUNNING)
1374# define RT_ALIGNAS_VAR(a_cbAlign) alignas(a_cbAlign)
1375# define RT_ALIGNAS_TYPE(a_cbAlign) alignas(a_cbAlign)
1376# define RT_ALIGNAS_MEMB(a_cbAlign) alignas(a_cbAlign)
1377# endif
1378#endif
1379#ifndef RT_ALIGNAS_VAR
1380# ifdef _MSC_VER
1381# define RT_ALIGNAS_VAR(a_cbAlign) __declspec(align(a_cbAlign))
1382# define RT_ALIGNAS_TYPE(a_cbAlign) __declspec(align(a_cbAlign))
1383# define RT_ALIGNAS_MEMB(a_cbAlign) __declspec(align(a_cbAlign))
1384# elif defined(__GNUC__)
1385# define RT_ALIGNAS_VAR(a_cbAlign) __attribute__((__aligned__(a_cbAlign)))
1386# define RT_ALIGNAS_TYPE(a_cbAlign) __attribute__((__aligned__(a_cbAlign)))
1387# define RT_ALIGNAS_MEMB(a_cbAlign) __attribute__((__aligned__(a_cbAlign)))
1388# else
1389# define RT_ALIGNAS_VAR(a_cbAlign)
1390# define RT_ALIGNAS_TYPE(a_cbAlign)
1391# define RT_ALIGNAS_MEMB(a_cbAlign)
1392# endif
1393#endif
1394
1395/** @def RT_CACHELINE_SIZE
1396 * The typical cache line size for the target architecture.
1397 * @see RT_ALIGNAS_VAR, RT_ALIGNAS_TYPE, RT_ALIGNAS_MEMB
1398 */
1399#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64) \
1400 || defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64) \
1401 || defined(RT_ARCH_SPARC32) || defined(RT_ARCH_SPARC64) \
1402 || defined(DOXYGEN_RUNNING)
1403# define RT_CACHELINE_SIZE 64
1404#else
1405# define RT_CACHELINE_SIZE 128 /* better overdo it */
1406#endif
1407
1408/** @def RT_FALL_THROUGH
1409 * Tell the compiler that we're falling through to the next case in a switch.
1410 * @sa RT_FALL_THRU */
1411#if RT_CLANG_PREREQ(4, 0) && RT_CPLUSPLUS_PREREQ(201100)
1412# define RT_FALL_THROUGH() [[clang::fallthrough]]
1413#elif RT_CLANG_PREREQ(12, 0) || RT_GNUC_PREREQ(7, 0)
1414# define RT_FALL_THROUGH() __attribute__((__fallthrough__))
1415#else
1416# define RT_FALL_THROUGH() (void)0
1417#endif
1418/** @def RT_FALL_THRU
1419 * Tell the compiler that we're falling thru to the next case in a switch.
1420 * @sa RT_FALL_THROUGH */
1421#define RT_FALL_THRU() RT_FALL_THROUGH()
1422
1423
1424/** @def RT_IPRT_FORMAT_ATTR
1425 * Identifies a function taking an IPRT format string.
1426 * @param a_iFmt The index (1-based) of the format string argument.
1427 * @param a_iArgs The index (1-based) of the first format argument, use 0 for
1428 * va_list.
1429 */
1430#if defined(__GNUC__) && defined(WITH_IPRT_FORMAT_ATTRIBUTE)
1431# define RT_IPRT_FORMAT_ATTR(a_iFmt, a_iArgs) __attribute__((__iprt_format__(a_iFmt, a_iArgs)))
1432#else
1433# define RT_IPRT_FORMAT_ATTR(a_iFmt, a_iArgs)
1434#endif
1435
1436/** @def RT_IPRT_FORMAT_ATTR_MAYBE_NULL
1437 * Identifies a function taking an IPRT format string, NULL is allowed.
1438 * @param a_iFmt The index (1-based) of the format string argument.
1439 * @param a_iArgs The index (1-based) of the first format argument, use 0 for
1440 * va_list.
1441 */
1442#if defined(__GNUC__) && defined(WITH_IPRT_FORMAT_ATTRIBUTE)
1443# define RT_IPRT_FORMAT_ATTR_MAYBE_NULL(a_iFmt, a_iArgs) __attribute__((__iprt_format_maybe_null__(a_iFmt, a_iArgs)))
1444#else
1445# define RT_IPRT_FORMAT_ATTR_MAYBE_NULL(a_iFmt, a_iArgs)
1446#endif
1447
1448
1449/** @def RT_GCC_SUPPORTS_VISIBILITY_HIDDEN
1450 * Indicates that the "hidden" visibility attribute can be used (GCC) */
1451#if defined(__GNUC__)
1452# if __GNUC__ >= 4 && !defined(RT_OS_OS2) && !defined(RT_OS_WINDOWS)
1453# define RT_GCC_SUPPORTS_VISIBILITY_HIDDEN
1454# endif
1455#endif
1456
1457/** @def RT_COMPILER_SUPPORTS_VA_ARGS
1458 * If the defined, the compiler supports the variadic macro feature (..., __VA_ARGS__). */
1459#if defined(_MSC_VER)
1460# if _MSC_VER >= 1600 /* Visual C++ v10.0 / 2010 */
1461# define RT_COMPILER_SUPPORTS_VA_ARGS
1462# endif
1463#elif defined(__GNUC__)
1464# if __GNUC__ >= 3 /* not entirely sure when this was added */
1465# define RT_COMPILER_SUPPORTS_VA_ARGS
1466# endif
1467#elif defined(__WATCOMC__)
1468# define RT_COMPILER_SUPPORTS_VA_ARGS
1469#endif
1470
1471/** @def RT_CB_LOG_CAST
1472 * Helper for logging function pointers to function may throw stuff.
1473 *
1474 * Not needed for function pointer types declared using our DECLCALLBACK
1475 * macros, only external types. */
1476#if defined(_MSC_VER) && defined(RT_EXCEPTIONS_ENABLED)
1477# define RT_CB_LOG_CAST(a_pfnCallback) ((uintptr_t)(a_pfnCallback) + 1 - 1)
1478#else
1479# define RT_CB_LOG_CAST(a_pfnCallback) (a_pfnCallback)
1480#endif
1481
1482
1483
1484/** @def RTCALL
1485 * The standard calling convention for the Runtime interfaces.
1486 *
1487 * @remarks The regparm(0) in the X86/GNUC variant deals with -mregparm=x use in
1488 * the linux kernel and potentially elsewhere (3rd party).
1489 */
1490#if defined(_MSC_VER) || defined(__WATCOMC__)
1491# define RTCALL __cdecl
1492#elif defined(RT_OS_OS2)
1493# define RTCALL __cdecl
1494#elif defined(__GNUC__) && defined(RT_ARCH_X86)
1495# define RTCALL __attribute__((__cdecl__,__regparm__(0)))
1496#else
1497# define RTCALL
1498#endif
1499
1500/** @def DECLEXPORT
1501 * How to declare an exported function.
1502 * @param a_RetType The return type of the function declaration.
1503 */
1504#if defined(_MSC_VER) || defined(RT_OS_OS2)
1505# define DECLEXPORT(a_RetType) __declspec(dllexport) a_RetType
1506#elif defined(RT_USE_VISIBILITY_DEFAULT)
1507# define DECLEXPORT(a_RetType) __attribute__((visibility("default"))) a_RetType
1508#else
1509# define DECLEXPORT(a_RetType) a_RetType
1510#endif
1511
1512/** @def DECL_EXPORT_NOTHROW
1513 * How to declare an exported function that does not throw C++ exceptions.
1514 * @param a_RetType The return type of the function declaration.
1515 */
1516#define DECL_EXPORT_NOTHROW(a_RetType) DECL_NOTHROW(DECLEXPORT(a_RetType))
1517
1518/** @def DECLIMPORT
1519 * How to declare an imported function.
1520 * @param a_RetType The return type of the function declaration.
1521 */
1522#if defined(_MSC_VER) || (defined(RT_OS_OS2) && !defined(__IBMC__) && !defined(__IBMCPP__))
1523# define DECLIMPORT(a_RetType) __declspec(dllimport) a_RetType
1524#else
1525# define DECLIMPORT(a_RetType) a_RetType
1526#endif
1527
1528/** @def DECL_IMPORT_NOTHROW
1529 * How to declare an imported function that does not throw C++ exceptions.
1530 * @param a_RetType The return type of the function declaration.
1531 */
1532#define DECL_IMPORT_NOTHROW(a_RetType) DECL_NOTHROW(DECLIMPORT(a_RetType))
1533
1534/** @def DECL_HIDDEN_ONLY
1535 * How to declare a non-exported function or variable.
1536 * @param a_Type The return type of the function or the data type of the variable.
1537 * @sa DECL_HIDDEN, DECL_HIDDEN_DATA, DECL_HIDDEN_CONST
1538 * @internal Considered more or less internal.
1539 */
1540#if !defined(RT_GCC_SUPPORTS_VISIBILITY_HIDDEN) || defined(RT_NO_VISIBILITY_HIDDEN)
1541# define DECL_HIDDEN_ONLY(a_Type) a_Type
1542#else
1543# define DECL_HIDDEN_ONLY(a_Type) __attribute__((visibility("hidden"))) a_Type
1544#endif
1545
1546/** @def DECLHIDDEN
1547 * How to declare a non-exported function or variable.
1548 * @param a_Type The return type of the function or the data type of the variable.
1549 * @sa DECL_HIDDEN_THROW, DECL_HIDDEN_DATA, DECL_HIDDEN_CONST
1550 * @todo split up into data and non-data.
1551 */
1552#define DECLHIDDEN(a_Type) DECL_NOTHROW(DECL_HIDDEN_ONLY(a_Type))
1553
1554/** @def DECL_HIDDEN_NOTHROW
1555 * How to declare a non-exported function that does not throw C++ exceptions.
1556 * @param a_RetType The return type of the function.
1557 * @note Same as DECLHIDDEN but provided to go along with DECL_IMPORT_NOTHROW
1558 * and DECL_EXPORT_NOTHROW.
1559 */
1560#define DECL_HIDDEN_NOTHROW(a_RetType) DECL_NOTHROW(DECL_HIDDEN_ONLY(a_RetType))
1561
1562/** @def DECL_HIDDEN_THROW
1563 * How to declare a non-exported function that may throw C++ exceptions.
1564 * @param a_RetType The return type of the function.
1565 */
1566#define DECL_HIDDEN_THROW(a_RetType) DECL_HIDDEN_ONLY(a_RetType)
1567
1568/** @def DECL_HIDDEN_DATA
1569 * How to declare a non-exported variable.
1570 * @param a_Type The data type of the variable.
1571 * @sa DECL_HIDDEN_CONST
1572 */
1573#if !defined(RT_GCC_SUPPORTS_VISIBILITY_HIDDEN) || defined(RT_NO_VISIBILITY_HIDDEN)
1574# define DECL_HIDDEN_DATA(a_Type) a_Type
1575#else
1576# define DECL_HIDDEN_DATA(a_Type) __attribute__((visibility("hidden"))) a_Type
1577#endif
1578
1579/** @def DECL_HIDDEN_CONST
1580 * Workaround for g++ warnings when applying the hidden attribute to a const
1581 * definition. Use DECL_HIDDEN_DATA for the declaration.
1582 * @param a_Type The data type of the variable.
1583 * @sa DECL_HIDDEN_DATA
1584 */
1585#if defined(__cplusplus) && defined(__GNUC__)
1586# define DECL_HIDDEN_CONST(a_Type) a_Type
1587#else
1588# define DECL_HIDDEN_CONST(a_Type) DECL_HIDDEN_DATA(a_Type)
1589#endif
1590
1591/** @def DECL_INVALID
1592 * How to declare a function not available for linking in the current context.
1593 * The purpose is to create compile or like time errors when used. This isn't
1594 * possible on all platforms.
1595 * @param a_RetType The return type of the function.
1596 */
1597#if defined(_MSC_VER)
1598# define DECL_INVALID(a_RetType) __declspec(dllimport) a_RetType __stdcall
1599#elif defined(__GNUC__) && defined(__cplusplus)
1600# define DECL_INVALID(a_RetType) extern "C++" a_RetType
1601#else
1602# define DECL_INVALID(a_RetType) a_RetType
1603#endif
1604
1605/** @def DECLASM
1606 * How to declare an internal assembly function.
1607 * @param a_RetType The return type of the function declaration.
1608 * @note DECL_NOTHROW is implied.
1609 */
1610#ifdef __cplusplus
1611# define DECLASM(a_RetType) extern "C" DECL_NOTHROW(a_RetType RTCALL)
1612#else
1613# define DECLASM(a_RetType) DECL_NOTHROW(a_RetType RTCALL)
1614#endif
1615
1616/** @def RT_ASM_DECL_PRAGMA_WATCOM
1617 * How to declare a assembly method prototype with watcom \#pragma aux definition. */
1618/** @def RT_ASM_DECL_PRAGMA_WATCOM_386
1619 * Same as RT_ASM_DECL_PRAGMA_WATCOM, but there is no 16-bit version when
1620 * 8086, 80186 or 80286 is selected as the target CPU. */
1621#if defined(__WATCOMC__) && ARCH_BITS == 16 && defined(RT_ARCH_X86)
1622# define RT_ASM_DECL_PRAGMA_WATCOM(a_RetType) a_RetType
1623# if defined(__SW_0) || defined(__SW_1) || defined(__SW_2)
1624# define RT_ASM_DECL_PRAGMA_WATCOM_386(a_RetType) DECLASM(a_RetType)
1625# else
1626# define RT_ASM_DECL_PRAGMA_WATCOM_386(a_RetType) a_RetType
1627# endif
1628#elif defined(__WATCOMC__) && ARCH_BITS == 32 && defined(RT_ARCH_X86)
1629# define RT_ASM_DECL_PRAGMA_WATCOM(a_RetType) a_RetType
1630# define RT_ASM_DECL_PRAGMA_WATCOM_386(a_RetType) a_RetType
1631#else
1632# define RT_ASM_DECL_PRAGMA_WATCOM(a_RetType) DECLASM(a_RetType)
1633# define RT_ASM_DECL_PRAGMA_WATCOM_386(a_RetType) DECLASM(a_RetType)
1634#endif
1635
1636/** @def DECL_NO_RETURN
1637 * How to declare a function which does not return.
1638 * @note This macro can be combined with other macros, for example
1639 * @code
1640 * RTR3DECL(DECL_NO_RETURN(void)) foo(void);
1641 * @endcode
1642 */
1643#ifdef _MSC_VER
1644# define DECL_NO_RETURN(a_RetType) __declspec(noreturn) a_RetType
1645#elif defined(__GNUC__)
1646# define DECL_NO_RETURN(a_RetType) __attribute__((noreturn)) a_RetType
1647#else
1648# define DECL_NO_RETURN(a_RetType) a_RetType
1649#endif
1650
1651/** @def DECL_RETURNS_TWICE
1652 * How to declare a function which may return more than once.
1653 * @note This macro can be combined with other macros, for example
1654 * @code
1655 * RTR3DECL(DECL_RETURNS_TWICE(void)) MySetJmp(void);
1656 * @endcode
1657 */
1658#if RT_GNUC_PREREQ(4, 1)
1659# define DECL_RETURNS_TWICE(a_RetType) __attribute__((returns_twice)) a_RetType
1660#else
1661# define DECL_RETURNS_TWICE(a_RetType) a_RetType
1662#endif
1663
1664/** @def DECL_CHECK_RETURN
1665 * Require a return value to be checked.
1666 * @note This macro can be combined with other macros, for example
1667 * @code
1668 * RTR3DECL(DECL_CHECK_RETURN(int)) MayReturnInfoStatus(void);
1669 * @endcode
1670 */
1671#if RT_GNUC_PREREQ(3, 4)
1672# define DECL_CHECK_RETURN(a_RetType) __attribute__((warn_unused_result)) a_RetType
1673#elif defined(_MSC_VER)
1674# define DECL_CHECK_RETURN(a_RetType) __declspec("SAL_checkReturn") a_RetType
1675#else
1676# define DECL_CHECK_RETURN(a_RetType) a_RetType
1677#endif
1678
1679/** @def DECL_CHECK_RETURN_NOT_R3
1680 * Variation of DECL_CHECK_RETURN that only applies the required to non-ring-3
1681 * code.
1682 */
1683#ifndef IN_RING3
1684# define DECL_CHECK_RETURN_NOT_R3(a_RetType) DECL_CHECK_RETURN(a_RetType)
1685#else
1686# define DECL_CHECK_RETURN_NOT_R3(a_RetType) a_RetType
1687#endif
1688
1689/** @def DECLWEAK
1690 * How to declare a variable which is not necessarily resolved at
1691 * runtime.
1692 * @note This macro can be combined with other macros, for example
1693 * @code
1694 * RTR3DECL(DECLWEAK(int)) foo;
1695 * @endcode
1696 */
1697#if defined(__GNUC__)
1698# define DECLWEAK(a_Type) a_Type __attribute__((weak))
1699#else
1700# define DECLWEAK(a_Type) a_Type
1701#endif
1702
1703/** @def DECLCALLBACK
1704 * How to declare an call back function.
1705 * @param a_RetType The return type of the function declaration.
1706 * @note DECL_NOTHROW is implied.
1707 * @note Use DECLCALLBACKTYPE for typedefs.
1708 */
1709#define DECLCALLBACK(a_RetType) DECL_NOTHROW(a_RetType RT_FAR_CODE RTCALL)
1710
1711/** @def DECL_HIDDEN_CALLBACK
1712 * How to declare an call back function with hidden visibility.
1713 * @param a_RetType The return type of the function declaration.
1714 * @note DECL_NOTHROW is implied.
1715 * @note Use DECLCALLBACKTYPE for typedefs.
1716 */
1717#define DECL_HIDDEN_CALLBACK(a_RetType) DECL_HIDDEN_ONLY(DECLCALLBACK(a_RetType))
1718
1719/** @def DECLCALLBACKTYPE_EX
1720 * How to declare an call back function type.
1721 * @param a_RetType The return type of the function declaration.
1722 * @param a_CallConv Calling convention.
1723 * @param a_Name The name of the typedef
1724 * @param a_Args The argument list enclosed in parentheses.
1725 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1726 */
1727#if RT_CLANG_PREREQ(6,0) && !defined(RT_RELAXED_CALLBACKS_TYPES)
1728# define DECLCALLBACKTYPE_EX(a_RetType, a_CallConv, a_Name, a_Args) __attribute__((__nothrow__)) a_RetType a_CallConv a_Name a_Args
1729#elif RT_MSC_PREREQ(RT_MSC_VER_VS2015) /*?*/ && defined(__cplusplus) && defined(_MSC_EXTENSIONS) && !defined(RT_RELAXED_CALLBACKS_TYPES)
1730# define DECLCALLBACKTYPE_EX(a_RetType, a_CallConv, a_Name, a_Args) a_RetType a_CallConv a_Name a_Args throw()
1731#else
1732# define DECLCALLBACKTYPE_EX(a_RetType, a_CallConv, a_Name, a_Args) a_RetType a_CallConv a_Name a_Args
1733#endif
1734/** @def DECLCALLBACKTYPE
1735 * How to declare an call back function type.
1736 * @param a_RetType The return type of the function declaration.
1737 * @param a_Name The name of the typedef
1738 * @param a_Args The argument list enclosed in parentheses.
1739 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1740 */
1741#define DECLCALLBACKTYPE(a_RetType, a_Name, a_Args) DECLCALLBACKTYPE_EX(a_RetType, RT_FAR_CODE RTCALL, a_Name, a_Args)
1742
1743/** @def DECLCALLBACKPTR_EX
1744 * How to declare an call back function pointer.
1745 * @param a_RetType The return type of the function declaration.
1746 * @param a_CallConv Calling convention.
1747 * @param a_Name The name of the variable member.
1748 * @param a_Args The argument list enclosed in parentheses.
1749 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1750 */
1751#if defined(__IBMC__) || defined(__IBMCPP__)
1752# define DECLCALLBACKPTR_EX(a_RetType, a_CallConv, a_Name, a_Args) a_RetType (* a_CallConv a_Name) a_Args
1753#elif RT_CLANG_PREREQ(6,0) && !defined(RT_RELAXED_CALLBACKS_TYPES)
1754# define DECLCALLBACKPTR_EX(a_RetType, a_CallConv, a_Name, a_Args) __attribute__((__nothrow__)) a_RetType (a_CallConv * a_Name) a_Args
1755#elif RT_MSC_PREREQ(RT_MSC_VER_VS2015) /*?*/ && defined(__cplusplus) && defined(_MSC_EXTENSIONS) && !defined(RT_RELAXED_CALLBACKS_TYPES)
1756# define DECLCALLBACKPTR_EX(a_RetType, a_CallConv, a_Name, a_Args) a_RetType (a_CallConv * a_Name) a_Args throw()
1757#else
1758# define DECLCALLBACKPTR_EX(a_RetType, a_CallConv, a_Name, a_Args) a_RetType (a_CallConv * a_Name) a_Args
1759#endif
1760/** @def DECLCALLBACKPTR
1761 * How to declare an call back function pointer.
1762 * @param a_RetType The return type of the function declaration.
1763 * @param a_Name The name of the variable member.
1764 * @param a_Args The argument list enclosed in parentheses.
1765 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1766 */
1767#define DECLCALLBACKPTR(a_RetType, a_Name, a_Args) DECLCALLBACKPTR_EX(a_RetType, RT_FAR_CODE RTCALL, a_Name, a_Args)
1768
1769/** @def DECLCALLBACKMEMBER_EX
1770 * How to declare an call back function pointer member.
1771 * @param a_RetType The return type of the function declaration.
1772 * @param a_CallConv Calling convention.
1773 * @param a_Name The name of the struct/union/class member.
1774 * @param a_Args The argument list enclosed in parentheses.
1775 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1776 */
1777#if defined(__IBMC__) || defined(__IBMCPP__)
1778# define DECLCALLBACKMEMBER_EX(a_RetType, a_CallConv, a_Name, a_Args) a_RetType (* a_CallConv a_Name) a_Args
1779#elif RT_CLANG_PREREQ(6,0) && !defined(RT_RELAXED_CALLBACKS_TYPES)
1780# define DECLCALLBACKMEMBER_EX(a_RetType, a_CallConv, a_Name, a_Args) __attribute__((__nothrow__)) a_RetType (a_CallConv *a_Name) a_Args
1781#elif RT_MSC_PREREQ(RT_MSC_VER_VS2015) /*?*/ && defined(__cplusplus) && defined(_MSC_EXTENSIONS) && !defined(RT_RELAXED_CALLBACKS_TYPES)
1782# define DECLCALLBACKMEMBER_EX(a_RetType, a_CallConv, a_Name, a_Args) a_RetType (a_CallConv *a_Name) a_Args throw()
1783#else
1784# define DECLCALLBACKMEMBER_EX(a_RetType, a_CallConv, a_Name, a_Args) a_RetType (a_CallConv *a_Name) a_Args
1785#endif
1786/** @def DECLCALLBACKMEMBER
1787 * How to declare an call back function pointer member.
1788 * @param a_RetType The return type of the function declaration.
1789 * @param a_Name The name of the struct/union/class member.
1790 * @param a_Args The argument list enclosed in parentheses.
1791 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1792 */
1793#define DECLCALLBACKMEMBER(a_RetType, a_Name, a_Args) DECLCALLBACKMEMBER_EX(a_RetType, RT_FAR_CODE RTCALL, a_Name, a_Args)
1794
1795/** @def DECLR3CALLBACKMEMBER
1796 * How to declare an call back function pointer member - R3 Ptr.
1797 * @param a_RetType The return type of the function declaration.
1798 * @param a_Name The name of the struct/union/class member.
1799 * @param a_Args The argument list enclosed in parentheses.
1800 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1801 */
1802#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
1803# define DECLR3CALLBACKMEMBER(a_RetType, a_Name, a_Args) DECLCALLBACKMEMBER(a_RetType, a_Name, a_Args)
1804#else
1805# define DECLR3CALLBACKMEMBER(a_RetType, a_Name, a_Args) RTR3PTR a_Name
1806#endif
1807
1808/** @def DECLRCCALLBACKMEMBER
1809 * How to declare an call back function pointer member - RC Ptr.
1810 * @param a_RetType The return type of the function declaration.
1811 * @param a_Name The name of the struct/union/class member.
1812 * @param a_Args The argument list enclosed in parentheses.
1813 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1814 */
1815#if defined(IN_RC) || defined(DOXYGEN_RUNNING)
1816# define DECLRCCALLBACKMEMBER(a_RetType, a_Name, a_Args) DECLCALLBACKMEMBER(a_RetType, a_Name, a_Args)
1817#else
1818# define DECLRCCALLBACKMEMBER(a_RetType, a_Name, a_Args) RTRCPTR a_Name
1819#endif
1820#if defined(IN_RC) || defined(DOXYGEN_RUNNING)
1821# define DECLRGCALLBACKMEMBER(a_RetType, a_Name, a_Args) DECLCALLBACKMEMBER(a_RetType, a_Name, a_Args)
1822#else
1823# define DECLRGCALLBACKMEMBER(a_RetType, a_Name, a_Args) RTRGPTR a_Name
1824#endif
1825
1826/** @def DECLR0CALLBACKMEMBER
1827 * How to declare an call back function pointer member - R0 Ptr.
1828 * @param a_RetType The return type of the function declaration.
1829 * @param a_Name The name of the struct/union/class member.
1830 * @param a_Args The argument list enclosed in parentheses.
1831 * @note DECL_NOTHROW is implied, but not supported by all compilers yet.
1832 */
1833#if defined(IN_RING0) || defined(DOXYGEN_RUNNING)
1834# define DECLR0CALLBACKMEMBER(a_RetType, a_Name, a_Args) DECLCALLBACKMEMBER(a_RetType, a_Name, a_Args)
1835#else
1836# define DECLR0CALLBACKMEMBER(a_RetType, a_Name, a_Args) RTR0PTR a_Name
1837#endif
1838
1839/** @def DECLINLINE
1840 * How to declare a function as inline that does not throw any C++ exceptions.
1841 * @param a_RetType The return type of the function declaration.
1842 * @remarks Don't use this macro on C++ methods.
1843 * @sa DECL_INLINE_THROW
1844 */
1845#if defined(__GNUC__) && !defined(DOXYGEN_RUNNING)
1846# define DECLINLINE(a_RetType) DECL_NOTHROW(static __inline__ a_RetType)
1847#elif defined(__cplusplus) || defined(DOXYGEN_RUNNING)
1848# define DECLINLINE(a_RetType) DECL_NOTHROW(static inline a_RetType)
1849#elif defined(_MSC_VER)
1850# define DECLINLINE(a_RetType) DECL_NOTHROW(static _inline a_RetType)
1851#elif defined(__IBMC__)
1852# define DECLINLINE(a_RetType) DECL_NOTHROW(_Inline a_RetType)
1853#else
1854# define DECLINLINE(a_RetType) DECL_NOTHROW(inline a_RetType)
1855#endif
1856
1857/** @def DECL_INLINE_THROW
1858 * How to declare a function as inline that throws C++ exceptions.
1859 * @param a_RetType The return type of the function declaration.
1860 * @remarks Don't use this macro on C++ methods.
1861 */
1862#if defined(__GNUC__) && !defined(DOXYGEN_RUNNING)
1863# define DECL_INLINE_THROW(a_RetType) static __inline__ a_RetType
1864#elif defined(__cplusplus) || defined(DOXYGEN_RUNNING)
1865# define DECL_INLINE_THROW(a_RetType) static inline a_RetType
1866#elif defined(_MSC_VER)
1867# define DECL_INLINE_THROW(a_RetType) static _inline a_RetType
1868#elif defined(__IBMC__)
1869# define DECL_INLINE_THROW(a_RetType) _Inline a_RetType
1870#else
1871# define DECL_INLINE_THROW(a_RetType) inline a_RetType
1872#endif
1873
1874/** @def DECL_FORCE_INLINE
1875 * How to declare a function that does not throw any C++ exceptions as inline
1876 * and try convince the compiler to always inline it regardless of optimization
1877 * switches.
1878 * @param a_RetType The return type of the function declaration.
1879 * @remarks Use sparsely and with care. Don't use this macro on C++ methods.
1880 * @sa DECL_FORCE_INLINE_THROW
1881 */
1882#ifdef __GNUC__
1883# define DECL_FORCE_INLINE(a_RetType) __attribute__((__always_inline__)) DECLINLINE(a_RetType)
1884#elif defined(_MSC_VER)
1885# define DECL_FORCE_INLINE(a_RetType) DECL_NOTHROW(__forceinline a_RetType)
1886#else
1887# define DECL_FORCE_INLINE(a_RetType) DECLINLINE(a_RetType)
1888#endif
1889
1890/** @def DECL_FORCE_INLINE_THROW
1891 * How to declare a function throwing C++ exceptions as inline and try convince
1892 * the compiler to always inline it regardless of optimization switches.
1893 * @param a_RetType The return type of the function declaration.
1894 * @remarks Use sparsely and with care. Don't use this macro on C++ methods.
1895 */
1896#ifdef __GNUC__
1897# define DECL_FORCE_INLINE_THROW(a_RetType) __attribute__((__always_inline__)) DECL_INLINE_THROW(a_RetType)
1898#elif defined(_MSC_VER)
1899# define DECL_FORCE_INLINE_THROW(a_RetType) __forceinline a_RetType
1900#else
1901# define DECL_FORCE_INLINE_THROW(a_RetType) DECL_INLINE_THROW(a_RetType)
1902#endif
1903
1904
1905/** @def DECL_NO_INLINE
1906 * How to declare a function telling the compiler not to inline it.
1907 * @param scope The function scope, static or RT_NOTHING.
1908 * @param a_RetType The return type of the function declaration.
1909 * @remarks Don't use this macro on C++ methods.
1910 */
1911#ifdef __GNUC__
1912# define DECL_NO_INLINE(scope, a_RetType) __attribute__((__noinline__)) scope a_RetType
1913#elif defined(_MSC_VER)
1914# define DECL_NO_INLINE(scope, a_RetType) __declspec(noinline) scope a_RetType
1915#else
1916# define DECL_NO_INLINE(scope,a_RetType) scope a_RetType
1917#endif
1918
1919
1920/** @def IN_RT_STATIC
1921 * Used to indicate whether we're linking against a static IPRT
1922 * or not.
1923 *
1924 * The IPRT symbols will be declared as hidden (if supported). Note that this
1925 * define has no effect without also setting one of the IN_RT_R0, IN_RT_R3 or
1926 * IN_RT_RC indicators.
1927 */
1928
1929/** @def IN_RT_R0
1930 * Used to indicate whether we're inside the same link module as the host
1931 * context ring-0 Runtime Library.
1932 */
1933/** @def RTR0DECL(a_RetType)
1934 * Runtime Library host context ring-0 export or import declaration.
1935 * @param a_RetType The return a_RetType of the function declaration.
1936 * @remarks This is only used inside IPRT. Other APIs need to define their own
1937 * XXXX_DECL macros for dealing with import/export/static visibility.
1938 * @note DECL_NOTHROW is implied.
1939 */
1940#ifdef IN_RT_R0
1941# ifdef IN_RT_STATIC
1942# define RTR0DECL(a_RetType) DECL_HIDDEN_NOTHROW(a_RetType) RTCALL
1943# else
1944# define RTR0DECL(a_RetType) DECL_EXPORT_NOTHROW(a_RetType) RTCALL
1945# endif
1946#else
1947# define RTR0DECL(a_RetType) DECL_IMPORT_NOTHROW(a_RetType) RTCALL
1948#endif
1949
1950/** @def IN_RT_R3
1951 * Used to indicate whether we're inside the same link module as the host
1952 * context ring-3 Runtime Library.
1953 */
1954/** @def RTR3DECL(a_RetType)
1955 * Runtime Library host context ring-3 export or import declaration.
1956 * @param a_RetType The return type of the function declaration.
1957 * @remarks This is only used inside IPRT. Other APIs need to define their own
1958 * XXXX_DECL macros for dealing with import/export/static visibility.
1959 * @note DECL_NOTHROW is implied.
1960 */
1961#ifdef IN_RT_R3
1962# ifdef IN_RT_STATIC
1963# define RTR3DECL(a_RetType) DECL_HIDDEN_NOTHROW(a_RetType) RTCALL
1964# else
1965# define RTR3DECL(a_RetType) DECL_EXPORT_NOTHROW(a_RetType) RTCALL
1966# endif
1967#else
1968# define RTR3DECL(a_RetType) DECL_IMPORT_NOTHROW(a_RetType) RTCALL
1969#endif
1970
1971/** @def IN_RT_RC
1972 * Used to indicate whether we're inside the same link module as the raw-mode
1973 * context (RC) runtime library.
1974 */
1975/** @def RTRCDECL(a_RetType)
1976 * Runtime Library raw-mode context export or import declaration.
1977 * @param a_RetType The return type of the function declaration.
1978 * @remarks This is only used inside IPRT. Other APIs need to define their own
1979 * XXXX_DECL macros for dealing with import/export/static visibility.
1980 * @note DECL_NOTHROW is implied.
1981 */
1982#ifdef IN_RT_RC
1983# ifdef IN_RT_STATIC
1984# define RTRCDECL(a_RetType) DECL_HIDDEN_NOTHROW(a_RetType) RTCALL
1985# else
1986# define RTRCDECL(a_RetType) DECL_EXPORT_NOTHROW(a_RetType) RTCALL
1987# endif
1988#else
1989# define RTRCDECL(a_RetType) DECL_IMPORT_NOTHROW(a_RetType) RTCALL
1990#endif
1991
1992/** @def RTDECL(a_RetType)
1993 * Runtime Library export or import declaration.
1994 * Functions declared using this macro exists in all contexts.
1995 * @param a_RetType The return type of the function declaration.
1996 * @remarks This is only used inside IPRT. Other APIs need to define their own
1997 * XXXX_DECL macros for dealing with import/export/static visibility.
1998 * @note DECL_NOTHROW is implied.
1999 */
2000#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
2001# ifdef IN_RT_STATIC
2002# define RTDECL(a_RetType) DECL_HIDDEN_NOTHROW(a_RetType) RTCALL
2003# else
2004# define RTDECL(a_RetType) DECL_EXPORT_NOTHROW(a_RetType) RTCALL
2005# endif
2006#else
2007# define RTDECL(a_RetType) DECL_IMPORT_NOTHROW(a_RetType) RTCALL
2008#endif
2009
2010/** @def RTDATADECL(a_Type)
2011 * Runtime Library export or import declaration.
2012 * Data declared using this macro exists in all contexts.
2013 * @param a_Type The data type.
2014 * @remarks This is only used inside IPRT. Other APIs need to define their own
2015 * XXXX_DECL macros for dealing with import/export/static visibility.
2016 */
2017/** @def RT_DECL_DATA_CONST(a_Type)
2018 * Definition of a const variable. See DECL_HIDDEN_CONST.
2019 * @param a_Type The const data type.
2020 * @remarks This is only used inside IPRT. Other APIs need to define their own
2021 * XXXX_DECL macros for dealing with import/export/static visibility.
2022 */
2023#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
2024# ifdef IN_RT_STATIC
2025# define RTDATADECL(a_Type) DECL_HIDDEN_DATA(a_Type)
2026# define RT_DECL_DATA_CONST(a_Type) DECL_HIDDEN_CONST(a_Type)
2027# else
2028# define RTDATADECL(a_Type) DECLEXPORT(a_Type)
2029# if defined(__cplusplus) && defined(__GNUC__)
2030# define RT_DECL_DATA_CONST(a_Type) a_Type
2031# else
2032# define RT_DECL_DATA_CONST(a_Type) DECLEXPORT(a_Type)
2033# endif
2034# endif
2035#else
2036# define RTDATADECL(a_Type) DECLIMPORT(a_Type)
2037# define RT_DECL_DATA_CONST(a_Type) DECLIMPORT(a_Type)
2038#endif
2039
2040/** @def RT_DECL_CLASS
2041 * Declares an class living in the runtime.
2042 * @remarks This is only used inside IPRT. Other APIs need to define their own
2043 * XXXX_DECL macros for dealing with import/export/static visibility.
2044 */
2045#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
2046# ifdef IN_RT_STATIC
2047# define RT_DECL_CLASS
2048# else
2049# define RT_DECL_CLASS DECLEXPORT_CLASS
2050# endif
2051#else
2052# define RT_DECL_CLASS DECLIMPORT_CLASS
2053#endif
2054
2055
2056/** @def RT_NOCRT
2057 * Symbol name wrapper for the No-CRT bits.
2058 *
2059 * In order to coexist in the same process as other CRTs, we need to
2060 * decorate the symbols such that they don't conflict the ones in the
2061 * other CRTs. The result of such conflicts / duplicate symbols can
2062 * confuse the dynamic loader on Unix like systems.
2063 *
2064 * Define RT_WITHOUT_NOCRT_WRAPPERS to drop the wrapping.
2065 * Define RT_WITHOUT_NOCRT_WRAPPER_ALIASES to drop the aliases to the
2066 * wrapped names.
2067 */
2068/** @def RT_NOCRT_STR
2069 * Same as RT_NOCRT only it'll return a double quoted string of the result.
2070 */
2071#if !defined(RT_WITHOUT_NOCRT_WRAPPERS) || defined(RT_FORCE_NOCRT_WRAPPERS)
2072# define RT_NOCRT(name) nocrt_ ## name
2073# define RT_NOCRT_STR(name) "nocrt_" # name
2074#else
2075# define RT_NOCRT(name) name
2076# define RT_NOCRT_STR(name) #name
2077#endif
2078
2079
2080/** @name Untrusted data classifications.
2081 * @{ */
2082/** @def RT_UNTRUSTED_USER
2083 * For marking non-volatile (race free) data from user mode as untrusted.
2084 * This is just for visible documentation. */
2085#define RT_UNTRUSTED_USER
2086/** @def RT_UNTRUSTED_VOLATILE_USER
2087 * For marking volatile data shared with user mode as untrusted.
2088 * This is more than just documentation as it specifies the 'volatile' keyword,
2089 * because the guest could modify the data at any time. */
2090#define RT_UNTRUSTED_VOLATILE_USER volatile
2091
2092/** @def RT_UNTRUSTED_GUEST
2093 * For marking non-volatile (race free) data from the guest as untrusted.
2094 * This is just for visible documentation. */
2095#define RT_UNTRUSTED_GUEST
2096/** @def RT_UNTRUSTED_VOLATILE_GUEST
2097 * For marking volatile data shared with the guest as untrusted.
2098 * This is more than just documentation as it specifies the 'volatile' keyword,
2099 * because the guest could modify the data at any time. */
2100#define RT_UNTRUSTED_VOLATILE_GUEST volatile
2101
2102/** @def RT_UNTRUSTED_HOST
2103 * For marking non-volatile (race free) data from the host as untrusted.
2104 * This is just for visible documentation. */
2105#define RT_UNTRUSTED_HOST
2106/** @def RT_UNTRUSTED_VOLATILE_HOST
2107 * For marking volatile data shared with the host as untrusted.
2108 * This is more than just documentation as it specifies the 'volatile' keyword,
2109 * because the host could modify the data at any time. */
2110#define RT_UNTRUSTED_VOLATILE_HOST volatile
2111
2112/** @def RT_UNTRUSTED_HSTGST
2113 * For marking non-volatile (race free) data from the host/gust as untrusted.
2114 * This is just for visible documentation. */
2115#define RT_UNTRUSTED_HSTGST
2116/** @def RT_UNTRUSTED_VOLATILE_HSTGST
2117 * For marking volatile data shared with the host/guest as untrusted.
2118 * This is more than just documentation as it specifies the 'volatile' keyword,
2119 * because the host could modify the data at any time. */
2120#define RT_UNTRUSTED_VOLATILE_HSTGST volatile
2121/** @} */
2122
2123/** @name Fences for use when handling untrusted data.
2124 * @{ */
2125/** For use after copying untruated volatile data to a non-volatile location.
2126 * This translates to a compiler memory barrier and will help ensure that the
2127 * compiler uses the non-volatile copy of the data. */
2128#define RT_UNTRUSTED_NONVOLATILE_COPY_FENCE() ASMCompilerBarrier()
2129/** For use after finished validating guest input.
2130 * What this translates to is architecture dependent. On intel it will
2131 * translate to a CPU load+store fence as well as a compiler memory barrier. */
2132#if defined(RT_ARCH_AMD64) || (defined(RT_ARCH_X86) && !defined(RT_WITH_OLD_CPU_SUPPORT))
2133# define RT_UNTRUSTED_VALIDATED_FENCE() do { ASMCompilerBarrier(); ASMReadFence(); } while (0)
2134#elif defined(RT_ARCH_X86)
2135# define RT_UNTRUSTED_VALIDATED_FENCE() do { ASMCompilerBarrier(); ASMMemoryFence(); } while (0)
2136#else
2137# define RT_UNTRUSTED_VALIDATED_FENCE() do { ASMCompilerBarrier(); } while (0)
2138#endif
2139/** @} */
2140
2141
2142/** @def RT_LIKELY
2143 * Give the compiler a hint that an expression is very likely to hold true.
2144 *
2145 * Some compilers support explicit branch prediction so that the CPU backend
2146 * can hint the processor and also so that code blocks can be reordered such
2147 * that the predicted path sees a more linear flow, thus improving cache
2148 * behaviour, etc.
2149 *
2150 * IPRT provides the macros RT_LIKELY() and RT_UNLIKELY() as a way to utilize
2151 * this compiler feature when present.
2152 *
2153 * A few notes about the usage:
2154 *
2155 * - Generally, order your code use RT_LIKELY() instead of RT_UNLIKELY().
2156 *
2157 * - Generally, use RT_UNLIKELY() with error condition checks (unless you
2158 * have some _strong_ reason to do otherwise, in which case document it),
2159 * and/or RT_LIKELY() with success condition checks, assuming you want
2160 * to optimize for the success path.
2161 *
2162 * - Other than that, if you don't know the likelihood of a test succeeding
2163 * from empirical or other 'hard' evidence, don't make predictions unless
2164 * you happen to be a Dirk Gently character.
2165 *
2166 * - These macros are meant to be used in places that get executed a lot. It
2167 * is wasteful to make predictions in code that is executed rarely (e.g.
2168 * at subsystem initialization time) as the basic block reordering that this
2169 * affects can often generate larger code.
2170 *
2171 * - Note that RT_SUCCESS() and RT_FAILURE() already makes use of RT_LIKELY()
2172 * and RT_UNLIKELY(). Should you wish for prediction free status checks,
2173 * use the RT_SUCCESS_NP() and RT_FAILURE_NP() macros instead.
2174 *
2175 *
2176 * @returns the boolean result of the expression.
2177 * @param expr The expression that's very likely to be true.
2178 * @see RT_UNLIKELY
2179 */
2180/** @def RT_UNLIKELY
2181 * Give the compiler a hint that an expression is highly unlikely to hold true.
2182 *
2183 * See the usage instructions give in the RT_LIKELY() docs.
2184 *
2185 * @returns the boolean result of the expression.
2186 * @param expr The expression that's very unlikely to be true.
2187 * @see RT_LIKELY
2188 *
2189 * @deprecated Please use RT_LIKELY() instead wherever possible! That gives us
2190 * a better chance of the windows compilers to generate favorable code
2191 * too. The belief is that the compiler will by default assume the
2192 * if-case is more likely than the else-case.
2193 */
2194#if defined(__GNUC__)
2195# if __GNUC__ >= 3 && !defined(FORTIFY_RUNNING)
2196# define RT_LIKELY(expr) __builtin_expect(!!(expr), 1)
2197# define RT_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
2198# else
2199# define RT_LIKELY(expr) (expr)
2200# define RT_UNLIKELY(expr) (expr)
2201# endif
2202#else
2203# define RT_LIKELY(expr) (expr)
2204# define RT_UNLIKELY(expr) (expr)
2205#endif
2206
2207/** @def RT_EXPAND_2
2208 * Helper for RT_EXPAND. */
2209#define RT_EXPAND_2(a_Expr) a_Expr
2210/** @def RT_EXPAND
2211 * Returns the expanded expression.
2212 * @param a_Expr The expression to expand. */
2213#define RT_EXPAND(a_Expr) RT_EXPAND_2(a_Expr)
2214
2215/** @def RT_STR
2216 * Returns the argument as a string constant.
2217 * @param str Argument to stringify. */
2218#define RT_STR(str) #str
2219/** @def RT_XSTR
2220 * Returns the expanded argument as a string.
2221 * @param str Argument to expand and stringify. */
2222#define RT_XSTR(str) RT_STR(str)
2223
2224/** @def RT_LSTR_2
2225 * Helper for RT_WSTR that gets the expanded @a str.
2226 * @param str String litteral to prefix with 'L'. */
2227#define RT_LSTR_2(str) L##str
2228/** @def RT_LSTR
2229 * Returns the expanded argument with a L string prefix.
2230 *
2231 * Intended for converting ASCII string \#defines into wide char string
2232 * litterals on Windows.
2233 *
2234 * @param str String litteral to . */
2235#define RT_LSTR(str) RT_LSTR_2(str)
2236
2237/** @def RT_UNPACK_CALL
2238 * Unpacks the an argument list inside an extra set of parenthesis and turns it
2239 * into a call to @a a_Fn.
2240 *
2241 * @param a_Fn Function/macro to call.
2242 * @param a_Args Parameter list in parenthesis.
2243 */
2244#define RT_UNPACK_CALL(a_Fn, a_Args) a_Fn a_Args
2245
2246#if defined(RT_COMPILER_SUPPORTS_VA_ARGS) || defined(DOXYGEN_RUNNING)
2247
2248/** @def RT_UNPACK_ARGS
2249 * Returns the arguments without parenthesis.
2250 *
2251 * @param ... Parameter list in parenthesis.
2252 * @remarks Requires RT_COMPILER_SUPPORTS_VA_ARGS.
2253 */
2254# define RT_UNPACK_ARGS(...) __VA_ARGS__
2255
2256/** @def RT_COUNT_VA_ARGS_HLP
2257 * Helper for RT_COUNT_VA_ARGS that picks out the argument count from
2258 * RT_COUNT_VA_ARGS_REV_SEQ. */
2259# define RT_COUNT_VA_ARGS_HLP( \
2260 c69, c68, c67, c66, c65, c64, c63, c62, c61, c60, \
2261 c59, c58, c57, c56, c55, c54, c53, c52, c51, c50, \
2262 c49, c48, c47, c46, c45, c44, c43, c42, c41, c40, \
2263 c39, c38, c37, c36, c35, c34, c33, c32, c31, c30, \
2264 c29, c28, c27, c26, c25, c24, c23, c22, c21, c20, \
2265 c19, c18, c17, c16, c15, c14, c13, c12, c11, c10, \
2266 c9, c8, c7, c6, c5, c4, c3, c2, c1, cArgs, ...) cArgs
2267/** Argument count sequence. */
2268# define RT_COUNT_VA_ARGS_REV_SEQ \
2269 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, \
2270 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
2271 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
2272 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
2273 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
2274 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
2275 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
2276/** This is for zero arguments. At least Visual C++ requires it. */
2277# define RT_COUNT_VA_ARGS_PREFIX_RT_NOTHING RT_COUNT_VA_ARGS_REV_SEQ
2278/**
2279 * Counts the number of arguments given to the variadic macro.
2280 *
2281 * Max is 69.
2282 *
2283 * @returns Number of arguments in the ellipsis
2284 * @param ... Arguments to count.
2285 * @remarks Requires RT_COMPILER_SUPPORTS_VA_ARGS.
2286 */
2287# define RT_COUNT_VA_ARGS(...) \
2288 RT_UNPACK_CALL(RT_COUNT_VA_ARGS_HLP, (RT_COUNT_VA_ARGS_PREFIX_ ## __VA_ARGS__ ## RT_NOTHING, \
2289 RT_COUNT_VA_ARGS_REV_SEQ))
2290
2291#endif /* RT_COMPILER_SUPPORTS_VA_ARGS */
2292
2293
2294/** @def RT_CONCAT
2295 * Concatenate the expanded arguments without any extra spaces in between.
2296 *
2297 * @param a The first part.
2298 * @param b The second part.
2299 */
2300#define RT_CONCAT(a,b) RT_CONCAT_HLP(a,b)
2301/** RT_CONCAT helper, don't use. */
2302#define RT_CONCAT_HLP(a,b) a##b
2303
2304/** @def RT_CONCAT3
2305 * Concatenate the expanded arguments without any extra spaces in between.
2306 *
2307 * @param a The 1st part.
2308 * @param b The 2nd part.
2309 * @param c The 3rd part.
2310 */
2311#define RT_CONCAT3(a,b,c) RT_CONCAT3_HLP(a,b,c)
2312/** RT_CONCAT3 helper, don't use. */
2313#define RT_CONCAT3_HLP(a,b,c) a##b##c
2314
2315/** @def RT_CONCAT4
2316 * Concatenate the expanded arguments without any extra spaces in between.
2317 *
2318 * @param a The 1st part.
2319 * @param b The 2nd part.
2320 * @param c The 3rd part.
2321 * @param d The 4th part.
2322 */
2323#define RT_CONCAT4(a,b,c,d) RT_CONCAT4_HLP(a,b,c,d)
2324/** RT_CONCAT4 helper, don't use. */
2325#define RT_CONCAT4_HLP(a,b,c,d) a##b##c##d
2326
2327/** @def RT_CONCAT5
2328 * Concatenate the expanded arguments without any extra spaces in between.
2329 *
2330 * @param a The 1st part.
2331 * @param b The 2nd part.
2332 * @param c The 3rd part.
2333 * @param d The 4th part.
2334 * @param e The 5th part.
2335 */
2336#define RT_CONCAT5(a,b,c,d,e) RT_CONCAT5_HLP(a,b,c,d,e)
2337/** RT_CONCAT5 helper, don't use. */
2338#define RT_CONCAT5_HLP(a,b,c,d,e) a##b##c##d##e
2339
2340/** @def RT_CONCAT6
2341 * Concatenate the expanded arguments without any extra spaces in between.
2342 *
2343 * @param a The 1st part.
2344 * @param b The 2nd part.
2345 * @param c The 3rd part.
2346 * @param d The 4th part.
2347 * @param e The 5th part.
2348 * @param f The 6th part.
2349 */
2350#define RT_CONCAT6(a,b,c,d,e,f) RT_CONCAT6_HLP(a,b,c,d,e,f)
2351/** RT_CONCAT6 helper, don't use. */
2352#define RT_CONCAT6_HLP(a,b,c,d,e,f) a##b##c##d##e##f
2353
2354/** @def RT_CONCAT7
2355 * Concatenate the expanded arguments without any extra spaces in between.
2356 *
2357 * @param a The 1st part.
2358 * @param b The 2nd part.
2359 * @param c The 3rd part.
2360 * @param d The 4th part.
2361 * @param e The 5th part.
2362 * @param f The 6th part.
2363 * @param g The 7th part.
2364 */
2365#define RT_CONCAT7(a,b,c,d,e,f,g) RT_CONCAT7_HLP(a,b,c,d,e,f,g)
2366/** RT_CONCAT7 helper, don't use. */
2367#define RT_CONCAT7_HLP(a,b,c,d,e,f,g) a##b##c##d##e##f##g
2368
2369/** @def RT_CONCAT8
2370 * Concatenate the expanded arguments without any extra spaces in between.
2371 *
2372 * @param a The 1st part.
2373 * @param b The 2nd part.
2374 * @param c The 3rd part.
2375 * @param d The 4th part.
2376 * @param e The 5th part.
2377 * @param f The 6th part.
2378 * @param g The 7th part.
2379 * @param h The 8th part.
2380 */
2381#define RT_CONCAT8(a,b,c,d,e,f,g,h) RT_CONCAT8_HLP(a,b,c,d,e,f,g,h)
2382/** RT_CONCAT8 helper, don't use. */
2383#define RT_CONCAT8_HLP(a,b,c,d,e,f,g,h) a##b##c##d##e##f##g##h
2384
2385/** @def RT_CONCAT9
2386 * Concatenate the expanded arguments without any extra spaces in between.
2387 *
2388 * @param a The 1st part.
2389 * @param b The 2nd part.
2390 * @param c The 3rd part.
2391 * @param d The 4th part.
2392 * @param e The 5th part.
2393 * @param f The 6th part.
2394 * @param g The 7th part.
2395 * @param h The 8th part.
2396 * @param i The 9th part.
2397 */
2398#define RT_CONCAT9(a,b,c,d,e,f,g,h,i) RT_CONCAT9_HLP(a,b,c,d,e,f,g,h,i)
2399/** RT_CONCAT9 helper, don't use. */
2400#define RT_CONCAT9_HLP(a,b,c,d,e,f,g,h,i) a##b##c##d##e##f##g##h##i
2401
2402/**
2403 * String constant tuple - string constant, strlen(string constant).
2404 *
2405 * @param a_szConst String constant.
2406 * @sa RTSTRTUPLE
2407 */
2408#define RT_STR_TUPLE(a_szConst) a_szConst, (sizeof(a_szConst) - 1)
2409
2410
2411/**
2412 * Macro for using in switch statements that turns constants into strings.
2413 *
2414 * @param a_Const The constant (not string).
2415 */
2416#define RT_CASE_RET_STR(a_Const) case a_Const: return #a_Const
2417
2418
2419/** @def RT_BIT
2420 * Convert a bit number into an integer bitmask (unsigned).
2421 * @param bit The bit number.
2422 */
2423#define RT_BIT(bit) ( 1U << (bit) )
2424
2425/** @def RT_BIT_32
2426 * Convert a bit number into a 32-bit bitmask (unsigned).
2427 * @param bit The bit number.
2428 */
2429#define RT_BIT_32(bit) ( UINT32_C(1) << (bit) )
2430
2431/** @def RT_BIT_64
2432 * Convert a bit number into a 64-bit bitmask (unsigned).
2433 * @param bit The bit number.
2434 */
2435#define RT_BIT_64(bit) ( UINT64_C(1) << (bit) )
2436
2437/** @def RT_BIT_Z
2438 * Convert a bit number into a size_t bitmask (for avoid MSC warnings).
2439 * @param a_iBit The bit number.
2440 */
2441#define RT_BIT_Z(a_iBit) ( (size_t)(1) << (a_iBit) )
2442
2443
2444/** @def RT_BF_GET
2445 * Gets the value of a bit field in an integer value.
2446 *
2447 * This requires a couple of macros to be defined for the field:
2448 * - \<a_FieldNm\>_SHIFT: The shift count to get to the field.
2449 * - \<a_FieldNm\>_MASK: The field mask.
2450 *
2451 * @returns The bit field value.
2452 * @param a_uValue The integer value containing the field.
2453 * @param a_FieldNm The field name prefix for getting at the _SHIFT and
2454 * _MASK macros.
2455 * @sa #RT_BF_CLEAR, #RT_BF_SET, #RT_BF_MAKE, #RT_BF_ZMASK
2456 */
2457#define RT_BF_GET(a_uValue, a_FieldNm) ( ((a_uValue) >> RT_CONCAT(a_FieldNm,_SHIFT)) & RT_BF_ZMASK(a_FieldNm) )
2458
2459/** @def RT_BF_SET
2460 * Sets the given bit field in the integer value.
2461 *
2462 * This requires a couple of macros to be defined for the field:
2463 * - \<a_FieldNm\>_SHIFT: The shift count to get to the field.
2464 * - \<a_FieldNm\>_MASK: The field mask. Must have the same type as the
2465 * integer value!!
2466 *
2467 * @returns Integer value with bit field set to @a a_uFieldValue.
2468 * @param a_uValue The integer value containing the field.
2469 * @param a_FieldNm The field name prefix for getting at the _SHIFT and
2470 * _MASK macros.
2471 * @param a_uFieldValue The new field value.
2472 * @sa #RT_BF_GET, #RT_BF_CLEAR, #RT_BF_MAKE, #RT_BF_ZMASK
2473 */
2474#define RT_BF_SET(a_uValue, a_FieldNm, a_uFieldValue) ( RT_BF_CLEAR(a_uValue, a_FieldNm) | RT_BF_MAKE(a_FieldNm, a_uFieldValue) )
2475
2476/** @def RT_BF_CLEAR
2477 * Clears the given bit field in the integer value.
2478 *
2479 * This requires a couple of macros to be defined for the field:
2480 * - \<a_FieldNm\>_SHIFT: The shift count to get to the field.
2481 * - \<a_FieldNm\>_MASK: The field mask. Must have the same type as the
2482 * integer value!!
2483 *
2484 * @returns Integer value with bit field set to zero.
2485 * @param a_uValue The integer value containing the field.
2486 * @param a_FieldNm The field name prefix for getting at the _SHIFT and
2487 * _MASK macros.
2488 * @sa #RT_BF_GET, #RT_BF_SET, #RT_BF_MAKE, #RT_BF_ZMASK
2489 */
2490#define RT_BF_CLEAR(a_uValue, a_FieldNm) ( (a_uValue) & ~RT_CONCAT(a_FieldNm,_MASK) )
2491
2492/** @def RT_BF_MAKE
2493 * Shifts and masks a bit field value into position in the integer value.
2494 *
2495 * This requires a couple of macros to be defined for the field:
2496 * - \<a_FieldNm\>_SHIFT: The shift count to get to the field.
2497 * - \<a_FieldNm\>_MASK: The field mask.
2498 *
2499 * @param a_FieldNm The field name prefix for getting at the _SHIFT and
2500 * _MASK macros.
2501 * @param a_uFieldValue The field value that should be masked and shifted
2502 * into position.
2503 * @sa #RT_BF_GET, #RT_BF_SET, #RT_BF_CLEAR, #RT_BF_ZMASK
2504 */
2505#define RT_BF_MAKE(a_FieldNm, a_uFieldValue) ( ((a_uFieldValue) & RT_BF_ZMASK(a_FieldNm) ) << RT_CONCAT(a_FieldNm,_SHIFT) )
2506
2507/** @def RT_BF_ZMASK
2508 * Helper for getting the field mask shifted to bit position zero.
2509 *
2510 * @param a_FieldNm The field name prefix for getting at the _SHIFT and
2511 * _MASK macros.
2512 * @sa #RT_BF_GET, #RT_BF_SET, #RT_BF_CLEAR, #RT_BF_MAKE
2513 */
2514#define RT_BF_ZMASK(a_FieldNm) ( RT_CONCAT(a_FieldNm,_MASK) >> RT_CONCAT(a_FieldNm,_SHIFT) )
2515
2516/** Bit field compile time check helper
2517 * @internal */
2518#define RT_BF_CHECK_DO_XOR_MASK(a_uLeft, a_RightPrefix, a_FieldNm) ((a_uLeft) ^ RT_CONCAT3(a_RightPrefix, a_FieldNm, _MASK))
2519/** Bit field compile time check helper
2520 * @internal */
2521#define RT_BF_CHECK_DO_OR_MASK(a_uLeft, a_RightPrefix, a_FieldNm) ((a_uLeft) | RT_CONCAT3(a_RightPrefix, a_FieldNm, _MASK))
2522/** Bit field compile time check helper
2523 * @internal */
2524#define RT_BF_CHECK_DO_1ST_MASK_BIT(a_uLeft, a_RightPrefix, a_FieldNm) \
2525 ((a_uLeft) && ( (RT_CONCAT3(a_RightPrefix, a_FieldNm, _MASK) >> RT_CONCAT3(a_RightPrefix, a_FieldNm, _SHIFT)) & 1U ) )
2526/** Used to check that a bit field mask does not start too early.
2527 * @internal */
2528#define RT_BF_CHECK_DO_MASK_START(a_uLeft, a_RightPrefix, a_FieldNm) \
2529 ( (a_uLeft) \
2530 && ( RT_CONCAT3(a_RightPrefix, a_FieldNm, _SHIFT) == 0 \
2531 || ( ( ( ((RT_CONCAT3(a_RightPrefix, a_FieldNm, _MASK) >> RT_CONCAT3(a_RightPrefix, a_FieldNm, _SHIFT)) & 1U) \
2532 << RT_CONCAT3(a_RightPrefix, a_FieldNm, _SHIFT)) /* => single bit mask, correct type */ \
2533 - 1U) /* => mask of all bits below the field */ \
2534 & RT_CONCAT3(a_RightPrefix, a_FieldNm, _MASK)) == 0 ) )
2535/** @name Bit field compile time check recursion workers.
2536 * @internal
2537 * @{ */
2538#define RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix, f1) \
2539 a_DoThis(a_uLeft, a_RightPrefix, f1)
2540#define RT_BF_CHECK_DO_2(a_DoThis, a_uLeft, a_RightPrefix, f1, f2) \
2541 RT_BF_CHECK_DO_1(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2)
2542#define RT_BF_CHECK_DO_3(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3) \
2543 RT_BF_CHECK_DO_2(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3)
2544#define RT_BF_CHECK_DO_4(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4) \
2545 RT_BF_CHECK_DO_3(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4)
2546#define RT_BF_CHECK_DO_5(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5) \
2547 RT_BF_CHECK_DO_4(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5)
2548#define RT_BF_CHECK_DO_6(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6) \
2549 RT_BF_CHECK_DO_5(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6)
2550#define RT_BF_CHECK_DO_7(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7) \
2551 RT_BF_CHECK_DO_6(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7)
2552#define RT_BF_CHECK_DO_8(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8) \
2553 RT_BF_CHECK_DO_7(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8)
2554#define RT_BF_CHECK_DO_9(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
2555 RT_BF_CHECK_DO_8(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9)
2556#define RT_BF_CHECK_DO_10(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
2557 RT_BF_CHECK_DO_9(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10)
2558#define RT_BF_CHECK_DO_11(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \
2559 RT_BF_CHECK_DO_10(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11)
2560#define RT_BF_CHECK_DO_12(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12) \
2561 RT_BF_CHECK_DO_11(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12)
2562#define RT_BF_CHECK_DO_13(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13) \
2563 RT_BF_CHECK_DO_12(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13)
2564#define RT_BF_CHECK_DO_14(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14) \
2565 RT_BF_CHECK_DO_13(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14)
2566#define RT_BF_CHECK_DO_15(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15) \
2567 RT_BF_CHECK_DO_14(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15)
2568#define RT_BF_CHECK_DO_16(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16) \
2569 RT_BF_CHECK_DO_15(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16)
2570#define RT_BF_CHECK_DO_17(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17) \
2571 RT_BF_CHECK_DO_16(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)
2572#define RT_BF_CHECK_DO_18(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18) \
2573 RT_BF_CHECK_DO_17(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18)
2574#define RT_BF_CHECK_DO_19(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19) \
2575 RT_BF_CHECK_DO_18(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19)
2576#define RT_BF_CHECK_DO_20(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20) \
2577 RT_BF_CHECK_DO_19(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20)
2578#define RT_BF_CHECK_DO_21(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21) \
2579 RT_BF_CHECK_DO_20(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21)
2580#define RT_BF_CHECK_DO_22(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22) \
2581 RT_BF_CHECK_DO_21(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22)
2582#define RT_BF_CHECK_DO_23(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23) \
2583 RT_BF_CHECK_DO_22(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23)
2584#define RT_BF_CHECK_DO_24(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24) \
2585 RT_BF_CHECK_DO_23(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24)
2586#define RT_BF_CHECK_DO_25(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25) \
2587 RT_BF_CHECK_DO_24(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25)
2588#define RT_BF_CHECK_DO_26(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26) \
2589 RT_BF_CHECK_DO_25(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26)
2590#define RT_BF_CHECK_DO_27(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27) \
2591 RT_BF_CHECK_DO_26(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27)
2592#define RT_BF_CHECK_DO_28(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28) \
2593 RT_BF_CHECK_DO_27(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28)
2594#define RT_BF_CHECK_DO_29(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29) \
2595 RT_BF_CHECK_DO_28(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29)
2596#define RT_BF_CHECK_DO_30(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30) \
2597 RT_BF_CHECK_DO_29(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30)
2598#define RT_BF_CHECK_DO_31(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31) \
2599 RT_BF_CHECK_DO_30(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31)
2600#define RT_BF_CHECK_DO_32(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32) \
2601 RT_BF_CHECK_DO_31(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32)
2602#define RT_BF_CHECK_DO_33(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33) \
2603 RT_BF_CHECK_DO_32(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33)
2604#define RT_BF_CHECK_DO_34(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34) \
2605 RT_BF_CHECK_DO_33(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34)
2606#define RT_BF_CHECK_DO_35(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35) \
2607 RT_BF_CHECK_DO_34(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35)
2608#define RT_BF_CHECK_DO_36(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36) \
2609 RT_BF_CHECK_DO_35(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36)
2610#define RT_BF_CHECK_DO_37(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37) \
2611 RT_BF_CHECK_DO_36(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37)
2612#define RT_BF_CHECK_DO_38(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38) \
2613 RT_BF_CHECK_DO_37(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38)
2614#define RT_BF_CHECK_DO_39(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39) \
2615 RT_BF_CHECK_DO_38(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39)
2616#define RT_BF_CHECK_DO_40(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40) \
2617 RT_BF_CHECK_DO_39(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40)
2618#define RT_BF_CHECK_DO_41(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41) \
2619 RT_BF_CHECK_DO_40(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41)
2620#define RT_BF_CHECK_DO_42(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42) \
2621 RT_BF_CHECK_DO_41(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42)
2622#define RT_BF_CHECK_DO_43(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43) \
2623 RT_BF_CHECK_DO_42(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43)
2624#define RT_BF_CHECK_DO_44(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44) \
2625 RT_BF_CHECK_DO_43(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44)
2626#define RT_BF_CHECK_DO_45(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45) \
2627 RT_BF_CHECK_DO_44(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45)
2628#define RT_BF_CHECK_DO_46(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46) \
2629 RT_BF_CHECK_DO_45(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46)
2630#define RT_BF_CHECK_DO_47(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47) \
2631 RT_BF_CHECK_DO_46(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47)
2632#define RT_BF_CHECK_DO_48(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48) \
2633 RT_BF_CHECK_DO_47(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48)
2634#define RT_BF_CHECK_DO_49(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49) \
2635 RT_BF_CHECK_DO_48(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49)
2636#define RT_BF_CHECK_DO_50(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50) \
2637 RT_BF_CHECK_DO_49(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50)
2638#define RT_BF_CHECK_DO_51(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51) \
2639 RT_BF_CHECK_DO_40(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51)
2640#define RT_BF_CHECK_DO_52(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52) \
2641 RT_BF_CHECK_DO_51(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52)
2642#define RT_BF_CHECK_DO_53(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53) \
2643 RT_BF_CHECK_DO_52(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53)
2644#define RT_BF_CHECK_DO_54(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54) \
2645 RT_BF_CHECK_DO_53(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54)
2646#define RT_BF_CHECK_DO_55(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55) \
2647 RT_BF_CHECK_DO_54(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55)
2648#define RT_BF_CHECK_DO_56(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56) \
2649 RT_BF_CHECK_DO_55(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56)
2650#define RT_BF_CHECK_DO_57(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57) \
2651 RT_BF_CHECK_DO_56(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57)
2652#define RT_BF_CHECK_DO_58(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58) \
2653 RT_BF_CHECK_DO_57(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58)
2654#define RT_BF_CHECK_DO_59(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59) \
2655 RT_BF_CHECK_DO_58(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59)
2656#define RT_BF_CHECK_DO_60(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60) \
2657 RT_BF_CHECK_DO_59(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60)
2658#define RT_BF_CHECK_DO_61(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61) \
2659 RT_BF_CHECK_DO_60(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61)
2660#define RT_BF_CHECK_DO_62(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62) \
2661 RT_BF_CHECK_DO_61(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62)
2662#define RT_BF_CHECK_DO_63(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, f63) \
2663 RT_BF_CHECK_DO_62(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, f63)
2664#define RT_BF_CHECK_DO_64(a_DoThis, a_uLeft, a_RightPrefix, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, f63, f64) \
2665 RT_BF_CHECK_DO_63(a_DoThis, RT_BF_CHECK_DO_1(a_DoThis, a_uLeft, a_RightPrefix,f1), a_RightPrefix, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, f63, f64)
2666/** @} */
2667
2668/** @def RT_BF_ASSERT_COMPILE_CHECKS
2669 * Emits a series of AssertCompile statements checking that the bit-field
2670 * declarations doesn't overlap, has holes, and generally makes some sense.
2671 *
2672 * This requires variadic macros because its too much to type otherwise.
2673 */
2674#if defined(RT_COMPILER_SUPPORTS_VA_ARGS) || defined(DOXYGEN_RUNNING)
2675# define RT_BF_ASSERT_COMPILE_CHECKS(a_Prefix, a_uZero, a_uCovered, a_Fields) \
2676 AssertCompile(RT_BF_CHECK_DO_N(RT_BF_CHECK_DO_OR_MASK, a_uZero, a_Prefix, RT_UNPACK_ARGS a_Fields ) == a_uCovered); \
2677 AssertCompile(RT_BF_CHECK_DO_N(RT_BF_CHECK_DO_XOR_MASK, a_uCovered, a_Prefix, RT_UNPACK_ARGS a_Fields ) == 0); \
2678 AssertCompile(RT_BF_CHECK_DO_N(RT_BF_CHECK_DO_1ST_MASK_BIT, true, a_Prefix, RT_UNPACK_ARGS a_Fields ) == true); \
2679 AssertCompile(RT_BF_CHECK_DO_N(RT_BF_CHECK_DO_MASK_START, true, a_Prefix, RT_UNPACK_ARGS a_Fields ) == true)
2680/** Bit field compile time check helper
2681 * @internal */
2682# define RT_BF_CHECK_DO_N(a_DoThis, a_uLeft, a_RightPrefix, ...) \
2683 RT_UNPACK_CALL(RT_CONCAT(RT_BF_CHECK_DO_, RT_EXPAND(RT_COUNT_VA_ARGS(__VA_ARGS__))), (a_DoThis, a_uLeft, a_RightPrefix, __VA_ARGS__))
2684#else
2685# define RT_BF_ASSERT_COMPILE_CHECKS(a_Prefix, a_uZero, a_uCovered, a_Fields) AssertCompile(true)
2686#endif
2687
2688
2689/** @def RT_ALIGN
2690 * Align macro.
2691 * @param u Value to align.
2692 * @param uAlignment The alignment. Power of two!
2693 *
2694 * @remark Be extremely careful when using this macro with type which sizeof != sizeof int.
2695 * When possible use any of the other RT_ALIGN_* macros. And when that's not
2696 * possible, make 101% sure that uAlignment is specified with a right sized type.
2697 *
2698 * Specifying an unsigned 32-bit alignment constant with a 64-bit value will give
2699 * you a 32-bit return value!
2700 *
2701 * In short: Don't use this macro. Use RT_ALIGN_T() instead.
2702 */
2703#define RT_ALIGN(u, uAlignment) ( ((u) + ((uAlignment) - 1)) & ~((uAlignment) - 1) )
2704
2705/** @def RT_ALIGN_T
2706 * Align macro.
2707 * @param u Value to align.
2708 * @param uAlignment The alignment. Power of two!
2709 * @param type Integer type to use while aligning.
2710 * @remark This macro is the preferred alignment macro, it doesn't have any of the pitfalls RT_ALIGN has.
2711 */
2712#define RT_ALIGN_T(u, uAlignment, type) ( ((type)(u) + ((uAlignment) - 1)) & ~(type)((uAlignment) - 1) )
2713
2714/** @def RT_ALIGN_32
2715 * Align macro for a 32-bit value.
2716 * @param u32 Value to align.
2717 * @param uAlignment The alignment. Power of two!
2718 */
2719#define RT_ALIGN_32(u32, uAlignment) RT_ALIGN_T(u32, uAlignment, uint32_t)
2720
2721/** @def RT_ALIGN_64
2722 * Align macro for a 64-bit value.
2723 * @param u64 Value to align.
2724 * @param uAlignment The alignment. Power of two!
2725 */
2726#define RT_ALIGN_64(u64, uAlignment) RT_ALIGN_T(u64, uAlignment, uint64_t)
2727
2728/** @def RT_ALIGN_Z
2729 * Align macro for size_t.
2730 * @param cb Value to align.
2731 * @param uAlignment The alignment. Power of two!
2732 */
2733#define RT_ALIGN_Z(cb, uAlignment) RT_ALIGN_T(cb, uAlignment, size_t)
2734
2735/** @def RT_ALIGN_P
2736 * Align macro for pointers.
2737 * @param pv Value to align.
2738 * @param uAlignment The alignment. Power of two!
2739 */
2740#define RT_ALIGN_P(pv, uAlignment) RT_ALIGN_PT(pv, uAlignment, void *)
2741
2742/** @def RT_ALIGN_PT
2743 * Align macro for pointers with type cast.
2744 * @param u Value to align.
2745 * @param uAlignment The alignment. Power of two!
2746 * @param CastType The type to cast the result to.
2747 */
2748#define RT_ALIGN_PT(u, uAlignment, CastType) ( (CastType)RT_ALIGN_T(u, uAlignment, uintptr_t) )
2749
2750/** @def RT_ALIGN_R3PT
2751 * Align macro for ring-3 pointers with type cast.
2752 * @param u Value to align.
2753 * @param uAlignment The alignment. Power of two!
2754 * @param CastType The type to cast the result to.
2755 */
2756#define RT_ALIGN_R3PT(u, uAlignment, CastType) ( (CastType)RT_ALIGN_T(u, uAlignment, RTR3UINTPTR) )
2757
2758/** @def RT_ALIGN_R0PT
2759 * Align macro for ring-0 pointers with type cast.
2760 * @param u Value to align.
2761 * @param uAlignment The alignment. Power of two!
2762 * @param CastType The type to cast the result to.
2763 */
2764#define RT_ALIGN_R0PT(u, uAlignment, CastType) ( (CastType)RT_ALIGN_T(u, uAlignment, RTR0UINTPTR) )
2765
2766/** @def RT_ALIGN_GCPT
2767 * Align macro for GC pointers with type cast.
2768 * @param u Value to align.
2769 * @param uAlignment The alignment. Power of two!
2770 * @param CastType The type to cast the result to.
2771 */
2772#define RT_ALIGN_GCPT(u, uAlignment, CastType) ( (CastType)RT_ALIGN_T(u, uAlignment, RTGCUINTPTR) )
2773
2774
2775/** @def RT_OFFSETOF
2776 * Our own special offsetof() variant, returns a signed result.
2777 *
2778 * @returns offset into the structure of the specified member. signed.
2779 * @param type Structure type.
2780 * @param member Member.
2781 *
2782 * @remarks Only use this for static offset calculations. Please
2783 * use RT_UOFFSETOF_DYN for dynamic ones (i.e. involves
2784 * non-constant array indexing).
2785 *
2786 */
2787#if RT_GNUC_PREREQ(4, 0)
2788# define RT_OFFSETOF(type, member) ( (int)__builtin_offsetof(type, member) )
2789#else
2790# define RT_OFFSETOF(type, member) ( (int)(intptr_t)&( ((type *)(void *)0)->member) )
2791#endif
2792
2793/** @def RT_UOFFSETOF
2794 * Our own offsetof() variant, returns an unsigned result.
2795 *
2796 * @returns offset into the structure of the specified member. unsigned.
2797 * @param type Structure type.
2798 * @param member Member.
2799 *
2800 * @remarks Only use this for static offset calculations. Please
2801 * use RT_UOFFSETOF_DYN for dynamic ones (i.e. involves
2802 * non-constant array indexing).
2803 */
2804#if RT_GNUC_PREREQ(4, 0)
2805# define RT_UOFFSETOF(type, member) ( (uintptr_t)__builtin_offsetof(type, member) )
2806#else
2807# define RT_UOFFSETOF(type, member) ( (uintptr_t)&( ((type *)(void *)0)->member) )
2808#endif
2809
2810/** @def RT_OFFSETOF_ADD
2811 * RT_OFFSETOF with an addend.
2812 *
2813 * @returns offset into the structure of the specified member. signed.
2814 * @param type Structure type.
2815 * @param member Member.
2816 * @param addend The addend to add to the offset.
2817 *
2818 * @remarks Only use this for static offset calculations.
2819 */
2820#define RT_OFFSETOF_ADD(type, member, addend) ( (int)RT_UOFFSETOF_ADD(type, member, addend) )
2821
2822/** @def RT_UOFFSETOF_ADD
2823 * RT_UOFFSETOF with an addend.
2824 *
2825 * @returns offset into the structure of the specified member. signed.
2826 * @param type Structure type.
2827 * @param member Member.
2828 * @param addend The addend to add to the offset.
2829 *
2830 * @remarks Only use this for static offset calculations.
2831 */
2832#if RT_GNUC_PREREQ(4, 0)
2833# define RT_UOFFSETOF_ADD(type, member, addend) ( (uintptr_t)(__builtin_offsetof(type, member) + (addend)))
2834#else
2835# define RT_UOFFSETOF_ADD(type, member, addend) ( (uintptr_t)&( ((type *)(void *)(uintptr_t)(addend))->member) )
2836#endif
2837
2838/** @def RT_UOFFSETOF_DYN
2839 * Dynamic (runtime) structure offset calculations, involving
2840 * indexing of array members via variable.
2841 *
2842 * @returns offset into the structure of the specified member. signed.
2843 * @param type Structure type.
2844 * @param memberarray Member.
2845 */
2846#if defined(__cplusplus) && RT_GNUC_PREREQ(4, 4)
2847# define RT_UOFFSETOF_DYN(type, memberarray) ( (uintptr_t)&( ((type *)(void *)0x1000)->memberarray) - 0x1000 )
2848#else
2849# define RT_UOFFSETOF_DYN(type, memberarray) ( (uintptr_t)&( ((type *)(void *)0)->memberarray) )
2850#endif
2851
2852
2853/** @def RT_SIZEOFMEMB
2854 * Get the size of a structure member.
2855 *
2856 * @returns size of the structure member.
2857 * @param type Structure type.
2858 * @param member Member.
2859 */
2860#define RT_SIZEOFMEMB(type, member) ( sizeof(((type *)(void *)0)->member) )
2861
2862/** @def RT_UOFFSET_AFTER
2863 * Returns the offset of the first byte following a structure/union member.
2864 *
2865 * @return byte offset into the struct.
2866 * @param a_Type Structure type.
2867 * @param a_Member The member name.
2868 */
2869#define RT_UOFFSET_AFTER(a_Type, a_Member) ( RT_UOFFSETOF(a_Type, a_Member) + RT_SIZEOFMEMB(a_Type, a_Member) )
2870
2871/** @def RT_FROM_MEMBER
2872 * Convert a pointer to a structure member into a pointer to the structure.
2873 *
2874 * @returns pointer to the structure.
2875 * @param pMem Pointer to the member.
2876 * @param Type Structure type.
2877 * @param Member Member name.
2878 */
2879#define RT_FROM_MEMBER(pMem, Type, Member) ( (Type *) ((uint8_t *)(void *)(pMem) - RT_UOFFSETOF(Type, Member)) )
2880
2881/** @def RT_FROM_CPP_MEMBER
2882 * Same as RT_FROM_MEMBER except it avoids the annoying g++ warnings about
2883 * invalid access to non-static data member of NULL object.
2884 *
2885 * @returns pointer to the structure.
2886 * @param pMem Pointer to the member.
2887 * @param Type Structure type.
2888 * @param Member Member name.
2889 *
2890 * @remarks Using the __builtin_offsetof does not shut up the compiler.
2891 */
2892#if defined(__GNUC__) && defined(__cplusplus)
2893# define RT_FROM_CPP_MEMBER(pMem, Type, Member) \
2894 ( (Type *) ((uintptr_t)(pMem) - (uintptr_t)&((Type *)0x1000)->Member + 0x1000U) )
2895#else
2896# define RT_FROM_CPP_MEMBER(pMem, Type, Member) RT_FROM_MEMBER(pMem, Type, Member)
2897#endif
2898
2899/** @def RT_FROM_MEMBER_DYN
2900 * Convert a pointer to a structure member into a pointer to the structure.
2901 *
2902 * @returns pointer to the structure.
2903 * @param pMem Pointer to the member.
2904 * @param Type Structure type.
2905 * @param Member Member name dynamic size (some array is index by
2906 * non-constant value).
2907 */
2908#define RT_FROM_MEMBER_DYN(pMem, Type, Member) ( (Type *) ((uint8_t *)(void *)(pMem) - RT_UOFFSETOF_DYN(Type, Member)) )
2909
2910/** @def RT_ELEMENTS
2911 * Calculates the number of elements in a statically sized array.
2912 * @returns Element count.
2913 * @param aArray Array in question.
2914 */
2915#define RT_ELEMENTS(aArray) ( sizeof(aArray) / sizeof((aArray)[0]) )
2916
2917/** @def RT_SAFE_SUBSCRIPT
2918 * Safe array subscript using modulo and size_t cast.
2919 * @param a_Array The array.
2920 * @param a_idx The array index, cast to size_t to ensure unsigned.
2921 */
2922#define RT_SAFE_SUBSCRIPT(a_Array, a_idx) (a_Array)[(size_t)(a_idx) % RT_ELEMENTS(a_Array)]
2923
2924/** @def RT_SAFE_SUBSCRIPT32
2925 * Safe array subscript using modulo and uint32_t cast.
2926 * @param a_Array The array.
2927 * @param a_idx The array index, cast to size_t to ensure unsigned.
2928 * @note Only consider using this if array size is not power of two.
2929 */
2930#define RT_SAFE_SUBSCRIPT32(a_Array, a_idx) (a_Array)[(uint32_t)(a_idx) % RT_ELEMENTS(a_Array)]
2931
2932/** @def RT_SAFE_SUBSCRIPT16
2933 * Safe array subscript using modulo and uint16_t cast.
2934 * @param a_Array The array.
2935 * @param a_idx The array index, cast to size_t to ensure unsigned.
2936 * @note Only consider using this if array size is not power of two.
2937 */
2938#define RT_SAFE_SUBSCRIPT16(a_Array, a_idx) (a_Array)[(uint16_t)(a_idx) % RT_ELEMENTS(a_Array)]
2939
2940/** @def RT_SAFE_SUBSCRIPT8
2941 * Safe array subscript using modulo and uint8_t cast.
2942 * @param a_Array The array.
2943 * @param a_idx The array index, cast to size_t to ensure unsigned.
2944 * @note Only consider using this if array size is not power of two.
2945 */
2946#define RT_SAFE_SUBSCRIPT8(a_Array, a_idx) (a_Array)[(uint8_t)(a_idx) % RT_ELEMENTS(a_Array)]
2947
2948/** @def RT_SAFE_SUBSCRIPT_NC
2949 * Safe array subscript using modulo but no cast.
2950 * @param a_Array The array.
2951 * @param a_idx The array index - assumes unsigned type.
2952 * @note Only consider using this if array size is not power of two.
2953 */
2954#define RT_SAFE_SUBSCRIPT_NC(a_Array, a_idx) (a_Array)[(a_idx) % RT_ELEMENTS(a_Array)]
2955
2956/** @def RT_FLEXIBLE_ARRAY
2957 * What to up inside the square brackets when declaring a structure member
2958 * with a flexible size.
2959 *
2960 * @note RT_FLEXIBLE_ARRAY_EXTENSION must always preceed the type, unless
2961 * it's C-only code.
2962 *
2963 * @note Use RT_UOFFSETOF() to calculate the structure size.
2964 *
2965 * @note Never do a sizeof() on the structure or member!
2966 *
2967 * @note The member must be the last one.
2968 *
2969 * @note GCC does not permit using this in a union. So, for unions you must
2970 * use RT_FLEXIBLE_ARRAY_IN_UNION instead.
2971 *
2972 * @note GCC does not permit using this in nested structures, where as MSC
2973 * does. So, use RT_FLEXIBLE_ARRAY_NESTED for that.
2974 *
2975 * @sa RT_FLEXIBLE_ARRAY_NESTED, RT_FLEXIBLE_ARRAY_IN_UNION
2976 */
2977#if RT_MSC_PREREQ(RT_MSC_VER_VS2005) /** @todo Probably much much earlier. */ \
2978 || (defined(__cplusplus) && RT_GNUC_PREREQ(6, 1)) /* not tested 7.x, but hope it works with __extension__ too. */ \
2979 || defined(__WATCOMC__) /* openwatcom 1.9 supports it, we don't care about older atm. */ \
2980 || RT_CLANG_PREREQ_EX(3, 4, 0) /* Only tested clang v3.4, support is probably older. */
2981# define RT_FLEXIBLE_ARRAY
2982# if defined(__cplusplus) && defined(_MSC_VER)
2983# pragma warning(disable:4200) /* -wd4200 does not work with VS2010 */
2984# pragma warning(disable:4815) /* -wd4815 does not work with VS2019 */
2985# endif
2986#elif defined(__STDC_VERSION__)
2987# if __STDC_VERSION__ >= 1999901L
2988# define RT_FLEXIBLE_ARRAY
2989# else
2990# define RT_FLEXIBLE_ARRAY 1
2991# endif
2992#else
2993# define RT_FLEXIBLE_ARRAY 1
2994#endif
2995
2996/** @def RT_FLEXIBLE_ARRAY_EXTENSION
2997 * A trick to make GNU C++ quietly accept flexible arrays in C++ code when
2998 * pedantic warnings are enabled. Put this on the line before the flexible
2999 * array. */
3000#if (RT_GNUC_PREREQ(7, 0) && defined(__cplusplus)) || defined(DOXGYEN_RUNNING)
3001# define RT_FLEXIBLE_ARRAY_EXTENSION RT_GCC_EXTENSION
3002#else
3003# define RT_FLEXIBLE_ARRAY_EXTENSION
3004#endif
3005
3006/** @def RT_FLEXIBLE_ARRAY_NESTED
3007 * Variant of RT_FLEXIBLE_ARRAY for use in structures that are nested.
3008 *
3009 * GCC only allow the use of flexible array member in the top structure, whereas
3010 * MSC is less strict and let you do struct { struct { char szName[]; } s; };
3011 *
3012 * @note See notes for RT_FLEXIBLE_ARRAY.
3013 *
3014 * @note GCC does not permit using this in a union. So, for unions you must
3015 * use RT_FLEXIBLE_ARRAY_IN_NESTED_UNION instead.
3016 *
3017 * @sa RT_FLEXIBLE_ARRAY, RT_FLEXIBLE_ARRAY_IN_NESTED_UNION
3018 */
3019#ifdef _MSC_VER
3020# define RT_FLEXIBLE_ARRAY_NESTED RT_FLEXIBLE_ARRAY
3021#else
3022# define RT_FLEXIBLE_ARRAY_NESTED 1
3023#endif
3024
3025/** @def RT_FLEXIBLE_ARRAY_IN_UNION
3026 * The union version of RT_FLEXIBLE_ARRAY.
3027 *
3028 * @remarks GCC does not support flexible array members in unions, 6.1.x
3029 * actively checks for this. Visual C++ 2010 seems happy with it.
3030 *
3031 * @note See notes for RT_FLEXIBLE_ARRAY.
3032 *
3033 * @sa RT_FLEXIBLE_ARRAY, RT_FLEXIBLE_ARRAY_IN_NESTED_UNION
3034 */
3035#ifdef _MSC_VER
3036# define RT_FLEXIBLE_ARRAY_IN_UNION RT_FLEXIBLE_ARRAY
3037#else
3038# define RT_FLEXIBLE_ARRAY_IN_UNION 1
3039#endif
3040
3041/** @def RT_FLEXIBLE_ARRAY_IN_NESTED_UNION
3042 * The union version of RT_FLEXIBLE_ARRAY_NESTED.
3043 *
3044 * @note See notes for RT_FLEXIBLE_ARRAY.
3045 *
3046 * @sa RT_FLEXIBLE_ARRAY, RT_FLEXIBLE_ARRAY_IN_NESTED_UNION
3047 */
3048#ifdef _MSC_VER
3049# define RT_FLEXIBLE_ARRAY_IN_NESTED_UNION RT_FLEXIBLE_ARRAY_NESTED
3050#else
3051# define RT_FLEXIBLE_ARRAY_IN_NESTED_UNION 1
3052#endif
3053
3054/** @def RT_UNION_NM
3055 * For compilers (like DTrace) that does not grok nameless unions, we have a
3056 * little hack to make them palatable.
3057 */
3058/** @def RT_STRUCT_NM
3059 * For compilers (like DTrace) that does not grok nameless structs (it is
3060 * non-standard C++), we have a little hack to make them palatable.
3061 */
3062#ifdef IPRT_WITHOUT_NAMED_UNIONS_AND_STRUCTS
3063# define RT_UNION_NM(a_Nm) a_Nm
3064# define RT_STRUCT_NM(a_Nm) a_Nm
3065#else
3066# define RT_UNION_NM(a_Nm)
3067# define RT_STRUCT_NM(a_Nm)
3068#endif
3069
3070/**
3071 * Checks if the value is a power of two.
3072 *
3073 * @returns true if power of two, false if not.
3074 * @param uVal The value to test.
3075 * @remarks 0 is a power of two.
3076 * @see VERR_NOT_POWER_OF_TWO
3077 */
3078#define RT_IS_POWER_OF_TWO(uVal) ( ((uVal) & ((uVal) - 1)) == 0)
3079
3080#ifdef RT_OS_OS2
3081/* Undefine RT_MAX since there is an unfortunate clash with the max
3082 resource type define in os2.h. */
3083# undef RT_MAX
3084#endif
3085
3086/** @def RT_MAX
3087 * Finds the maximum value.
3088 * @returns The higher of the two.
3089 * @param Value1 Value 1
3090 * @param Value2 Value 2
3091 */
3092#define RT_MAX(Value1, Value2) ( (Value1) >= (Value2) ? (Value1) : (Value2) )
3093
3094/** @def RT_MIN
3095 * Finds the minimum value.
3096 * @returns The lower of the two.
3097 * @param Value1 Value 1
3098 * @param Value2 Value 2
3099 */
3100#define RT_MIN(Value1, Value2) ( (Value1) <= (Value2) ? (Value1) : (Value2) )
3101
3102/** @def RT_CLAMP
3103 * Clamps the value to minimum and maximum values.
3104 * @returns The clamped value.
3105 * @param Value The value to check.
3106 * @param Min Minimum value.
3107 * @param Max Maximum value.
3108 */
3109#define RT_CLAMP(Value, Min, Max) ( (Value) > (Max) ? (Max) : (Value) < (Min) ? (Min) : (Value) )
3110
3111/** @def RT_ABS
3112 * Get the absolute (non-negative) value.
3113 * @returns The absolute value of Value.
3114 * @param Value The value.
3115 */
3116#define RT_ABS(Value) ( (Value) >= 0 ? (Value) : -(Value) )
3117
3118/** @def RT_BOOL
3119 * Turn non-zero/zero into true/false
3120 * @returns The resulting boolean value.
3121 * @param Value The value.
3122 */
3123#define RT_BOOL(Value) ( !!(Value) )
3124
3125/** @def RT_LO_U8
3126 * Gets the low uint8_t of a uint16_t or something equivalent. */
3127#ifdef __GNUC__
3128# define RT_LO_U8(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint16_t)); (uint8_t)(a); })
3129#elif defined(_MSC_VER) /* shut up cast truncates constant value warnings */
3130# define RT_LO_U8(a) ( (uint8_t)(UINT8_MAX & (a)) )
3131#else
3132# define RT_LO_U8(a) ( (uint8_t)(a) )
3133#endif
3134/** @def RT_HI_U8
3135 * Gets the high uint8_t of a uint16_t or something equivalent. */
3136#ifdef __GNUC__
3137# define RT_HI_U8(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint16_t)); (uint8_t)((a) >> 8); })
3138#else
3139# define RT_HI_U8(a) ( (uint8_t)((a) >> 8) )
3140#endif
3141
3142/** @def RT_LO_U16
3143 * Gets the low uint16_t of a uint32_t or something equivalent. */
3144#ifdef __GNUC__
3145# define RT_LO_U16(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint32_t)); (uint16_t)(a); })
3146#elif defined(_MSC_VER) /* shut up cast truncates constant value warnings */
3147# define RT_LO_U16(a) ( (uint16_t)(UINT16_MAX & (a)) )
3148#else
3149# define RT_LO_U16(a) ( (uint16_t)(a) )
3150#endif
3151/** @def RT_HI_U16
3152 * Gets the high uint16_t of a uint32_t or something equivalent. */
3153#ifdef __GNUC__
3154# define RT_HI_U16(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint32_t)); (uint16_t)((a) >> 16); })
3155#else
3156# define RT_HI_U16(a) ( (uint16_t)((a) >> 16) )
3157#endif
3158
3159/** @def RT_LO_U32
3160 * Gets the low uint32_t of a uint64_t or something equivalent. */
3161#ifdef __GNUC__
3162# define RT_LO_U32(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint64_t)); (uint32_t)(a); })
3163#elif defined(_MSC_VER) /* shut up cast truncates constant value warnings */
3164# define RT_LO_U32(a) ( (uint32_t)(UINT32_MAX & (a)) )
3165#else
3166# define RT_LO_U32(a) ( (uint32_t)(a) )
3167#endif
3168/** @def RT_HI_U32
3169 * Gets the high uint32_t of a uint64_t or something equivalent. */
3170#ifdef __GNUC__
3171# define RT_HI_U32(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint64_t)); (uint32_t)((a) >> 32); })
3172#else
3173# define RT_HI_U32(a) ( (uint32_t)((a) >> 32) )
3174#endif
3175
3176/** @def RT_BYTE1
3177 * Gets the first byte of something. */
3178#define RT_BYTE1(a) ( (uint8_t)((a) & 0xff) )
3179/** @def RT_BYTE2
3180 * Gets the second byte of something. */
3181#define RT_BYTE2(a) ( (uint8_t)(((a) >> 8) & 0xff) )
3182/** @def RT_BYTE3
3183 * Gets the second byte of something. */
3184#define RT_BYTE3(a) ( (uint8_t)(((a) >> 16) & 0xff) )
3185/** @def RT_BYTE4
3186 * Gets the fourth byte of something. */
3187#define RT_BYTE4(a) ( (uint8_t)(((a) >> 24) & 0xff) )
3188/** @def RT_BYTE5
3189 * Gets the fifth byte of something. */
3190#define RT_BYTE5(a) ( (uint8_t)(((a) >> 32) & 0xff) )
3191/** @def RT_BYTE6
3192 * Gets the sixth byte of something. */
3193#define RT_BYTE6(a) ( (uint8_t)(((a) >> 40) & 0xff) )
3194/** @def RT_BYTE7
3195 * Gets the seventh byte of something. */
3196#define RT_BYTE7(a) ( (uint8_t)(((a) >> 48) & 0xff) )
3197/** @def RT_BYTE8
3198 * Gets the eight byte of something. */
3199#define RT_BYTE8(a) ( (uint8_t)(((a) >> 56) & 0xff) )
3200
3201
3202/** @def RT_LODWORD
3203 * Gets the low dword (=uint32_t) of something.
3204 * @deprecated Use RT_LO_U32. */
3205#define RT_LODWORD(a) ( (uint32_t)(a) )
3206/** @def RT_HIDWORD
3207 * Gets the high dword (=uint32_t) of a 64-bit of something.
3208 * @deprecated Use RT_HI_U32. */
3209#define RT_HIDWORD(a) ( (uint32_t)((a) >> 32) )
3210
3211/** @def RT_LOWORD
3212 * Gets the low word (=uint16_t) of something.
3213 * @deprecated Use RT_LO_U16. */
3214#define RT_LOWORD(a) ( (a) & 0xffff )
3215/** @def RT_HIWORD
3216 * Gets the high word (=uint16_t) of a 32-bit something.
3217 * @deprecated Use RT_HI_U16. */
3218#define RT_HIWORD(a) ( (a) >> 16 )
3219
3220/** @def RT_LOBYTE
3221 * Gets the low byte of something.
3222 * @deprecated Use RT_LO_U8. */
3223#define RT_LOBYTE(a) ( (a) & 0xff )
3224/** @def RT_HIBYTE
3225 * Gets the high byte of a 16-bit something.
3226 * @deprecated Use RT_HI_U8. */
3227#define RT_HIBYTE(a) ( (a) >> 8 )
3228
3229
3230/** @def RT_MAKE_U64
3231 * Constructs a uint64_t value from two uint32_t values.
3232 */
3233#define RT_MAKE_U64(Lo, Hi) ( (uint64_t)((uint32_t)(Hi)) << 32 | (uint32_t)(Lo) )
3234
3235/** @def RT_MAKE_U64_FROM_U16
3236 * Constructs a uint64_t value from four uint16_t values.
3237 */
3238#define RT_MAKE_U64_FROM_U16(w0, w1, w2, w3) \
3239 ((uint64_t)( (uint64_t)((uint16_t)(w3)) << 48 \
3240 | (uint64_t)((uint16_t)(w2)) << 32 \
3241 | (uint32_t)((uint16_t)(w1)) << 16 \
3242 | (uint16_t)(w0) ))
3243
3244/** @def RT_MAKE_U64_FROM_U8
3245 * Constructs a uint64_t value from eight uint8_t values.
3246 */
3247#define RT_MAKE_U64_FROM_U8(b0, b1, b2, b3, b4, b5, b6, b7) \
3248 ((uint64_t)( (uint64_t)((uint8_t)(b7)) << 56 \
3249 | (uint64_t)((uint8_t)(b6)) << 48 \
3250 | (uint64_t)((uint8_t)(b5)) << 40 \
3251 | (uint64_t)((uint8_t)(b4)) << 32 \
3252 | (uint64_t)((uint8_t)(b3)) << 24 \
3253 | (uint64_t)((uint8_t)(b2)) << 16 \
3254 | (uint64_t)((uint8_t)(b1)) << 8 \
3255 | (uint64_t) (uint8_t)(b0) ))
3256
3257/** @def RT_MAKE_U32
3258 * Constructs a uint32_t value from two uint16_t values.
3259 */
3260#define RT_MAKE_U32(Lo, Hi) \
3261 ((uint32_t)( (uint32_t)((uint16_t)(Hi)) << 16 \
3262 | (uint16_t)(Lo) ))
3263
3264/** @def RT_MAKE_U32_FROM_U8
3265 * Constructs a uint32_t value from four uint8_t values.
3266 */
3267#define RT_MAKE_U32_FROM_U8(b0, b1, b2, b3) \
3268 ((uint32_t)( (uint32_t)((uint8_t)(b3)) << 24 \
3269 | (uint32_t)((uint8_t)(b2)) << 16 \
3270 | (uint32_t)((uint8_t)(b1)) << 8 \
3271 | (uint8_t)(b0) ))
3272
3273/** @def RT_MAKE_U16
3274 * Constructs a uint16_t value from two uint8_t values.
3275 */
3276#define RT_MAKE_U16(Lo, Hi) \
3277 ((uint16_t)( (uint16_t)((uint8_t)(Hi)) << 8 \
3278 | (uint8_t)(Lo) ))
3279
3280
3281/** @def RT_BSWAP_U64
3282 * Reverses the byte order of an uint64_t value. */
3283#if defined(__GNUC__)
3284# define RT_BSWAP_U64(u64) (__builtin_constant_p((u64)) ? RT_BSWAP_U64_C(u64) : ASMByteSwapU64(u64))
3285#else
3286# define RT_BSWAP_U64(u64) ASMByteSwapU64(u64)
3287#endif
3288
3289/** @def RT_BSWAP_U32
3290 * Reverses the byte order of an uint32_t value. */
3291#if defined(__GNUC__)
3292# define RT_BSWAP_U32(u32) (__builtin_constant_p((u32)) ? RT_BSWAP_U32_C(u32) : ASMByteSwapU32(u32))
3293#else
3294# define RT_BSWAP_U32(u32) ASMByteSwapU32(u32)
3295#endif
3296
3297/** @def RT_BSWAP_U16
3298 * Reverses the byte order of an uint16_t value. */
3299#if defined(__GNUC__)
3300# define RT_BSWAP_U16(u16) (__builtin_constant_p((u16)) ? RT_BSWAP_U16_C(u16) : ASMByteSwapU16(u16))
3301#else
3302# define RT_BSWAP_U16(u16) ASMByteSwapU16(u16)
3303#endif
3304
3305/** @def RT_BSWAP_S64
3306 * Reverses the byte order of an int64_t value. */
3307#define RT_BSWAP_S64(i64) ((int64_t)RT_BSWAP_U64((uint64_t)i64))
3308
3309/** @def RT_BSWAP_S32
3310 * Reverses the byte order of an int32_t value. */
3311#define RT_BSWAP_S32(i32) ((int32_t)RT_BSWAP_U32((uint32_t)i32))
3312
3313/** @def RT_BSWAP_S16
3314 * Reverses the byte order of an int16_t value. */
3315#define RT_BSWAP_S16(i16) ((int16_t)RT_BSWAP_U16((uint16_t)i16))
3316
3317
3318/** @def RT_BSWAP_U64_C
3319 * Reverses the byte order of an uint64_t constant. */
3320#define RT_BSWAP_U64_C(u64) RT_MAKE_U64(RT_BSWAP_U32_C((u64) >> 32), RT_BSWAP_U32_C((u64) & 0xffffffff))
3321
3322/** @def RT_BSWAP_U32_C
3323 * Reverses the byte order of an uint32_t constant. */
3324#define RT_BSWAP_U32_C(u32) RT_MAKE_U32_FROM_U8(RT_BYTE4(u32), RT_BYTE3(u32), RT_BYTE2(u32), RT_BYTE1(u32))
3325
3326/** @def RT_BSWAP_U16_C
3327 * Reverses the byte order of an uint16_t constant. */
3328#define RT_BSWAP_U16_C(u16) RT_MAKE_U16(RT_HIBYTE(u16), RT_LOBYTE(u16))
3329
3330/** @def RT_BSWAP_S64_C
3331 * Reverses the byte order of an int64_t constant. */
3332#define RT_BSWAP_S64_C(i64) ((int64_t)RT_MAKE_U64(RT_BSWAP_U32_C((uint64_t)(i64) >> 32), RT_BSWAP_U32_C((uint32_t)(i64))))
3333
3334/** @def RT_BSWAP_S32_C
3335 * Reverses the byte order of an int32_t constant. */
3336#define RT_BSWAP_S32_C(i32) ((int32_t)RT_MAKE_U32_FROM_U8(RT_BYTE4(i32), RT_BYTE3(i32), RT_BYTE2(i32), RT_BYTE1(i)))
3337
3338/** @def RT_BSWAP_S16_C
3339 * Reverses the byte order of an uint16_t constant. */
3340#define RT_BSWAP_S16_C(i16) ((int16_t)RT_MAKE_U16(RT_HIBYTE(i16), RT_LOBYTE(i16)))
3341
3342
3343
3344/** @name Host to/from little endian.
3345 * @note Typically requires iprt/asm.h to be included.
3346 * @{ */
3347
3348/** @def RT_H2LE_U64
3349 * Converts an uint64_t value from host to little endian byte order. */
3350#ifdef RT_BIG_ENDIAN
3351# define RT_H2LE_U64(u64) RT_BSWAP_U64(u64)
3352#else
3353# define RT_H2LE_U64(u64) (u64)
3354#endif
3355
3356/** @def RT_H2LE_U64_C
3357 * Converts an uint64_t constant from host to little endian byte order. */
3358#ifdef RT_BIG_ENDIAN
3359# define RT_H2LE_U64_C(u64) RT_BSWAP_U64_C(u64)
3360#else
3361# define RT_H2LE_U64_C(u64) (u64)
3362#endif
3363
3364/** @def RT_H2LE_U32
3365 * Converts an uint32_t value from host to little endian byte order. */
3366#ifdef RT_BIG_ENDIAN
3367# define RT_H2LE_U32(u32) RT_BSWAP_U32(u32)
3368#else
3369# define RT_H2LE_U32(u32) (u32)
3370#endif
3371
3372/** @def RT_H2LE_U32_C
3373 * Converts an uint32_t constant from host to little endian byte order. */
3374#ifdef RT_BIG_ENDIAN
3375# define RT_H2LE_U32_C(u32) RT_BSWAP_U32_C(u32)
3376#else
3377# define RT_H2LE_U32_C(u32) (u32)
3378#endif
3379
3380/** @def RT_H2LE_U16
3381 * Converts an uint16_t value from host to little endian byte order. */
3382#ifdef RT_BIG_ENDIAN
3383# define RT_H2LE_U16(u16) RT_BSWAP_U16(u16)
3384#else
3385# define RT_H2LE_U16(u16) (u16)
3386#endif
3387
3388/** @def RT_H2LE_U16_C
3389 * Converts an uint16_t constant from host to little endian byte order. */
3390#ifdef RT_BIG_ENDIAN
3391# define RT_H2LE_U16_C(u16) RT_BSWAP_U16_C(u16)
3392#else
3393# define RT_H2LE_U16_C(u16) (u16)
3394#endif
3395
3396
3397/** @def RT_LE2H_U64
3398 * Converts an uint64_t value from little endian to host byte order. */
3399#ifdef RT_BIG_ENDIAN
3400# define RT_LE2H_U64(u64) RT_BSWAP_U64(u64)
3401#else
3402# define RT_LE2H_U64(u64) (u64)
3403#endif
3404
3405/** @def RT_LE2H_U64_C
3406 * Converts an uint64_t constant from little endian to host byte order. */
3407#ifdef RT_BIG_ENDIAN
3408# define RT_LE2H_U64_C(u64) RT_BSWAP_U64_C(u64)
3409#else
3410# define RT_LE2H_U64_C(u64) (u64)
3411#endif
3412
3413/** @def RT_LE2H_U32
3414 * Converts an uint32_t value from little endian to host byte order. */
3415#ifdef RT_BIG_ENDIAN
3416# define RT_LE2H_U32(u32) RT_BSWAP_U32(u32)
3417#else
3418# define RT_LE2H_U32(u32) (u32)
3419#endif
3420
3421/** @def RT_LE2H_U32_C
3422 * Converts an uint32_t constant from little endian to host byte order. */
3423#ifdef RT_BIG_ENDIAN
3424# define RT_LE2H_U32_C(u32) RT_BSWAP_U32_C(u32)
3425#else
3426# define RT_LE2H_U32_C(u32) (u32)
3427#endif
3428
3429/** @def RT_LE2H_U16
3430 * Converts an uint16_t value from little endian to host byte order. */
3431#ifdef RT_BIG_ENDIAN
3432# define RT_LE2H_U16(u16) RT_BSWAP_U16(u16)
3433#else
3434# define RT_LE2H_U16(u16) (u16)
3435#endif
3436
3437/** @def RT_LE2H_U16_C
3438 * Converts an uint16_t constant from little endian to host byte order. */
3439#ifdef RT_BIG_ENDIAN
3440# define RT_LE2H_U16_C(u16) RT_BSWAP_U16_C(u16)
3441#else
3442# define RT_LE2H_U16_C(u16) (u16)
3443#endif
3444
3445/** @def RT_H2LE_S64
3446 * Converts an int64_t value from host to little endian byte order. */
3447#ifdef RT_BIG_ENDIAN
3448# define RT_H2LE_S64(i64) RT_BSWAP_S64(i64)
3449#else
3450# define RT_H2LE_S64(i64) (i64)
3451#endif
3452
3453/** @def RT_H2LE_S64_C
3454 * Converts an int64_t constant from host to little endian byte order. */
3455#ifdef RT_BIG_ENDIAN
3456# define RT_H2LE_S64_C(i64) RT_BSWAP_S64_C(i64)
3457#else
3458# define RT_H2LE_S64_C(i64) (i64)
3459#endif
3460
3461/** @def RT_H2LE_S32
3462 * Converts an int32_t value from host to little endian byte order. */
3463#ifdef RT_BIG_ENDIAN
3464# define RT_H2LE_S32(i32) RT_BSWAP_S32(i32)
3465#else
3466# define RT_H2LE_S32(i32) (i32)
3467#endif
3468
3469/** @def RT_H2LE_S32_C
3470 * Converts an int32_t constant from host to little endian byte order. */
3471#ifdef RT_BIG_ENDIAN
3472# define RT_H2LE_S32_C(i32) RT_BSWAP_S32_C(i32)
3473#else
3474# define RT_H2LE_S32_C(i32) (i32)
3475#endif
3476
3477/** @def RT_H2LE_S16
3478 * Converts an int16_t value from host to little endian byte order. */
3479#ifdef RT_BIG_ENDIAN
3480# define RT_H2LE_S16(i16) RT_BSWAP_S16(i16)
3481#else
3482# define RT_H2LE_S16(i16) (i16)
3483#endif
3484
3485/** @def RT_H2LE_S16_C
3486 * Converts an int16_t constant from host to little endian byte order. */
3487#ifdef RT_BIG_ENDIAN
3488# define RT_H2LE_S16_C(i16) RT_BSWAP_S16_C(i16)
3489#else
3490# define RT_H2LE_S16_C(i16) (i16)
3491#endif
3492
3493/** @def RT_LE2H_S64
3494 * Converts an int64_t value from little endian to host byte order. */
3495#ifdef RT_BIG_ENDIAN
3496# define RT_LE2H_S64(i64) RT_BSWAP_S64(i64)
3497#else
3498# define RT_LE2H_S64(i64) (i64)
3499#endif
3500
3501/** @def RT_LE2H_S64_C
3502 * Converts an int64_t constant from little endian to host byte order. */
3503#ifdef RT_BIG_ENDIAN
3504# define RT_LE2H_S64_C(i64) RT_BSWAP_S64_C(i64)
3505#else
3506# define RT_LE2H_S64_C(i64) (i64)
3507#endif
3508
3509/** @def RT_LE2H_S32
3510 * Converts an int32_t value from little endian to host byte order. */
3511#ifdef RT_BIG_ENDIAN
3512# define RT_LE2H_S32(i32) RT_BSWAP_S32(i32)
3513#else
3514# define RT_LE2H_S32(i32) (i32)
3515#endif
3516
3517/** @def RT_LE2H_S32_C
3518 * Converts an int32_t constant from little endian to host byte order. */
3519#ifdef RT_BIG_ENDIAN
3520# define RT_LE2H_S32_C(i32) RT_BSWAP_S32_C(i32)
3521#else
3522# define RT_LE2H_S32_C(i32) (i32)
3523#endif
3524
3525/** @def RT_LE2H_S16
3526 * Converts an int16_t value from little endian to host byte order. */
3527#ifdef RT_BIG_ENDIAN
3528# define RT_LE2H_S16(i16) RT_BSWAP_S16(i16)
3529#else
3530# define RT_LE2H_S16(i16) (i16)
3531#endif
3532
3533/** @def RT_LE2H_S16_C
3534 * Converts an int16_t constant from little endian to host byte order. */
3535#ifdef RT_BIG_ENDIAN
3536# define RT_LE2H_S16_C(i16) RT_BSWAP_S16_C(i16)
3537#else
3538# define RT_LE2H_S16_C(i16) (i16)
3539#endif
3540
3541/** @} */
3542
3543/** @name Host to/from big endian.
3544 * @note Typically requires iprt/asm.h to be included.
3545 * @{ */
3546
3547/** @def RT_H2BE_U64
3548 * Converts an uint64_t value from host to big endian byte order. */
3549#ifdef RT_BIG_ENDIAN
3550# define RT_H2BE_U64(u64) (u64)
3551#else
3552# define RT_H2BE_U64(u64) RT_BSWAP_U64(u64)
3553#endif
3554
3555/** @def RT_H2BE_U64_C
3556 * Converts an uint64_t constant from host to big endian byte order. */
3557#ifdef RT_BIG_ENDIAN
3558# define RT_H2BE_U64_C(u64) (u64)
3559#else
3560# define RT_H2BE_U64_C(u64) RT_BSWAP_U64_C(u64)
3561#endif
3562
3563/** @def RT_H2BE_U32
3564 * Converts an uint32_t value from host to big endian byte order. */
3565#ifdef RT_BIG_ENDIAN
3566# define RT_H2BE_U32(u32) (u32)
3567#else
3568# define RT_H2BE_U32(u32) RT_BSWAP_U32(u32)
3569#endif
3570
3571/** @def RT_H2BE_U32_C
3572 * Converts an uint32_t constant from host to big endian byte order. */
3573#ifdef RT_BIG_ENDIAN
3574# define RT_H2BE_U32_C(u32) (u32)
3575#else
3576# define RT_H2BE_U32_C(u32) RT_BSWAP_U32_C(u32)
3577#endif
3578
3579/** @def RT_H2BE_U16
3580 * Converts an uint16_t value from host to big endian byte order. */
3581#ifdef RT_BIG_ENDIAN
3582# define RT_H2BE_U16(u16) (u16)
3583#else
3584# define RT_H2BE_U16(u16) RT_BSWAP_U16(u16)
3585#endif
3586
3587/** @def RT_H2BE_U16_C
3588 * Converts an uint16_t constant from host to big endian byte order. */
3589#ifdef RT_BIG_ENDIAN
3590# define RT_H2BE_U16_C(u16) (u16)
3591#else
3592# define RT_H2BE_U16_C(u16) RT_BSWAP_U16_C(u16)
3593#endif
3594
3595/** @def RT_BE2H_U64
3596 * Converts an uint64_t value from big endian to host byte order. */
3597#ifdef RT_BIG_ENDIAN
3598# define RT_BE2H_U64(u64) (u64)
3599#else
3600# define RT_BE2H_U64(u64) RT_BSWAP_U64(u64)
3601#endif
3602
3603/** @def RT_BE2H_U64
3604 * Converts an uint64_t constant from big endian to host byte order. */
3605#ifdef RT_BIG_ENDIAN
3606# define RT_BE2H_U64_C(u64) (u64)
3607#else
3608# define RT_BE2H_U64_C(u64) RT_BSWAP_U64_C(u64)
3609#endif
3610
3611/** @def RT_BE2H_U32
3612 * Converts an uint32_t value from big endian to host byte order. */
3613#ifdef RT_BIG_ENDIAN
3614# define RT_BE2H_U32(u32) (u32)
3615#else
3616# define RT_BE2H_U32(u32) RT_BSWAP_U32(u32)
3617#endif
3618
3619/** @def RT_BE2H_U32_C
3620 * Converts an uint32_t value from big endian to host byte order. */
3621#ifdef RT_BIG_ENDIAN
3622# define RT_BE2H_U32_C(u32) (u32)
3623#else
3624# define RT_BE2H_U32_C(u32) RT_BSWAP_U32_C(u32)
3625#endif
3626
3627/** @def RT_BE2H_U16
3628 * Converts an uint16_t value from big endian to host byte order. */
3629#ifdef RT_BIG_ENDIAN
3630# define RT_BE2H_U16(u16) (u16)
3631#else
3632# define RT_BE2H_U16(u16) RT_BSWAP_U16(u16)
3633#endif
3634
3635/** @def RT_BE2H_U16_C
3636 * Converts an uint16_t constant from big endian to host byte order. */
3637#ifdef RT_BIG_ENDIAN
3638# define RT_BE2H_U16_C(u16) (u16)
3639#else
3640# define RT_BE2H_U16_C(u16) RT_BSWAP_U16_C(u16)
3641#endif
3642
3643/** @def RT_H2BE_S64
3644 * Converts an int64_t value from host to big endian byte order. */
3645#ifdef RT_BIG_ENDIAN
3646# define RT_H2BE_S64(i64) (i64)
3647#else
3648# define RT_H2BE_S64(i64) RT_BSWAP_S64(i64)
3649#endif
3650
3651/** @def RT_H2BE_S64_C
3652 * Converts an int64_t constant from host to big endian byte order. */
3653#ifdef RT_BIG_ENDIAN
3654# define RT_H2BE_S64_C(i64) (i64)
3655#else
3656# define RT_H2BE_S64_C(i64) RT_BSWAP_S64_C(i64)
3657#endif
3658
3659/** @def RT_H2BE_S32
3660 * Converts an int32_t value from host to big endian byte order. */
3661#ifdef RT_BIG_ENDIAN
3662# define RT_H2BE_S32(i32) (i32)
3663#else
3664# define RT_H2BE_S32(i32) RT_BSWAP_S32(i32)
3665#endif
3666
3667/** @def RT_H2BE_S32_C
3668 * Converts an int32_t constant from host to big endian byte order. */
3669#ifdef RT_BIG_ENDIAN
3670# define RT_H2BE_S32_C(i32) (i32)
3671#else
3672# define RT_H2BE_S32_C(i32) RT_BSWAP_S32_C(i32)
3673#endif
3674
3675/** @def RT_H2BE_S16
3676 * Converts an int16_t value from host to big endian byte order. */
3677#ifdef RT_BIG_ENDIAN
3678# define RT_H2BE_S16(i16) (i16)
3679#else
3680# define RT_H2BE_S16(i16) RT_BSWAP_S16(i16)
3681#endif
3682
3683/** @def RT_H2BE_S16_C
3684 * Converts an int16_t constant from host to big endian byte order. */
3685#ifdef RT_BIG_ENDIAN
3686# define RT_H2BE_S16_C(i16) (i16)
3687#else
3688# define RT_H2BE_S16_C(i16) RT_BSWAP_S16_C(i16)
3689#endif
3690
3691/** @def RT_BE2H_S64
3692 * Converts an int64_t value from big endian to host byte order. */
3693#ifdef RT_BIG_ENDIAN
3694# define RT_BE2H_S64(i64) (i64)
3695#else
3696# define RT_BE2H_S64(i64) RT_BSWAP_S64(i64)
3697#endif
3698
3699/** @def RT_BE2H_S64
3700 * Converts an int64_t constant from big endian to host byte order. */
3701#ifdef RT_BIG_ENDIAN
3702# define RT_BE2H_S64_C(i64) (i64)
3703#else
3704# define RT_BE2H_S64_C(i64) RT_BSWAP_S64_C(i64)
3705#endif
3706
3707/** @def RT_BE2H_S32
3708 * Converts an int32_t value from big endian to host byte order. */
3709#ifdef RT_BIG_ENDIAN
3710# define RT_BE2H_S32(i32) (i32)
3711#else
3712# define RT_BE2H_S32(i32) RT_BSWAP_S32(i32)
3713#endif
3714
3715/** @def RT_BE2H_S32_C
3716 * Converts an int32_t value from big endian to host byte order. */
3717#ifdef RT_BIG_ENDIAN
3718# define RT_BE2H_S32_C(i32) (i32)
3719#else
3720# define RT_BE2H_S32_C(i32) RT_BSWAP_S32_C(i32)
3721#endif
3722
3723/** @def RT_BE2H_S16
3724 * Converts an int16_t value from big endian to host byte order. */
3725#ifdef RT_BIG_ENDIAN
3726# define RT_BE2H_S16(i16) (i16)
3727#else
3728# define RT_BE2H_S16(i16) RT_BSWAP_S16(i16)
3729#endif
3730
3731/** @def RT_BE2H_S16_C
3732 * Converts an int16_t constant from big endian to host byte order. */
3733#ifdef RT_BIG_ENDIAN
3734# define RT_BE2H_S16_C(i16) (i16)
3735#else
3736# define RT_BE2H_S16_C(i16) RT_BSWAP_S16_C(i16)
3737#endif
3738/** @} */
3739
3740/** @name Host to/from network byte order.
3741 * @note Typically requires iprt/asm.h to be included.
3742 * @{ */
3743
3744/** @def RT_H2N_U64
3745 * Converts an uint64_t value from host to network byte order. */
3746#define RT_H2N_U64(u64) RT_H2BE_U64(u64)
3747
3748/** @def RT_H2N_U64_C
3749 * Converts an uint64_t constant from host to network byte order. */
3750#define RT_H2N_U64_C(u64) RT_H2BE_U64_C(u64)
3751
3752/** @def RT_H2N_U32
3753 * Converts an uint32_t value from host to network byte order. */
3754#define RT_H2N_U32(u32) RT_H2BE_U32(u32)
3755
3756/** @def RT_H2N_U32_C
3757 * Converts an uint32_t constant from host to network byte order. */
3758#define RT_H2N_U32_C(u32) RT_H2BE_U32_C(u32)
3759
3760/** @def RT_H2N_U16
3761 * Converts an uint16_t value from host to network byte order. */
3762#define RT_H2N_U16(u16) RT_H2BE_U16(u16)
3763
3764/** @def RT_H2N_U16_C
3765 * Converts an uint16_t constant from host to network byte order. */
3766#define RT_H2N_U16_C(u16) RT_H2BE_U16_C(u16)
3767
3768/** @def RT_N2H_U64
3769 * Converts an uint64_t value from network to host byte order. */
3770#define RT_N2H_U64(u64) RT_BE2H_U64(u64)
3771
3772/** @def RT_N2H_U64_C
3773 * Converts an uint64_t constant from network to host byte order. */
3774#define RT_N2H_U64_C(u64) RT_BE2H_U64_C(u64)
3775
3776/** @def RT_N2H_U32
3777 * Converts an uint32_t value from network to host byte order. */
3778#define RT_N2H_U32(u32) RT_BE2H_U32(u32)
3779
3780/** @def RT_N2H_U32_C
3781 * Converts an uint32_t constant from network to host byte order. */
3782#define RT_N2H_U32_C(u32) RT_BE2H_U32_C(u32)
3783
3784/** @def RT_N2H_U16
3785 * Converts an uint16_t value from network to host byte order. */
3786#define RT_N2H_U16(u16) RT_BE2H_U16(u16)
3787
3788/** @def RT_N2H_U16_C
3789 * Converts an uint16_t value from network to host byte order. */
3790#define RT_N2H_U16_C(u16) RT_BE2H_U16_C(u16)
3791
3792/** @def RT_H2N_S64
3793 * Converts an int64_t value from host to network byte order. */
3794#define RT_H2N_S64(i64) RT_H2BE_S64(i64)
3795
3796/** @def RT_H2N_S64_C
3797 * Converts an int64_t constant from host to network byte order. */
3798#define RT_H2N_S64_C(i64) RT_H2BE_S64_C(i64)
3799
3800/** @def RT_H2N_S32
3801 * Converts an int32_t value from host to network byte order. */
3802#define RT_H2N_S32(i32) RT_H2BE_S32(i32)
3803
3804/** @def RT_H2N_S32_C
3805 * Converts an int32_t constant from host to network byte order. */
3806#define RT_H2N_S32_C(i32) RT_H2BE_S32_C(i32)
3807
3808/** @def RT_H2N_S16
3809 * Converts an int16_t value from host to network byte order. */
3810#define RT_H2N_S16(i16) RT_H2BE_S16(i16)
3811
3812/** @def RT_H2N_S16_C
3813 * Converts an int16_t constant from host to network byte order. */
3814#define RT_H2N_S16_C(i16) RT_H2BE_S16_C(i16)
3815
3816/** @def RT_N2H_S64
3817 * Converts an int64_t value from network to host byte order. */
3818#define RT_N2H_S64(i64) RT_BE2H_S64(i64)
3819
3820/** @def RT_N2H_S64_C
3821 * Converts an int64_t constant from network to host byte order. */
3822#define RT_N2H_S64_C(i64) RT_BE2H_S64_C(i64)
3823
3824/** @def RT_N2H_S32
3825 * Converts an int32_t value from network to host byte order. */
3826#define RT_N2H_S32(i32) RT_BE2H_S32(i32)
3827
3828/** @def RT_N2H_S32_C
3829 * Converts an int32_t constant from network to host byte order. */
3830#define RT_N2H_S32_C(i32) RT_BE2H_S32_C(i32)
3831
3832/** @def RT_N2H_S16
3833 * Converts an int16_t value from network to host byte order. */
3834#define RT_N2H_S16(i16) RT_BE2H_S16(i16)
3835
3836/** @def RT_N2H_S16_C
3837 * Converts an int16_t value from network to host byte order. */
3838#define RT_N2H_S16_C(i16) RT_BE2H_S16_C(i16)
3839
3840/** @} */
3841
3842
3843/*
3844 * The BSD sys/param.h + machine/param.h file is a major source of
3845 * namespace pollution. Kill off some of the worse ones unless we're
3846 * compiling kernel code.
3847 */
3848#if defined(RT_OS_DARWIN) \
3849 && !defined(KERNEL) \
3850 && !defined(RT_NO_BSD_PARAM_H_UNDEFING) \
3851 && ( defined(_SYS_PARAM_H_) || defined(_I386_PARAM_H_) )
3852/* sys/param.h: */
3853# undef PSWP
3854# undef PVM
3855# undef PINOD
3856# undef PRIBO
3857# undef PVFS
3858# undef PZERO
3859# undef PSOCK
3860# undef PWAIT
3861# undef PLOCK
3862# undef PPAUSE
3863# undef PUSER
3864# undef PRIMASK
3865# undef MINBUCKET
3866# undef MAXALLOCSAVE
3867# undef FSHIFT
3868# undef FSCALE
3869
3870/* i386/machine.h: */
3871# undef ALIGN
3872# undef ALIGNBYTES
3873# undef DELAY
3874# undef STATUS_WORD
3875# undef USERMODE
3876# undef BASEPRI
3877# undef MSIZE
3878# undef CLSIZE
3879# undef CLSIZELOG2
3880#endif
3881
3882/** @def NIL_OFFSET
3883 * NIL offset.
3884 * Whenever we use offsets instead of pointers to save space and relocation effort
3885 * NIL_OFFSET shall be used as the equivalent to NULL.
3886 */
3887#define NIL_OFFSET (~0U)
3888
3889
3890/** @def NOREF
3891 * Keeps the compiler from bitching about an unused parameter, local variable,
3892 * or other stuff, will never use _Pragma are is thus more flexible.
3893 */
3894#define NOREF(var) (void)(var)
3895
3896/** @def RT_NOREF_PV
3897 * Keeps the compiler from bitching about an unused parameter or local variable.
3898 * This one cannot be used with structure members and such, like for instance
3899 * AssertRC may end up doing due to its generic nature.
3900 */
3901#if defined(__cplusplus) && RT_CLANG_PREREQ(6, 0)
3902# define RT_NOREF_PV(var) _Pragma(RT_STR(unused(var)))
3903#else
3904# define RT_NOREF_PV(var) (void)(var)
3905#endif
3906
3907/** @def RT_NOREF1
3908 * RT_NOREF_PV shorthand taking on parameter. */
3909#define RT_NOREF1(var1) RT_NOREF_PV(var1)
3910/** @def RT_NOREF2
3911 * RT_NOREF_PV shorthand taking two parameters. */
3912#define RT_NOREF2(var1, var2) RT_NOREF_PV(var1); RT_NOREF1(var2)
3913/** @def RT_NOREF3
3914 * RT_NOREF_PV shorthand taking three parameters. */
3915#define RT_NOREF3(var1, var2, var3) RT_NOREF_PV(var1); RT_NOREF2(var2, var3)
3916/** @def RT_NOREF4
3917 * RT_NOREF_PV shorthand taking four parameters. */
3918#define RT_NOREF4(var1, var2, var3, var4) RT_NOREF_PV(var1); RT_NOREF3(var2, var3, var4)
3919/** @def RT_NOREF5
3920 * RT_NOREF_PV shorthand taking five parameters. */
3921#define RT_NOREF5(var1, var2, var3, var4, var5) RT_NOREF_PV(var1); RT_NOREF4(var2, var3, var4, var5)
3922/** @def RT_NOREF6
3923 * RT_NOREF_PV shorthand taking six parameters. */
3924#define RT_NOREF6(var1, var2, var3, var4, var5, var6) RT_NOREF_PV(var1); RT_NOREF5(var2, var3, var4, var5, var6)
3925/** @def RT_NOREF7
3926 * RT_NOREF_PV shorthand taking seven parameters. */
3927#define RT_NOREF7(var1, var2, var3, var4, var5, var6, var7) \
3928 RT_NOREF_PV(var1); RT_NOREF6(var2, var3, var4, var5, var6, var7)
3929/** @def RT_NOREF8
3930 * RT_NOREF_PV shorthand taking eight parameters. */
3931#define RT_NOREF8(var1, var2, var3, var4, var5, var6, var7, var8) \
3932 RT_NOREF_PV(var1); RT_NOREF7(var2, var3, var4, var5, var6, var7, var8)
3933/** @def RT_NOREF9
3934 * RT_NOREF_PV shorthand taking nine parameters. */
3935#define RT_NOREF9(var1, var2, var3, var4, var5, var6, var7, var8, var9) \
3936 RT_NOREF_PV(var1); RT_NOREF8(var2, var3, var4, var5, var6, var7, var8, var9)
3937/** @def RT_NOREF10
3938 * RT_NOREF_PV shorthand taking ten parameters. */
3939#define RT_NOREF10(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10) \
3940 RT_NOREF_PV(var1); RT_NOREF_PV(var2); RT_NOREF_PV(var3); RT_NOREF_PV(var4); RT_NOREF_PV(var5); RT_NOREF_PV(var6); \
3941 RT_NOREF_PV(var7); RT_NOREF_PV(var8); RT_NOREF_PV(var9); RT_NOREF_PV(var10)
3942/** @def RT_NOREF11
3943 * RT_NOREF_PV shorthand taking eleven parameters. */
3944#define RT_NOREF11(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11) \
3945 RT_NOREF_PV(var1); RT_NOREF10(var2, var3, var4, var5, var6, var7, var8, var9, var10, var11)
3946/** @def RT_NOREF12
3947 * RT_NOREF_PV shorthand taking twelve parameters. */
3948#define RT_NOREF12(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12) \
3949 RT_NOREF_PV(var1); RT_NOREF11(var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12)
3950/** @def RT_NOREF13
3951 * RT_NOREF_PV shorthand taking thirteen parameters. */
3952#define RT_NOREF13(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13) \
3953 RT_NOREF_PV(var1); RT_NOREF12(var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13)
3954/** @def RT_NOREF14
3955 * RT_NOREF_PV shorthand taking fourteen parameters. */
3956#define RT_NOREF14(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14) \
3957 RT_NOREF_PV(var1); RT_NOREF13(var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14)
3958/** @def RT_NOREF15
3959 * RT_NOREF_PV shorthand taking fifteen parameters. */
3960#define RT_NOREF15(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15) \
3961 RT_NOREF_PV(var1); RT_NOREF14(var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15)
3962/** @def RT_NOREF16
3963 * RT_NOREF_PV shorthand taking fifteen parameters. */
3964#define RT_NOREF16(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16) \
3965 RT_NOREF_PV(var1); RT_NOREF15(var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16)
3966/** @def RT_NOREF17
3967 * RT_NOREF_PV shorthand taking seventeen parameters. */
3968#define RT_NOREF17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) \
3969 RT_NOREF_PV(v1); RT_NOREF16(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
3970/** @def RT_NOREF18
3971 * RT_NOREF_PV shorthand taking eighteen parameters. */
3972#define RT_NOREF18(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) \
3973 RT_NOREF_PV(v1); RT_NOREF17(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
3974/** @def RT_NOREF19
3975 * RT_NOREF_PV shorthand taking nineteen parameters. */
3976#define RT_NOREF19(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) \
3977 RT_NOREF_PV(v1); RT_NOREF18(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
3978/** @def RT_NOREF20
3979 * RT_NOREF_PV shorthand taking twenty parameters. */
3980#define RT_NOREF20(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) \
3981 RT_NOREF_PV(v1); RT_NOREF19(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
3982/** @def RT_NOREF21
3983 * RT_NOREF_PV shorthand taking twentyone parameters. */
3984#define RT_NOREF21(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) \
3985 RT_NOREF_PV(v1); RT_NOREF20(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
3986/** @def RT_NOREF22
3987 * RT_NOREF_PV shorthand taking twentytwo parameters. */
3988#define RT_NOREF22(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) \
3989 RT_NOREF_PV(v1); RT_NOREF21(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
3990
3991/** @def RT_NOREF
3992 * RT_NOREF_PV variant using the variadic macro feature of C99.
3993 * @remarks Only use this in sources */
3994#ifdef RT_COMPILER_SUPPORTS_VA_ARGS
3995# define RT_NOREF(...) \
3996 RT_UNPACK_CALL(RT_CONCAT(RT_NOREF, RT_EXPAND(RT_COUNT_VA_ARGS(__VA_ARGS__))),(__VA_ARGS__))
3997#endif
3998
3999
4000/** @def RT_BREAKPOINT
4001 * Emit a debug breakpoint instruction.
4002 *
4003 * @remarks In the x86/amd64 gnu world we add a nop instruction after the int3
4004 * to force gdb to remain at the int3 source line.
4005 * @remarks The L4 kernel will try make sense of the breakpoint, thus the jmp on
4006 * x86/amd64.
4007 */
4008#ifdef __GNUC__
4009# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
4010# if !defined(__L4ENV__)
4011# define RT_BREAKPOINT() __asm__ __volatile__("int $3\n\tnop\n\t")
4012# else
4013# define RT_BREAKPOINT() __asm__ __volatile__("int3; jmp 1f; 1:\n\t")
4014# endif
4015# elif defined(RT_ARCH_SPARC64)
4016# define RT_BREAKPOINT() __asm__ __volatile__("illtrap 0\n\t") /** @todo Sparc64: this is just a wild guess. */
4017# elif defined(RT_ARCH_SPARC)
4018# define RT_BREAKPOINT() __asm__ __volatile__("unimp 0\n\t") /** @todo Sparc: this is just a wild guess (same as Sparc64, just different name). */
4019# elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
4020# define RT_BREAKPOINT() __asm__ __volatile__("brk #0xf000\n\t")
4021# endif
4022#endif
4023#ifdef _MSC_VER
4024# define RT_BREAKPOINT() __debugbreak()
4025#endif
4026#if defined(__IBMC__) || defined(__IBMCPP__)
4027# define RT_BREAKPOINT() __interrupt(3)
4028#endif
4029#if defined(__WATCOMC__)
4030# define RT_BREAKPOINT() _asm { int 3 }
4031#endif
4032#ifndef RT_BREAKPOINT
4033# error "This compiler/arch is not supported!"
4034#endif
4035
4036
4037/** @defgroup grp_rt_cdefs_size Size Constants
4038 * (Of course, these are binary computer terms, not SI.)
4039 * @{
4040 */
4041/** 1 K (Kilo) (1 024). */
4042#define _1K 0x00000400
4043/** 2 K (Kilo) (2 048). */
4044#define _2K 0x00000800
4045/** 4 K (Kilo) (4 096). */
4046#define _4K 0x00001000
4047/** 8 K (Kilo) (8 192). */
4048#define _8K 0x00002000
4049/** 16 K (Kilo) (16 384). */
4050#define _16K 0x00004000
4051/** 32 K (Kilo) (32 768). */
4052#define _32K 0x00008000
4053/** 64 K (Kilo) (65 536). */
4054#if ARCH_BITS != 16
4055# define _64K 0x00010000
4056#else
4057# define _64K UINT32_C(0x00010000)
4058#endif
4059/** 128 K (Kilo) (131 072). */
4060#if ARCH_BITS != 16
4061# define _128K 0x00020000
4062#else
4063# define _128K UINT32_C(0x00020000)
4064#endif
4065/** 256 K (Kilo) (262 144). */
4066#if ARCH_BITS != 16
4067# define _256K 0x00040000
4068#else
4069# define _256K UINT32_C(0x00040000)
4070#endif
4071/** 512 K (Kilo) (524 288). */
4072#if ARCH_BITS != 16
4073# define _512K 0x00080000
4074#else
4075# define _512K UINT32_C(0x00080000)
4076#endif
4077/** 1 M (Mega) (1 048 576). */
4078#if ARCH_BITS != 16
4079# define _1M 0x00100000
4080#else
4081# define _1M UINT32_C(0x00100000)
4082#endif
4083/** 2 M (Mega) (2 097 152). */
4084#if ARCH_BITS != 16
4085# define _2M 0x00200000
4086#else
4087# define _2M UINT32_C(0x00200000)
4088#endif
4089/** 4 M (Mega) (4 194 304). */
4090#if ARCH_BITS != 16
4091# define _4M 0x00400000
4092#else
4093# define _4M UINT32_C(0x00400000)
4094#endif
4095/** 8 M (Mega) (8 388 608). */
4096#define _8M UINT32_C(0x00800000)
4097/** 16 M (Mega) (16 777 216). */
4098#define _16M UINT32_C(0x01000000)
4099/** 32 M (Mega) (33 554 432). */
4100#define _32M UINT32_C(0x02000000)
4101/** 64 M (Mega) (67 108 864). */
4102#define _64M UINT32_C(0x04000000)
4103/** 128 M (Mega) (134 217 728). */
4104#define _128M UINT32_C(0x08000000)
4105/** 256 M (Mega) (268 435 456). */
4106#define _256M UINT32_C(0x10000000)
4107/** 512 M (Mega) (536 870 912). */
4108#define _512M UINT32_C(0x20000000)
4109/** 1 G (Giga) (1 073 741 824). (32-bit) */
4110#if ARCH_BITS != 16
4111# define _1G 0x40000000
4112#else
4113# define _1G UINT32_C(0x40000000)
4114#endif
4115/** 1 G (Giga) (1 073 741 824). (64-bit) */
4116#if ARCH_BITS != 16
4117# define _1G64 0x40000000LL
4118#else
4119# define _1G64 UINT64_C(0x40000000)
4120#endif
4121/** 2 G (Giga) (2 147 483 648). (32-bit) */
4122#define _2G32 UINT32_C(0x80000000)
4123/** 2 G (Giga) (2 147 483 648). (64-bit) */
4124#if ARCH_BITS != 16
4125# define _2G 0x0000000080000000LL
4126#else
4127# define _2G UINT64_C(0x0000000080000000)
4128#endif
4129/** 4 G (Giga) (4 294 967 296). */
4130#if ARCH_BITS != 16
4131# define _4G 0x0000000100000000LL
4132#else
4133# define _4G UINT64_C(0x0000000100000000)
4134#endif
4135/** 1 T (Tera) (1 099 511 627 776). */
4136#if ARCH_BITS != 16
4137# define _1T 0x0000010000000000LL
4138#else
4139# define _1T UINT64_C(0x0000010000000000)
4140#endif
4141/** 1 P (Peta) (1 125 899 906 842 624). */
4142#if ARCH_BITS != 16
4143# define _1P 0x0004000000000000LL
4144#else
4145# define _1P UINT64_C(0x0004000000000000)
4146#endif
4147/** 1 E (Exa) (1 152 921 504 606 846 976). */
4148#if ARCH_BITS != 16
4149# define _1E 0x1000000000000000LL
4150#else
4151# define _1E UINT64_C(0x1000000000000000)
4152#endif
4153/** 2 E (Exa) (2 305 843 009 213 693 952). */
4154#if ARCH_BITS != 16
4155# define _2E 0x2000000000000000ULL
4156#else
4157# define _2E UINT64_C(0x2000000000000000)
4158#endif
4159/** @} */
4160
4161/** @defgroup grp_rt_cdefs_decimal_grouping Decimal Constant Grouping Macros
4162 * @{ */
4163#define RT_D1(g1) g1
4164#define RT_D2(g1, g2) g1#g2
4165#define RT_D3(g1, g2, g3) g1#g2#g3
4166#define RT_D4(g1, g2, g3, g4) g1#g2#g3#g4
4167#define RT_D5(g1, g2, g3, g4, g5) g1#g2#g3#g4#g5
4168#define RT_D6(g1, g2, g3, g4, g5, g6) g1#g2#g3#g4#g5#g6
4169#define RT_D7(g1, g2, g3, g4, g5, g6, g7) g1#g2#g3#g4#g5#g6#g7
4170
4171#define RT_D1_U(g1) UINT32_C(g1)
4172#define RT_D2_U(g1, g2) UINT32_C(g1#g2)
4173#define RT_D3_U(g1, g2, g3) UINT32_C(g1#g2#g3)
4174#define RT_D4_U(g1, g2, g3, g4) UINT64_C(g1#g2#g3#g4)
4175#define RT_D5_U(g1, g2, g3, g4, g5) UINT64_C(g1#g2#g3#g4#g5)
4176#define RT_D6_U(g1, g2, g3, g4, g5, g6) UINT64_C(g1#g2#g3#g4#g5#g6)
4177#define RT_D7_U(g1, g2, g3, g4, g5, g6, g7) UINT64_C(g1#g2#g3#g4#g5#g6#g7)
4178
4179#define RT_D1_S(g1) INT32_C(g1)
4180#define RT_D2_S(g1, g2) INT32_C(g1#g2)
4181#define RT_D3_S(g1, g2, g3) INT32_C(g1#g2#g3)
4182#define RT_D4_S(g1, g2, g3, g4) INT64_C(g1#g2#g3#g4)
4183#define RT_D5_S(g1, g2, g3, g4, g5) INT64_C(g1#g2#g3#g4#g5)
4184#define RT_D6_S(g1, g2, g3, g4, g5, g6) INT64_C(g1#g2#g3#g4#g5#g6)
4185#define RT_D7_S(g1, g2, g3, g4, g5, g6, g7) INT64_C(g1#g2#g3#g4#g5#g6#g7)
4186
4187#define RT_D1_U32(g1) UINT32_C(g1)
4188#define RT_D2_U32(g1, g2) UINT32_C(g1#g2)
4189#define RT_D3_U32(g1, g2, g3) UINT32_C(g1#g2#g3)
4190#define RT_D4_U32(g1, g2, g3, g4) UINT32_C(g1#g2#g3#g4)
4191
4192#define RT_D1_S32(g1) INT32_C(g1)
4193#define RT_D2_S32(g1, g2) INT32_C(g1#g2)
4194#define RT_D3_S32(g1, g2, g3) INT32_C(g1#g2#g3)
4195#define RT_D4_S32(g1, g2, g3, g4) INT32_C(g1#g2#g3#g4)
4196
4197#define RT_D1_U64(g1) UINT64_C(g1)
4198#define RT_D2_U64(g1, g2) UINT64_C(g1#g2)
4199#define RT_D3_U64(g1, g2, g3) UINT64_C(g1#g2#g3)
4200#define RT_D4_U64(g1, g2, g3, g4) UINT64_C(g1#g2#g3#g4)
4201#define RT_D5_U64(g1, g2, g3, g4, g5) UINT64_C(g1#g2#g3#g4#g5)
4202#define RT_D6_U64(g1, g2, g3, g4, g5, g6) UINT64_C(g1#g2#g3#g4#g5#g6)
4203#define RT_D7_U64(g1, g2, g3, g4, g5, g6, g7) UINT64_C(g1#g2#g3#g4#g5#g6#g7)
4204
4205#define RT_D1_S64(g1) INT64_C(g1)
4206#define RT_D2_S64(g1, g2) INT64_C(g1#g2)
4207#define RT_D3_S64(g1, g2, g3) INT64_C(g1#g2#g3)
4208#define RT_D4_S64(g1, g2, g3, g4) INT64_C(g1#g2#g3#g4)
4209#define RT_D5_S64(g1, g2, g3, g4, g5) INT64_C(g1#g2#g3#g4#g5)
4210#define RT_D6_S64(g1, g2, g3, g4, g5, g6) INT64_C(g1#g2#g3#g4#g5#g6)
4211#define RT_D7_S64(g1, g2, g3, g4, g5, g6, g7) INT64_C(g1#g2#g3#g4#g5#g6#g7)
4212/** @} */
4213
4214
4215/** @defgroup grp_rt_cdefs_time Time Constants
4216 * @{
4217 */
4218/** 1 week expressed in nanoseconds (64-bit). */
4219#define RT_NS_1WEEK UINT64_C(604800000000000)
4220/** 1 day expressed in nanoseconds (64-bit). */
4221#define RT_NS_1DAY UINT64_C(86400000000000)
4222/** 1 hour expressed in nanoseconds (64-bit). */
4223#define RT_NS_1HOUR UINT64_C(3600000000000)
4224/** 30 minutes expressed in nanoseconds (64-bit). */
4225#define RT_NS_30MIN UINT64_C(1800000000000)
4226/** 5 minutes expressed in nanoseconds (64-bit). */
4227#define RT_NS_5MIN UINT64_C(300000000000)
4228/** 1 minute expressed in nanoseconds (64-bit). */
4229#define RT_NS_1MIN UINT64_C(60000000000)
4230/** 45 seconds expressed in nanoseconds (64-bit). */
4231#define RT_NS_45SEC UINT64_C(45000000000)
4232/** 30 seconds expressed in nanoseconds (64-bit). */
4233#define RT_NS_30SEC UINT64_C(30000000000)
4234/** 20 seconds expressed in nanoseconds (64-bit). */
4235#define RT_NS_20SEC UINT64_C(20000000000)
4236/** 15 seconds expressed in nanoseconds (64-bit). */
4237#define RT_NS_15SEC UINT64_C(15000000000)
4238/** 10 seconds expressed in nanoseconds (64-bit). */
4239#define RT_NS_10SEC UINT64_C(10000000000)
4240/** 1 second expressed in nanoseconds. */
4241#define RT_NS_1SEC UINT32_C(1000000000)
4242/** 100 millsecond expressed in nanoseconds. */
4243#define RT_NS_100MS UINT32_C(100000000)
4244/** 10 millsecond expressed in nanoseconds. */
4245#define RT_NS_10MS UINT32_C(10000000)
4246/** 8 millsecond expressed in nanoseconds. */
4247#define RT_NS_8MS UINT32_C(8000000)
4248/** 2 millsecond expressed in nanoseconds. */
4249#define RT_NS_2MS UINT32_C(2000000)
4250/** 1 millsecond expressed in nanoseconds. */
4251#define RT_NS_1MS UINT32_C(1000000)
4252/** 100 microseconds expressed in nanoseconds. */
4253#define RT_NS_100US UINT32_C(100000)
4254/** 10 microseconds expressed in nanoseconds. */
4255#define RT_NS_10US UINT32_C(10000)
4256/** 1 microsecond expressed in nanoseconds. */
4257#define RT_NS_1US UINT32_C(1000)
4258
4259/** 1 second expressed in nanoseconds - 64-bit type. */
4260#define RT_NS_1SEC_64 UINT64_C(1000000000)
4261/** 100 millsecond expressed in nanoseconds - 64-bit type. */
4262#define RT_NS_100MS_64 UINT64_C(100000000)
4263/** 10 millsecond expressed in nanoseconds - 64-bit type. */
4264#define RT_NS_10MS_64 UINT64_C(10000000)
4265/** 1 millsecond expressed in nanoseconds - 64-bit type. */
4266#define RT_NS_1MS_64 UINT64_C(1000000)
4267/** 100 microseconds expressed in nanoseconds - 64-bit type. */
4268#define RT_NS_100US_64 UINT64_C(100000)
4269/** 10 microseconds expressed in nanoseconds - 64-bit type. */
4270#define RT_NS_10US_64 UINT64_C(10000)
4271/** 1 microsecond expressed in nanoseconds - 64-bit type. */
4272#define RT_NS_1US_64 UINT64_C(1000)
4273
4274/** 1 week expressed in microseconds (64-bit). */
4275#define RT_US_1WEEK UINT64_C(604800000000)
4276/** 1 day expressed in microseconds (64-bit). */
4277#define RT_US_1DAY UINT64_C(86400000000)
4278/** 1 hour expressed in microseconds. */
4279#define RT_US_1HOUR UINT32_C(3600000000)
4280/** 30 minutes expressed in microseconds. */
4281#define RT_US_30MIN UINT32_C(1800000000)
4282/** 5 minutes expressed in microseconds. */
4283#define RT_US_5MIN UINT32_C(300000000)
4284/** 1 minute expressed in microseconds. */
4285#define RT_US_1MIN UINT32_C(60000000)
4286/** 45 seconds expressed in microseconds. */
4287#define RT_US_45SEC UINT32_C(45000000)
4288/** 30 seconds expressed in microseconds. */
4289#define RT_US_30SEC UINT32_C(30000000)
4290/** 20 seconds expressed in microseconds. */
4291#define RT_US_20SEC UINT32_C(20000000)
4292/** 15 seconds expressed in microseconds. */
4293#define RT_US_15SEC UINT32_C(15000000)
4294/** 10 seconds expressed in microseconds. */
4295#define RT_US_10SEC UINT32_C(10000000)
4296/** 5 seconds expressed in microseconds. */
4297#define RT_US_5SEC UINT32_C(5000000)
4298/** 1 second expressed in microseconds. */
4299#define RT_US_1SEC UINT32_C(1000000)
4300/** 100 millsecond expressed in microseconds. */
4301#define RT_US_100MS UINT32_C(100000)
4302/** 10 millsecond expressed in microseconds. */
4303#define RT_US_10MS UINT32_C(10000)
4304/** 1 millsecond expressed in microseconds. */
4305#define RT_US_1MS UINT32_C(1000)
4306
4307/** 1 hour expressed in microseconds - 64-bit type. */
4308#define RT_US_1HOUR_64 UINT64_C(3600000000)
4309/** 30 minutes expressed in microseconds - 64-bit type. */
4310#define RT_US_30MIN_64 UINT64_C(1800000000)
4311/** 5 minutes expressed in microseconds - 64-bit type. */
4312#define RT_US_5MIN_64 UINT64_C(300000000)
4313/** 1 minute expressed in microseconds - 64-bit type. */
4314#define RT_US_1MIN_64 UINT64_C(60000000)
4315/** 45 seconds expressed in microseconds - 64-bit type. */
4316#define RT_US_45SEC_64 UINT64_C(45000000)
4317/** 30 seconds expressed in microseconds - 64-bit type. */
4318#define RT_US_30SEC_64 UINT64_C(30000000)
4319/** 20 seconds expressed in microseconds - 64-bit type. */
4320#define RT_US_20SEC_64 UINT64_C(20000000)
4321/** 15 seconds expressed in microseconds - 64-bit type. */
4322#define RT_US_15SEC_64 UINT64_C(15000000)
4323/** 10 seconds expressed in microseconds - 64-bit type. */
4324#define RT_US_10SEC_64 UINT64_C(10000000)
4325/** 5 seconds expressed in microseconds - 64-bit type. */
4326#define RT_US_5SEC_64 UINT64_C(5000000)
4327/** 1 second expressed in microseconds - 64-bit type. */
4328#define RT_US_1SEC_64 UINT64_C(1000000)
4329/** 100 millsecond expressed in microseconds - 64-bit type. */
4330#define RT_US_100MS_64 UINT64_C(100000)
4331/** 10 millsecond expressed in microseconds - 64-bit type. */
4332#define RT_US_10MS_64 UINT64_C(10000)
4333/** 1 millsecond expressed in microseconds - 64-bit type. */
4334#define RT_US_1MS_64 UINT64_C(1000)
4335
4336/** 1 week expressed in milliseconds. */
4337#define RT_MS_1WEEK UINT32_C(604800000)
4338/** 1 day expressed in milliseconds. */
4339#define RT_MS_1DAY UINT32_C(86400000)
4340/** 1 hour expressed in milliseconds. */
4341#define RT_MS_1HOUR UINT32_C(3600000)
4342/** 30 minutes expressed in milliseconds. */
4343#define RT_MS_30MIN UINT32_C(1800000)
4344/** 5 minutes expressed in milliseconds. */
4345#define RT_MS_5MIN UINT32_C(300000)
4346/** 1 minute expressed in milliseconds. */
4347#define RT_MS_1MIN UINT32_C(60000)
4348/** 45 seconds expressed in milliseconds. */
4349#define RT_MS_45SEC UINT32_C(45000)
4350/** 30 seconds expressed in milliseconds. */
4351#define RT_MS_30SEC UINT32_C(30000)
4352/** 20 seconds expressed in milliseconds. */
4353#define RT_MS_20SEC UINT32_C(20000)
4354/** 15 seconds expressed in milliseconds. */
4355#define RT_MS_15SEC UINT32_C(15000)
4356/** 10 seconds expressed in milliseconds. */
4357#define RT_MS_10SEC UINT32_C(10000)
4358/** 5 seconds expressed in milliseconds. */
4359#define RT_MS_5SEC UINT32_C(5000)
4360/** 1 second expressed in milliseconds. */
4361#define RT_MS_1SEC UINT32_C(1000)
4362
4363/** 1 week expressed in milliseconds - 64-bit type. */
4364#define RT_MS_1WEEK_64 UINT64_C(604800000)
4365/** 1 day expressed in milliseconds - 64-bit type. */
4366#define RT_MS_1DAY_64 UINT64_C(86400000)
4367/** 1 hour expressed in milliseconds - 64-bit type. */
4368#define RT_MS_1HOUR_64 UINT64_C(3600000)
4369/** 30 minutes expressed in milliseconds - 64-bit type. */
4370#define RT_MS_30MIN_64 UINT64_C(1800000)
4371/** 5 minutes expressed in milliseconds - 64-bit type. */
4372#define RT_MS_5MIN_64 UINT64_C(300000)
4373/** 1 minute expressed in milliseconds - 64-bit type. */
4374#define RT_MS_1MIN_64 UINT64_C(60000)
4375/** 45 seconds expressed in milliseconds - 64-bit type. */
4376#define RT_MS_45SEC_64 UINT64_C(45000)
4377/** 30 seconds expressed in milliseconds - 64-bit type. */
4378#define RT_MS_30SEC_64 UINT64_C(30000)
4379/** 20 seconds expressed in milliseconds - 64-bit type. */
4380#define RT_MS_20SEC_64 UINT64_C(20000)
4381/** 15 seconds expressed in milliseconds - 64-bit type. */
4382#define RT_MS_15SEC_64 UINT64_C(15000)
4383/** 10 seconds expressed in milliseconds - 64-bit type. */
4384#define RT_MS_10SEC_64 UINT64_C(10000)
4385/** 5 seconds expressed in milliseconds - 64-bit type. */
4386#define RT_MS_5SEC_64 UINT64_C(5000)
4387/** 1 second expressed in milliseconds - 64-bit type. */
4388#define RT_MS_1SEC_64 UINT64_C(1000)
4389
4390/** The number of seconds per week. */
4391#define RT_SEC_1WEEK UINT32_C(604800)
4392/** The number of seconds per day. */
4393#define RT_SEC_1DAY UINT32_C(86400)
4394/** The number of seconds per hour. */
4395#define RT_SEC_1HOUR UINT32_C(3600)
4396
4397/** The number of seconds per week - 64-bit type. */
4398#define RT_SEC_1WEEK_64 UINT64_C(604800)
4399/** The number of seconds per day - 64-bit type. */
4400#define RT_SEC_1DAY_64 UINT64_C(86400)
4401/** The number of seconds per hour - 64-bit type. */
4402#define RT_SEC_1HOUR_64 UINT64_C(3600)
4403/** @} */
4404
4405
4406/** @defgroup grp_rt_cdefs_dbgtype Debug Info Types
4407 * @{ */
4408/** Other format. */
4409#define RT_DBGTYPE_OTHER RT_BIT_32(0)
4410/** Stabs. */
4411#define RT_DBGTYPE_STABS RT_BIT_32(1)
4412/** Debug With Arbitrary Record Format (DWARF). */
4413#define RT_DBGTYPE_DWARF RT_BIT_32(2)
4414/** Microsoft Codeview debug info. */
4415#define RT_DBGTYPE_CODEVIEW RT_BIT_32(3)
4416/** Watcom debug info. */
4417#define RT_DBGTYPE_WATCOM RT_BIT_32(4)
4418/** IBM High Level Language debug info. */
4419#define RT_DBGTYPE_HLL RT_BIT_32(5)
4420/** Old OS/2 and Windows symbol file. */
4421#define RT_DBGTYPE_SYM RT_BIT_32(6)
4422/** Map file. */
4423#define RT_DBGTYPE_MAP RT_BIT_32(7)
4424/** @} */
4425
4426
4427/** @defgroup grp_rt_cdefs_exetype Executable Image Types
4428 * @{ */
4429/** Some other format. */
4430#define RT_EXETYPE_OTHER RT_BIT_32(0)
4431/** Portable Executable. */
4432#define RT_EXETYPE_PE RT_BIT_32(1)
4433/** Linear eXecutable. */
4434#define RT_EXETYPE_LX RT_BIT_32(2)
4435/** Linear Executable. */
4436#define RT_EXETYPE_LE RT_BIT_32(3)
4437/** New Executable. */
4438#define RT_EXETYPE_NE RT_BIT_32(4)
4439/** DOS Executable (Mark Zbikowski). */
4440#define RT_EXETYPE_MZ RT_BIT_32(5)
4441/** COM Executable. */
4442#define RT_EXETYPE_COM RT_BIT_32(6)
4443/** a.out Executable. */
4444#define RT_EXETYPE_AOUT RT_BIT_32(7)
4445/** Executable and Linkable Format. */
4446#define RT_EXETYPE_ELF RT_BIT_32(8)
4447/** Mach-O Executable (including FAT ones). */
4448#define RT_EXETYPE_MACHO RT_BIT_32(9)
4449/** TE from UEFI. */
4450#define RT_EXETYPE_TE RT_BIT_32(9)
4451/** @} */
4452
4453
4454/** @def RT_VALID_PTR
4455 * Pointer validation macro.
4456 * @param ptr The pointer.
4457 */
4458#ifdef VBOX_WITH_PARFAIT
4459/*
4460 * Parfait will report memory leaks when something returns after a memory allocation
4461 * using a check containing RT_VALID_PTR() (AssertPtrReturn and friends for example).
4462 * To avoid those false positives the macro will just check for the pointer being != NULL.
4463 */
4464# define RT_VALID_PTR(ptr) (ptr != NULL)
4465#else
4466#if defined(RT_ARCH_AMD64)
4467# ifdef IN_RING3
4468# if defined(RT_OS_DARWIN) /* first 4GB is reserved for legacy kernel. */
4469# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) >= _4G \
4470 && !((uintptr_t)(ptr) & 0xffff800000000000ULL) )
4471# elif defined(RT_OS_SOLARIS) /* The kernel only used the top 2TB, but keep it simple. */
4472# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U \
4473 && ( ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0xffff800000000000ULL \
4474 || ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0) )
4475# elif defined(RT_OS_LINUX) /* May use 5-level paging (see Documentation/x86/x86_64/mm.rst). */
4476# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) >= 0x1000U /* one invalid page at the bottom */ \
4477 && !((uintptr_t)(ptr) & 0xff00000000000000ULL) )
4478# else
4479# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) >= 0x1000U \
4480 && !((uintptr_t)(ptr) & 0xffff800000000000ULL) )
4481# endif
4482# else /* !IN_RING3 */
4483# if defined(RT_OS_LINUX) /* May use 5-level paging (see Documentation/x86/x86_64/mm.rst). */
4484# if 1 /* User address are no longer considered valid in kernel mode (SMAP, etc). */
4485# define RT_VALID_PTR(ptr) ((uintptr_t)(ptr) - 0xff00000000000000ULL < 0x00ffffffffe00000ULL) /* 2MB invalid space at the top */
4486# else
4487# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x200000 >= 0x201000U /* one invalid page at the bottom and 2MB at the top */ \
4488 && ( ((uintptr_t)(ptr) & 0xff00000000000000ULL) == 0xff00000000000000ULL \
4489 || ((uintptr_t)(ptr) & 0xff00000000000000ULL) == 0) )
4490# endif
4491# else
4492# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U \
4493 && ( ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0xffff800000000000ULL \
4494 || ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0) )
4495# endif
4496# endif /* !IN_RING3 */
4497
4498# elif defined(RT_ARCH_X86)
4499# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
4500
4501# elif defined(RT_ARCH_SPARC64)
4502# ifdef IN_RING3
4503# if defined(RT_OS_SOLARIS)
4504/** Sparc64 user mode: According to Figure 9.4 in solaris internals */
4505/** @todo # define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x80004000U >= 0x80004000U + 0x100000000ULL ) - figure this. */
4506# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x80000000U >= 0x80000000U + 0x100000000ULL )
4507# else
4508# error "Port me"
4509# endif
4510# else /* !IN_RING3 */
4511# if defined(RT_OS_SOLARIS)
4512/** @todo Sparc64 kernel mode: This is according to Figure 11.1 in solaris
4513 * internals. Verify in sources. */
4514# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) >= 0x01000000U )
4515# else
4516# error "Port me"
4517# endif
4518# endif /* !IN_RING3 */
4519
4520# elif defined(RT_ARCH_SPARC)
4521# ifdef IN_RING3
4522# ifdef RT_OS_SOLARIS
4523/** Sparc user mode: According to
4524 * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/sun4/os/startup.c#510 */
4525# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x400000U >= 0x400000U + 0x2000U )
4526
4527# else
4528# error "Port me"
4529# endif
4530# else /* !IN_RING3 */
4531# ifdef RT_OS_SOLARIS
4532/** @todo Sparc kernel mode: Check the sources! */
4533# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
4534# else
4535# error "Port me"
4536# endif
4537# endif /* !IN_RING3 */
4538
4539# elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
4540/* ASSUMES that at least the last and first 4K are out of bounds. */
4541# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
4542
4543# else
4544# error "Architecture identifier missing / not implemented."
4545# endif
4546#endif /*!VBOX_WITH_PARFAIT*/
4547
4548/** @def RT_VALID_ALIGNED_PTR
4549 * Pointer validation macro that also checks the alignment.
4550 * @param ptr The pointer.
4551 * @param align The alignment, must be a power of two.
4552 */
4553#define RT_VALID_ALIGNED_PTR(ptr, align) \
4554 ( !((uintptr_t)(ptr) & (uintptr_t)((align) - 1)) \
4555 && RT_VALID_PTR(ptr) )
4556
4557
4558/** @def VALID_PHYS32
4559 * 32 bits physical address validation macro.
4560 * @param Phys The RTGCPHYS address.
4561 */
4562#define VALID_PHYS32(Phys) ( (uint64_t)(Phys) < (uint64_t)_4G )
4563
4564/** @def N_
4565 * The \#define N_ is used to mark a string for translation. This is usable in
4566 * any part of the code, as it is only used by the tools that create message
4567 * catalogs. This macro is a no-op as far as the compiler and code generation
4568 * is concerned.
4569 *
4570 * If you want to both mark a string for translation and translate it, use _().
4571 */
4572#define N_(s) (s)
4573
4574/** @def _
4575 * The \#define _ is used to mark a string for translation and to translate it
4576 * in one step.
4577 *
4578 * If you want to only mark a string for translation, use N_().
4579 */
4580#define _(s) gettext(s)
4581
4582
4583#if (!defined(__GNUC__) && !defined(__PRETTY_FUNCTION__)) || defined(DOXYGEN_RUNNING)
4584# if defined(_MSC_VER) || defined(DOXYGEN_RUNNING)
4585/** With GNU C we'd like to use the builtin __PRETTY_FUNCTION__, so define that
4586 * for the other compilers. */
4587# define __PRETTY_FUNCTION__ __FUNCSIG__
4588# else
4589# define __PRETTY_FUNCTION__ __FUNCTION__
4590# endif
4591#endif
4592
4593
4594/** @def RT_STRICT
4595 * The \#define RT_STRICT controls whether or not assertions and other runtime
4596 * checks should be compiled in or not. This is defined when DEBUG is defined.
4597 * If RT_NO_STRICT is defined, it will unconditionally be undefined.
4598 *
4599 * If you want assertions which are not subject to compile time options use
4600 * the AssertRelease*() flavors.
4601 */
4602#if !defined(RT_STRICT) && defined(DEBUG)
4603# define RT_STRICT
4604#endif
4605#ifdef RT_NO_STRICT
4606# undef RT_STRICT
4607#endif
4608
4609/** @todo remove this: */
4610#if !defined(RT_LOCK_STRICT) && !defined(DEBUG_bird)
4611# define RT_LOCK_NO_STRICT
4612#endif
4613#if !defined(RT_LOCK_STRICT_ORDER) && !defined(DEBUG_bird)
4614# define RT_LOCK_NO_STRICT_ORDER
4615#endif
4616
4617/** @def RT_LOCK_STRICT
4618 * The \#define RT_LOCK_STRICT controls whether deadlock detection and related
4619 * checks are done in the lock and semaphore code. It is by default enabled in
4620 * RT_STRICT builds, but this behavior can be overridden by defining
4621 * RT_LOCK_NO_STRICT. */
4622#if !defined(RT_LOCK_STRICT) && !defined(RT_LOCK_NO_STRICT) && defined(RT_STRICT)
4623# define RT_LOCK_STRICT
4624#endif
4625/** @def RT_LOCK_NO_STRICT
4626 * The \#define RT_LOCK_NO_STRICT disables RT_LOCK_STRICT. */
4627#if defined(RT_LOCK_NO_STRICT) && defined(RT_LOCK_STRICT)
4628# undef RT_LOCK_STRICT
4629#endif
4630
4631/** @def RT_LOCK_STRICT_ORDER
4632 * The \#define RT_LOCK_STRICT_ORDER controls whether locking order is checked
4633 * by the lock and semaphore code. It is by default enabled in RT_STRICT
4634 * builds, but this behavior can be overridden by defining
4635 * RT_LOCK_NO_STRICT_ORDER. */
4636#if !defined(RT_LOCK_STRICT_ORDER) && !defined(RT_LOCK_NO_STRICT_ORDER) && defined(RT_STRICT)
4637# define RT_LOCK_STRICT_ORDER
4638#endif
4639/** @def RT_LOCK_NO_STRICT_ORDER
4640 * The \#define RT_LOCK_NO_STRICT_ORDER disables RT_LOCK_STRICT_ORDER. */
4641#if defined(RT_LOCK_NO_STRICT_ORDER) && defined(RT_LOCK_STRICT_ORDER)
4642# undef RT_LOCK_STRICT_ORDER
4643#endif
4644
4645
4646/** Source position. */
4647#define RT_SRC_POS __FILE__, __LINE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__
4648
4649/** Source position declaration. */
4650#define RT_SRC_POS_DECL const char *pszFile, unsigned iLine, const char *pszFunction
4651
4652/** Source position arguments. */
4653#define RT_SRC_POS_ARGS pszFile, iLine, pszFunction
4654
4655/** Applies NOREF() to the source position arguments. */
4656#define RT_SRC_POS_NOREF() do { NOREF(pszFile); NOREF(iLine); NOREF(pszFunction); } while (0)
4657
4658
4659/** @def RT_INLINE_ASM_EXTERNAL
4660 * Defined as 1 if the compiler does not support inline assembly.
4661 * The ASM* functions will then be implemented in external .asm files.
4662 */
4663#if (defined(_MSC_VER) && defined(RT_ARCH_AMD64)) \
4664 || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86) && !defined(RT_ARCH_ARM64) && !defined(RT_ARCH_ARM32)) \
4665 || defined(__WATCOMC__)
4666# define RT_INLINE_ASM_EXTERNAL 1
4667#else
4668# define RT_INLINE_ASM_EXTERNAL 0
4669#endif
4670
4671/** @def RT_INLINE_ASM_GNU_STYLE
4672 * Defined as 1 if the compiler understands GNU style inline assembly.
4673 */
4674#if defined(_MSC_VER) || defined(__WATCOMC__)
4675# define RT_INLINE_ASM_GNU_STYLE 0
4676#else
4677# define RT_INLINE_ASM_GNU_STYLE 1
4678#endif
4679
4680/** @def RT_INLINE_ASM_USES_INTRIN
4681 * Defined as one of the RT_MSC_VER_XXX MSC version values if the compiler have
4682 * and uses intrin.h. Otherwise it is 0. */
4683#ifdef _MSC_VER
4684# if _MSC_VER >= RT_MSC_VER_VS2019 /* Visual C++ v14.2 */
4685# define RT_INLINE_ASM_USES_INTRIN RT_MSC_VER_VS2019
4686# elif _MSC_VER >= RT_MSC_VER_VS2017 /* Visual C++ v14.1 */
4687# define RT_INLINE_ASM_USES_INTRIN RT_MSC_VER_VS2017
4688# elif _MSC_VER >= RT_MSC_VER_VS2015 /* Visual C++ v14.0 */
4689# define RT_INLINE_ASM_USES_INTRIN RT_MSC_VER_VS2015
4690# elif _MSC_VER >= RT_MSC_VER_VS2013 /* Visual C++ v12.0 */
4691# define RT_INLINE_ASM_USES_INTRIN RT_MSC_VER_VS2013
4692# elif _MSC_VER >= RT_MSC_VER_VS2012 /* Visual C++ v11.0 */
4693# define RT_INLINE_ASM_USES_INTRIN RT_MSC_VER_VS2012
4694# elif _MSC_VER >= RT_MSC_VER_VS2010 /* Visual C++ v10.0 */
4695# define RT_INLINE_ASM_USES_INTRIN RT_MSC_VER_VS2010
4696# elif _MSC_VER >= RT_MSC_VER_VS2008 /* Visual C++ v9.0 */
4697# define RT_INLINE_ASM_USES_INTRIN RT_MSC_VER_VS2008
4698# elif _MSC_VER >= RT_MSC_VER_VS2005 /* Visual C++ v8.0 */
4699# define RT_INLINE_ASM_USES_INTRIN RT_MSC_VER_VS2005
4700# endif
4701#endif
4702#ifndef RT_INLINE_ASM_USES_INTRIN
4703# define RT_INLINE_ASM_USES_INTRIN 0
4704#endif
4705
4706#define RT_MSC_VER_VS2012 (1700) /**< Visual Studio 2012. */
4707#define RT_MSC_VER_VC110 RT_MSC_VER_VS2012 /**< Visual C++ 11.0, aka Visual Studio 2012. */
4708#define RT_MSC_VER_VS2013 (1800) /**< Visual Studio 2013. */
4709#define RT_MSC_VER_VC120 RT_MSC_VER_VS2013 /**< Visual C++ 12.0, aka Visual Studio 2013. */
4710#define RT_MSC_VER_VS2015 (1900) /**< Visual Studio 2015. */
4711#define RT_MSC_VER_VC140 RT_MSC_VER_VS2015 /**< Visual C++ 14.0, aka Visual Studio 2015. */
4712#define RT_MSC_VER_VS2017 (1910) /**< Visual Studio 2017. */
4713#define RT_MSC_VER_VC141 RT_MSC_VER_VS2017 /**< Visual C++ 14.1, aka Visual Studio 2017. */
4714#define RT_MSC_VER_VS2019 (1920) /**< Visual Studio 2017. */
4715#define RT_MSC_VER_VC142 RT_MSC_VER_VS2019 /**< Visual C++ 14.2, aka Visual Studio 2019. */
4716
4717/** @def RT_COMPILER_SUPPORTS_LAMBDA
4718 * If the defined, the compiler supports lambda expressions. These expressions
4719 * are useful for embedding assertions and type checks into macros. */
4720#if defined(_MSC_VER) && defined(__cplusplus)
4721# if _MSC_VER >= 1600 /* Visual C++ v10.0 / 2010 */
4722# define RT_COMPILER_SUPPORTS_LAMBDA
4723# endif
4724#elif defined(__GNUC__) && defined(__cplusplus)
4725/* 4.5 or later, I think, if in ++11 mode... */
4726#endif
4727
4728/** @def RT_DATA_IS_FAR
4729 * Set to 1 if we're in 16-bit mode and use far pointers.
4730 */
4731#if ARCH_BITS == 16 && defined(__WATCOMC__) \
4732 && (defined(__COMPACT__) || defined(__LARGE__))
4733# define RT_DATA_IS_FAR 1
4734#else
4735# define RT_DATA_IS_FAR 0
4736#endif
4737
4738/** @def RT_FAR
4739 * For indicating far pointers in 16-bit code.
4740 * Does nothing in 32-bit and 64-bit code. */
4741/** @def RT_NEAR
4742 * For indicating near pointers in 16-bit code.
4743 * Does nothing in 32-bit and 64-bit code. */
4744/** @def RT_FAR_CODE
4745 * For indicating far 16-bit functions.
4746 * Does nothing in 32-bit and 64-bit code. */
4747/** @def RT_NEAR_CODE
4748 * For indicating near 16-bit functions.
4749 * Does nothing in 32-bit and 64-bit code. */
4750/** @def RT_FAR_DATA
4751 * For indicating far 16-bit external data, i.e. in a segment other than DATA16.
4752 * Does nothing in 32-bit and 64-bit code. */
4753#if ARCH_BITS == 16
4754# define RT_FAR __far
4755# define RT_NEAR __near
4756# define RT_FAR_CODE __far
4757# define RT_NEAR_CODE __near
4758# define RT_FAR_DATA __far
4759#else
4760# define RT_FAR
4761# define RT_NEAR
4762# define RT_FAR_CODE
4763# define RT_NEAR_CODE
4764# define RT_FAR_DATA
4765#endif
4766
4767
4768/** @} */
4769
4770
4771/** @defgroup grp_rt_cdefs_cpp Special Macros for C++
4772 * @ingroup grp_rt_cdefs
4773 * @{
4774 */
4775
4776#ifdef __cplusplus
4777
4778/** @def DECLEXPORT_CLASS
4779 * How to declare an exported class. Place this macro after the 'class'
4780 * keyword in the declaration of every class you want to export.
4781 *
4782 * @note It is necessary to use this macro even for inner classes declared
4783 * inside the already exported classes. This is a GCC specific requirement,
4784 * but it seems not to harm other compilers.
4785 */
4786#if defined(_MSC_VER) || defined(RT_OS_OS2)
4787# define DECLEXPORT_CLASS __declspec(dllexport)
4788#elif defined(RT_USE_VISIBILITY_DEFAULT)
4789# define DECLEXPORT_CLASS __attribute__((visibility("default")))
4790#else
4791# define DECLEXPORT_CLASS
4792#endif
4793
4794/** @def DECLIMPORT_CLASS
4795 * How to declare an imported class Place this macro after the 'class'
4796 * keyword in the declaration of every class you want to export.
4797 *
4798 * @note It is necessary to use this macro even for inner classes declared
4799 * inside the already exported classes. This is a GCC specific requirement,
4800 * but it seems not to harm other compilers.
4801 */
4802#if defined(_MSC_VER) || (defined(RT_OS_OS2) && !defined(__IBMC__) && !defined(__IBMCPP__))
4803# define DECLIMPORT_CLASS __declspec(dllimport)
4804#elif defined(RT_USE_VISIBILITY_DEFAULT)
4805# define DECLIMPORT_CLASS __attribute__((visibility("default")))
4806#else
4807# define DECLIMPORT_CLASS
4808#endif
4809
4810/** @def WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP
4811 * Macro to work around error C2593 of the not-so-smart MSVC 7.x ambiguity
4812 * resolver. The following snippet clearly demonstrates the code causing this
4813 * error:
4814 * @code
4815 * class A
4816 * {
4817 * public:
4818 * operator bool() const { return false; }
4819 * operator int*() const { return NULL; }
4820 * };
4821 * int main()
4822 * {
4823 * A a;
4824 * if (!a);
4825 * if (a && 0);
4826 * return 0;
4827 * }
4828 * @endcode
4829 * The code itself seems pretty valid to me and GCC thinks the same.
4830 *
4831 * This macro fixes the compiler error by explicitly overloading implicit
4832 * global operators !, && and || that take the given class instance as one of
4833 * their arguments.
4834 *
4835 * The best is to use this macro right after the class declaration.
4836 *
4837 * @note The macro expands to nothing for compilers other than MSVC.
4838 *
4839 * @param Cls Class to apply the workaround to
4840 */
4841#if defined(_MSC_VER)
4842# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Cls) \
4843 inline bool operator! (const Cls &that) { return !bool (that); } \
4844 inline bool operator&& (const Cls &that, bool b) { return bool (that) && b; } \
4845 inline bool operator|| (const Cls &that, bool b) { return bool (that) || b; } \
4846 inline bool operator&& (bool b, const Cls &that) { return b && bool (that); } \
4847 inline bool operator|| (bool b, const Cls &that) { return b || bool (that); }
4848#else
4849# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Cls)
4850#endif
4851
4852/** @def WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL
4853 * Version of WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP for template classes.
4854 *
4855 * @param Tpl Name of the template class to apply the workaround to
4856 * @param ArgsDecl arguments of the template, as declared in |<>| after the
4857 * |template| keyword, including |<>|
4858 * @param Args arguments of the template, as specified in |<>| after the
4859 * template class name when using the, including |<>|
4860 *
4861 * Example:
4862 * @code
4863 * // template class declaration
4864 * template <class C>
4865 * class Foo { ... };
4866 * // applied workaround
4867 * WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL (Foo, <class C>, <C>)
4868 * @endcode
4869 */
4870#if defined(_MSC_VER)
4871# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL(Tpl, ArgsDecl, Args) \
4872 template ArgsDecl \
4873 inline bool operator! (const Tpl Args &that) { return !bool (that); } \
4874 template ArgsDecl \
4875 inline bool operator&& (const Tpl Args &that, bool b) { return bool (that) && b; } \
4876 template ArgsDecl \
4877 inline bool operator|| (const Tpl Args &that, bool b) { return bool (that) || b; } \
4878 template ArgsDecl \
4879 inline bool operator&& (bool b, const Tpl Args &that) { return b && bool (that); } \
4880 template ArgsDecl \
4881 inline bool operator|| (bool b, const Tpl Args &that) { return b || bool (that); }
4882#else
4883# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL(Tpl, ArgsDecl, Args)
4884#endif
4885
4886
4887/** @def DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP
4888 * Declares the copy constructor and the assignment operation as inlined no-ops
4889 * (non-existent functions) for the given class. Use this macro inside the
4890 * private section if you want to effectively disable these operations for your
4891 * class.
4892 *
4893 * @param Cls class name to declare for
4894 */
4895#define DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(Cls) \
4896 inline Cls(const Cls &); \
4897 inline Cls &operator= (const Cls &)
4898
4899
4900/** @def DECLARE_CLS_NEW_DELETE_NOOP
4901 * Declares the new and delete operations as no-ops (non-existent functions)
4902 * for the given class. Use this macro inside the private section if you want
4903 * to effectively limit creating class instances on the stack only.
4904 *
4905 * @note The destructor of the given class must not be virtual, otherwise a
4906 * compile time error will occur. Note that this is not a drawback: having
4907 * the virtual destructor for a stack-based class is absolutely useless
4908 * (the real class of the stack-based instance is always known to the compiler
4909 * at compile time, so it will always call the correct destructor).
4910 *
4911 * @param Cls class name to declare for
4912 */
4913#define DECLARE_CLS_NEW_DELETE_NOOP(Cls) \
4914 inline static void *operator new (size_t); \
4915 inline static void operator delete (void *)
4916
4917#endif /* __cplusplus */
4918
4919/** @} */
4920
4921#endif /* !IPRT_INCLUDED_cdefs_h */
4922
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette