X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdePkg%2FInclude%2FBase.h;h=02140a5ac2eea335d6aa330d0e4c4b113424c229;hb=4e6fed27197a6a42a07c8bdaa3427bb181c1b99c;hp=e1ffa7d23b6434c2270a4f11885a5a126cef06cc;hpb=068a82fc5ae8f4186da92db8ba2aa3dcd1ef2d14;p=mirror_edk2.git diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index e1ffa7d23b..02140a5ac2 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -6,7 +6,7 @@ environment. There are a set of base libraries in the Mde Package that can be used to implement base modules. -Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2017, 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 @@ -27,6 +27,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // #include +#if defined(_MSC_EXTENSIONS) +// +// Disable warning when last field of data structure is a zero sized array. +// +#pragma warning ( disable : 4200 ) +#endif /** Verifies the storage size of a given data type. @@ -57,12 +63,35 @@ 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 // a non standard extension // -#if defined(_MSC_EXTENSIONS) && !defined (MDE_CPU_EBC) +#if defined(_MSC_EXTENSIONS) && _MSC_VER < 1800 && !defined (MDE_CPU_EBC) /// /// Remove global variable from the linked image if there are no references to /// it after all compiler and linker optimizations have been performed. @@ -79,22 +108,132 @@ VERIFY_SIZE_OF (CHAR16, 2); #endif // -// For symbol name in GNU assembly code, an extra "_" is necessary +// Should be used in combination with NORETURN to avoid 'noreturn' returns +// warnings. // -#if defined(__GNUC__) - /// - /// Private worker functions for ASM_PFX() - /// - #define _CONCATENATE(a, b) __CONCATENATE(a, b) - #define __CONCATENATE(a, b) a ## b +#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 - /// - /// The __USER_LABEL_PREFIX__ macro predefined by GNUC represents the prefix - /// on symbols in assembly language. - /// - #define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name) +// +// 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 +// + +/// +/// Private worker functions for ASM_PFX() +/// +#define _CONCATENATE(a, b) __CONCATENATE(a, b) +#define __CONCATENATE(a, b) a ## b + +/// +/// The __USER_LABEL_PREFIX__ macro predefined by GNUC represents the prefix +/// on symbols in assembly language. +/// +#define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name) + #if __APPLE__ // // Apple extension that is used by the linker to optimize code size @@ -126,6 +265,20 @@ typedef struct { UINT8 Data4[8]; } GUID; +/// +/// 4-byte buffer. An IPv4 internet protocol address. +/// +typedef struct { + UINT8 Addr[4]; +} IPv4_ADDRESS; + +/// +/// 16-byte buffer. An IPv6 internet protocol address. +/// +typedef struct { + UINT8 Addr[16]; +} IPv6_ADDRESS; + // // 8-bytes unsigned value that represents a physical system address. // @@ -186,7 +339,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. // /// @@ -206,6 +359,11 @@ struct _LIST_ENTRY { /// #define NULL ((VOID *) 0) +// +// Null character +// +#define CHAR_NULL 0x0000 + /// /// Maximum values for common UEFI Data Types /// @@ -473,7 +631,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. // @@ -492,6 +674,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 @@ -935,6 +1119,11 @@ typedef UINTN RETURN_STATUS; /// #define RETURN_COMPROMISED_DATA ENCODE_ERROR (33) +/// +/// A HTTP error occurred during the network operation. +/// +#define RETURN_HTTP_ERROR ENCODE_ERROR (35) + /// /// The string contained one or more characters that /// the device could not render and were skipped. @@ -964,6 +1153,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. @@ -1017,5 +1212,60 @@ 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 (__INTEL_COMPILER) && !defined (MDE_CPU_EBC) + void * _ReturnAddress(void); + #pragma intrinsic(_ReturnAddress) + /** + 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 + control returns to the caller. + + @param L Return Level. + + @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 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 function. + + **/ + #define RETURN_ADDRESS(L) __builtin_return_address (L) +#else + /** + Get the return address of the calling function. + + @param L Return Level. + + @return 0 as compilers don't support this feature. + + **/ + #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