X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdePkg%2FInclude%2FBase.h;h=4680e64136314d1d7c2b5eaa7d25e5daaa3739e0;hb=70bebafd1b77e6edd034a12ba47656669a833a80;hp=29db8a253e2f67d701308c3e98b0c065696f6d66;hpb=2d94c38ba5e0318f9ac42c15150e6748d84587ec;p=mirror_edk2.git diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index 29db8a253e..4680e64136 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -6,15 +6,9 @@ environment. There are a set of base libraries in the Mde Package that can be used to implement base modules. -Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -34,58 +28,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #pragma warning ( disable : 4200 ) #endif -/** - Verifies the storage size of a given data type. - - This macro generates a divide by zero error or a zero size array declaration in - the preprocessor if the size is incorrect. These are declared as "extern" so - the space for these arrays will not be in the modules. - - @param TYPE The date type to determine the size of. - @param Size The expected size for the TYPE. - -**/ -#define VERIFY_SIZE_OF(TYPE, Size) extern UINT8 _VerifySizeof##TYPE[(sizeof(TYPE) == (Size)) / (sizeof(TYPE) == (Size))] - -// -// Verify that ProcessorBind.h produced UEFI Data Types that are compliant with -// Section 2.3.1 of the UEFI 2.3 Specification. -// -VERIFY_SIZE_OF (BOOLEAN, 1); -VERIFY_SIZE_OF (INT8, 1); -VERIFY_SIZE_OF (UINT8, 1); -VERIFY_SIZE_OF (INT16, 2); -VERIFY_SIZE_OF (UINT16, 2); -VERIFY_SIZE_OF (INT32, 4); -VERIFY_SIZE_OF (UINT32, 4); -VERIFY_SIZE_OF (INT64, 8); -VERIFY_SIZE_OF (UINT64, 8); -VERIFY_SIZE_OF (CHAR8, 1); -VERIFY_SIZE_OF (CHAR16, 2); - -// -// The following three enum types are used to verify that the compiler -// configuration for enum types is compliant with Section 2.3.1 of the -// UEFI 2.3 Specification. These enum types and enum values are not -// intended to be used. A prefix of '__' is used avoid conflicts with -// other types. -// -typedef enum { - __VerifyUint8EnumValue = 0xff -} __VERIFY_UINT8_ENUM_SIZE; - -typedef enum { - __VerifyUint16EnumValue = 0xffff -} __VERIFY_UINT16_ENUM_SIZE; - -typedef enum { - __VerifyUint32EnumValue = 0xffffffff -} __VERIFY_UINT32_ENUM_SIZE; - -VERIFY_SIZE_OF (__VERIFY_UINT8_ENUM_SIZE, 4); -VERIFY_SIZE_OF (__VERIFY_UINT16_ENUM_SIZE, 4); -VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4); - // // The Microsoft* C compiler can removed references to unreferenced data items // if the /OPT:REF linker option is used. We defined a macro as this is a @@ -112,11 +54,10 @@ VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4); // warnings. // #ifndef UNREACHABLE - #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4) + #ifdef __GNUC__ /// /// Signal compilers and analyzers that this call is not reachable. It is /// up to the compiler to remove any code past that point. - /// Not implemented by GCC 4.4 or earlier. /// #define UNREACHABLE() __builtin_unreachable () #elif defined (__has_feature) @@ -396,6 +337,14 @@ struct _LIST_ENTRY { #define MAX_INT64 ((INT64)0x7FFFFFFFFFFFFFFFULL) #define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL) +/// +/// Minimum values for the signed UEFI Data Types +/// +#define MIN_INT8 (((INT8) -127) - 1) +#define MIN_INT16 (((INT16) -32767) - 1) +#define MIN_INT32 (((INT32) -2147483647) - 1) +#define MIN_INT64 (((INT64) -9223372036854775807LL) - 1) + #define BIT0 0x00000001 #define BIT1 0x00000002 #define BIT2 0x00000004 @@ -660,9 +609,21 @@ struct _LIST_ENTRY { #define VA_COPY(Dest, Start) __va_copy (Dest, Start) -#elif defined(__GNUC__) +#elif defined(_M_ARM) || defined(_M_ARM64) +// +// MSFT ARM variable argument list support. +// + +typedef char* VA_LIST; + +#define VA_START(Marker, Parameter) __va_start (&Marker, &Parameter, _INT_SIZE_OF (Parameter), __alignof(Parameter), &Parameter) +#define VA_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE) + ((-(INTN)Marker) & (sizeof(TYPE) - 1))) - _INT_SIZE_OF (TYPE))) +#define VA_END(Marker) (Marker = (VA_LIST) 0) +#define VA_COPY(Dest, Start) ((void)((Dest) = (Start))) -#if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS) +#elif defined(__GNUC__) || defined(__clang__) + +#if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS) && !defined(__clang__) // // X64 only. Use MS ABI version of GCC built-in macros for variable argument lists. // @@ -765,7 +726,7 @@ typedef CHAR8 *VA_LIST; This macro initializes Dest as a copy of Start, as if the VA_START macro had been applied to Dest followed by the same sequence of uses of the VA_ARG macro as had previously been used to reach - the present state of Start. + the present state of Start. @param Dest VA_LIST used to traverse the list of arguments. @param Start VA_LIST used to traverse the list of arguments. @@ -830,6 +791,62 @@ typedef UINTN *BASE_LIST; #define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field)) #endif +/** + Portable definition for compile time assertions. + Equivalent to C11 static_assert macro from assert.h. + + @param Expression Boolean expression. + @param Message Raised compiler diagnostic message when expression is false. + +**/ +#ifdef MDE_CPU_EBC + #define STATIC_ASSERT(Expression, Message) +#elif _MSC_EXTENSIONS + #define STATIC_ASSERT static_assert +#else + #define STATIC_ASSERT _Static_assert +#endif + +// +// Verify that ProcessorBind.h produced UEFI Data Types that are compliant with +// Section 2.3.1 of the UEFI 2.3 Specification. +// + +STATIC_ASSERT (sizeof (BOOLEAN) == 1, "sizeof (BOOLEAN) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (INT8) == 1, "sizeof (INT8) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (UINT8) == 1, "sizeof (UINT8) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (INT16) == 2, "sizeof (INT16) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (UINT16) == 2, "sizeof (UINT16) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (INT32) == 4, "sizeof (INT32) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (UINT32) == 4, "sizeof (UINT32) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (INT64) == 8, "sizeof (INT64) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (UINT64) == 8, "sizeof (UINT64) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (CHAR8) == 1, "sizeof (CHAR8) does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (CHAR16) == 2, "sizeof (CHAR16) does not meet UEFI Specification Data Type requirements"); + +// +// The following three enum types are used to verify that the compiler +// configuration for enum types is compliant with Section 2.3.1 of the +// UEFI 2.3 Specification. These enum types and enum values are not +// intended to be used. A prefix of '__' is used avoid conflicts with +// other types. +// +typedef enum { + __VerifyUint8EnumValue = 0xff +} __VERIFY_UINT8_ENUM_SIZE; + +typedef enum { + __VerifyUint16EnumValue = 0xffff +} __VERIFY_UINT16_ENUM_SIZE; + +typedef enum { + __VerifyUint32EnumValue = 0xffffffff +} __VERIFY_UINT32_ENUM_SIZE; + +STATIC_ASSERT (sizeof (__VERIFY_UINT8_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (__VERIFY_UINT16_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); +STATIC_ASSERT (sizeof (__VERIFY_UINT32_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); + /** Macro that returns a pointer to the data structure that contains a specified field of that data structure. This is a lightweight method to hide information by placing a @@ -849,7 +866,7 @@ typedef UINTN *BASE_LIST; @return A pointer to the structure from one of it's elements. **/ -#define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) +#define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field))) /** Rounds a value up to the next boundary using a specified alignment. @@ -1257,7 +1274,7 @@ typedef UINTN RETURN_STATUS; **/ #define RETURN_ADDRESS(L) ((L == 0) ? _ReturnAddress() : (VOID *) 0) -#elif defined(__GNUC__) +#elif defined (__GNUC__) || defined (__clang__) void * __builtin_return_address (unsigned int level); /** Get the return address of the calling function.