X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdePkg%2FInclude%2FBase.h;h=22170581a00f44f57e2affc27360f2f00d4210c5;hp=882b5a679375bc47bd8a6d167fbb15533c71c1d0;hb=6440385b17def888544c2454ffba58384b929a22;hpb=10a3840ff9edbe7038ced76c551bffd087dc4387 diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index 882b5a6793..22170581a0 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -63,6 +63,22 @@ VERIFY_SIZE_OF (UINT64, 8); VERIFY_SIZE_OF (CHAR8, 1); VERIFY_SIZE_OF (CHAR16, 2); +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 @@ -84,6 +100,117 @@ VERIFY_SIZE_OF (CHAR16, 2); #define GLOBAL_REMOVE_IF_UNREFERENCED #endif +// +// Should be used in combination with NORETURN to avoid 'noreturn' returns +// warnings. +// +#ifndef UNREACHABLE + #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4) + /// + /// 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) + #if __has_builtin (__builtin_unreachable) + /// + /// Signal compilers and analyzers that this call is not reachable. It is + /// up to the compiler to remove any code past that point. + /// + #define UNREACHABLE() __builtin_unreachable () + #endif + #endif + + #ifndef UNREACHABLE + /// + /// Signal compilers and analyzers that this call is not reachable. It is + /// up to the compiler to remove any code past that point. + /// + #define UNREACHABLE() + #endif +#endif + +// +// Signaling compilers and analyzers that a certain function cannot return may +// remove all following code and thus lead to better optimization and less +// false positives. +// +#ifndef NORETURN + #if defined (__GNUC__) || defined (__clang__) + /// + /// Signal compilers and analyzers that the function cannot return. + /// It is up to the compiler to remove any code past a call to functions + /// flagged with this attribute. + /// + #define NORETURN __attribute__((noreturn)) + #elif defined(_MSC_EXTENSIONS) && !defined(MDE_CPU_EBC) + /// + /// Signal compilers and analyzers that the function cannot return. + /// It is up to the compiler to remove any code past a call to functions + /// flagged with this attribute. + /// + #define NORETURN __declspec(noreturn) + #else + /// + /// Signal compilers and analyzers that the function cannot return. + /// It is up to the compiler to remove any code past a call to functions + /// flagged with this attribute. + /// + #define NORETURN + #endif +#endif + +// +// Should be used in combination with ANALYZER_NORETURN to avoid 'noreturn' +// returns warnings. +// +#ifndef ANALYZER_UNREACHABLE + #ifdef __clang_analyzer__ + #if __has_builtin (__builtin_unreachable) + /// + /// Signal the analyzer that this call is not reachable. + /// This excludes compilers. + /// + #define ANALYZER_UNREACHABLE() __builtin_unreachable () + #endif + #endif + + #ifndef ANALYZER_UNREACHABLE + /// + /// Signal the analyzer that this call is not reachable. + /// This excludes compilers. + /// + #define ANALYZER_UNREACHABLE() + #endif +#endif + +// +// Static Analyzers may issue errors about potential NULL-dereferences when +// dereferencing a pointer, that has been checked before, outside of a +// NULL-check. This may lead to false positives, such as when using ASSERT() +// for verification. +// +#ifndef ANALYZER_NORETURN + #ifdef __has_feature + #if __has_feature (attribute_analyzer_noreturn) + /// + /// Signal analyzers that the function cannot return. + /// This excludes compilers. + /// + #define ANALYZER_NORETURN __attribute__((analyzer_noreturn)) + #endif + #endif + + #ifndef ANALYZER_NORETURN + /// + /// Signal the analyzer that the function cannot return. + /// This excludes compilers. + /// + #define ANALYZER_NORETURN + #endif +#endif + // // For symbol name in assembly code, an extra "_" is sometimes necessary // @@ -191,7 +318,7 @@ struct _LIST_ENTRY { // // UEFI specification claims 1 and 0. We are concerned about the -// complier portability so we did it this way. +// compiler portability so we did it this way. // /// @@ -478,7 +605,31 @@ struct _LIST_ENTRY { #define VA_COPY(Dest, Start) __va_copy (Dest, Start) -#elif defined(__GNUC__) && !defined(NO_BUILTIN_VA_FUNCS) +#elif defined(__GNUC__) + +#if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS) +// +// X64 only. Use MS ABI version of GCC built-in macros for variable argument lists. +// +/// +/// Both GCC and LLVM 3.8 for X64 support new variable argument intrinsics for Microsoft ABI +/// + +/// +/// Variable used to traverse the list of arguments. This type can vary by +/// implementation and could be an array or structure. +/// +typedef __builtin_ms_va_list VA_LIST; + +#define VA_START(Marker, Parameter) __builtin_ms_va_start (Marker, Parameter) + +#define VA_ARG(Marker, TYPE) ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE))) + +#define VA_END(Marker) __builtin_ms_va_end (Marker) + +#define VA_COPY(Dest, Start) __builtin_ms_va_copy (Dest, Start) + +#else // // Use GCC built-in macros for variable argument lists. // @@ -497,6 +648,8 @@ typedef __builtin_va_list VA_LIST; #define VA_COPY(Dest, Start) __builtin_va_copy (Dest, Start) +#endif + #else /// /// Variable used to traverse the list of arguments. This type can vary by @@ -974,6 +1127,12 @@ typedef UINTN RETURN_STATUS; /// #define RETURN_WARN_STALE_DATA ENCODE_WARNING (5) +/// +/// The resulting buffer contains UEFI-compliant file system. +/// +#define RETURN_WARN_FILE_SYSTEM ENCODE_WARNING (6) + + /** Returns a 16-bit signature built from 2 ASCII characters. @@ -1027,10 +1186,10 @@ typedef UINTN RETURN_STATUS; #define SIGNATURE_64(A, B, C, D, E, F, G, H) \ (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32)) -#if defined(_MSC_EXTENSIONS) && !defined (MDE_CPU_EBC) +#if defined(_MSC_EXTENSIONS) && !defined (__INTEL_COMPILER) && !defined (MDE_CPU_EBC) #pragma intrinsic(_ReturnAddress) /** - Get the return address of the calling funcation. + Get the return address of the calling function. Based on intrinsic function _ReturnAddress that provides the address of the instruction in the calling function that will be executed after @@ -1038,27 +1197,27 @@ typedef UINTN RETURN_STATUS; @param L Return Level. - @return The return address of the calling funcation or 0 if L != 0. + @return The return address of the calling function or 0 if L != 0. **/ #define RETURN_ADDRESS(L) ((L == 0) ? _ReturnAddress() : (VOID *) 0) #elif defined(__GNUC__) void * __builtin_return_address (unsigned int level); /** - Get the return address of the calling funcation. + Get the return address of the calling function. Based on built-in Function __builtin_return_address that returns the return address of the current function, or of one of its callers. @param L Return Level. - @return The return address of the calling funcation. + @return The return address of the calling function. **/ #define RETURN_ADDRESS(L) __builtin_return_address (L) #else /** - Get the return address of the calling funcation. + Get the return address of the calling function. @param L Return Level. @@ -1068,5 +1227,18 @@ typedef UINTN RETURN_STATUS; #define RETURN_ADDRESS(L) ((VOID *) 0) #endif +/** + Return the number of elements in an array. + + @param Array An object of array type. Array is only used as an argument to + the sizeof operator, therefore Array is never evaluated. The + caller is responsible for ensuring that Array's type is not + incomplete; that is, Array must have known constant size. + + @return The number of elements in Array. The result has type UINTN. + +**/ +#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0])) + #endif