From 5244f47e46709b22ecefcee8e52b6dc6170ed6c9 Mon Sep 17 00:00:00 2001 From: darylm503 Date: Thu, 1 Sep 2011 21:56:45 +0000 Subject: StdLib: Fix build errors caused by differences between the minGW 4.3 and GCC 4.4 compilers. There are several significant differences between the mingw32 (gcc 4.3.0 based) compiler and the GCC 4.4 and later compilers. Mingw32 requires that types int, long, long long, unsigned { int, long, long long}, float, and double be the only types passed to va_arg(). This requires the programmer to ensure that va_arg is called with type int for arguments of any type with a size less-than or equal-to int. GCC 4.4 and later does not require this and performs the appropriate promotions for you. Mingw32 uses 32-bit long in both ia32 and x64 mode. GCC 4.4 makes long a 64-bit value when in x64 mode. Signed-off-by: darylm503 Reviewed-by: jcarsey git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12258 6f19259b-4bc3-4df7-8a09-765794883524 --- StdLib/Include/X64/machine/limits.h | 31 +++++++++++++++++++++++-------- StdLib/Include/X64/machine/types.h | 14 +++++--------- StdLib/Include/sys/EfiCdefs.h | 27 ++++++++++++++++++++++----- StdLib/LibC/Stdio/vfwprintf.c | 11 ++++++++--- 4 files changed, 58 insertions(+), 25 deletions(-) (limited to 'StdLib') diff --git a/StdLib/Include/X64/machine/limits.h b/StdLib/Include/X64/machine/limits.h index 144549c..193ce36 100644 --- a/StdLib/Include/X64/machine/limits.h +++ b/StdLib/Include/X64/machine/limits.h @@ -3,22 +3,37 @@ #define __POINTER_BIT 64 #if defined(__GNUC__) -#define __LONG_BIT 64 -/** minimum value for an object of type long int **/ -#define __LONG_MIN (-9223372036854775807LL - 1LL) // -(2^63 - 1) +#if __GNUC_PREREQ__(4,4) + #define __LONG_BIT 64 -/** maximum value for an object of type long int **/ -#define __LONG_MAX +9223372036854775807LL // 2^63 - 1 + /** minimum value for an object of type long int **/ + #define __LONG_MIN (-9223372036854775807LL - 1LL) // -(2^63 - 2) -/** maximum value for an object of type unsigned long int **/ -#define __ULONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1 + /** maximum value for an object of type long int **/ + #define __LONG_MAX (9223372036854775807LL) // 2^63 - 1 + + /** maximum value for an object of type unsigned long int **/ + #define __ULONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1 #else + #define __LONG_BIT 32 + /** minimum value for an object of type long int **/ + #define __LONG_MIN (-2147483647L - 1L) // -(2^31 - 1) + + /** maximum value for an object of type long int **/ + #define __LONG_MAX 2147483647L // 2^31 - 1 + + /** maximum value for an object of type unsigned long int **/ + #define __ULONG_MAX 0xffffffff // 2^32 - 1 +#endif + + +#else /* NOT defined(__GNUC__) */ #define __LONG_BIT 32 /** minimum value for an object of type long int **/ #define __LONG_MIN (-2147483647L - 1L) // -(2^31 - 1) /** maximum value for an object of type long int **/ -#define __LONG_MAX +2147483647L // 2^31 - 1 +#define __LONG_MAX 2147483647L // 2^31 - 1 /** maximum value for an object of type unsigned long int **/ #define __ULONG_MAX 0xffffffff // 2^32 - 1 diff --git a/StdLib/Include/X64/machine/types.h b/StdLib/Include/X64/machine/types.h index 1c1f1ab..f14625b 100644 --- a/StdLib/Include/X64/machine/types.h +++ b/StdLib/Include/X64/machine/types.h @@ -1,11 +1,11 @@ /** @file Machine dependent type definitions. - Portions Copyright (c) 2010, Intel Corporation. All rights reserved.
- This program and the accompanying materials are licensed and made available - under the terms and conditions of the BSD License that accompanies this - distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. + Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License that accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @@ -46,10 +46,6 @@ #include #include -/* Handle the long and unsigned long data types which EFI doesn't directly support. */ -//typedef long int LONGN; // 32-bit -//typedef long unsigned int ULONGN; // 32-bit - typedef PHYSICAL_ADDRESS paddr_t; typedef UINT64 psize_t; typedef PHYSICAL_ADDRESS vaddr_t; diff --git a/StdLib/Include/sys/EfiCdefs.h b/StdLib/Include/sys/EfiCdefs.h index c3a2772..812a495 100644 --- a/StdLib/Include/sys/EfiCdefs.h +++ b/StdLib/Include/sys/EfiCdefs.h @@ -102,6 +102,7 @@ //#define _EFI_WINT_MIN (0) //#define _EFI_WINT_MAX (0xFFFF) #define _EFI_PTRDIFF_T_ __PTRDIFF_TYPE__ /* ptr1 - ptr2 --- Must be same size as size_t */ + #else #define _EFI_SIZE_T_ UINTN /* sizeof() */ #define _EFI_WCHAR_T UINT16 @@ -338,13 +339,29 @@ extern int _fltused; // VC++ requires this if you use floating point. KEEP f #define _DIAGASSERT(e) // Types used to replace long so that it will have constant length regardless of compiler. -typedef INT32 EFI_LONG_T; // Equivalent to long in VS200? -typedef UINT32 EFI_ULONG_T; // Equivalent to unsigned long in VS200? -typedef INTN LONGN; -typedef UINTN ULONGN; -typedef INT32 LONG32; +typedef INT32 LONG32; typedef UINT32 ULONG32; typedef INT64 LONG64; typedef UINT64 ULONG64; +typedef INT32 EFI_LONG_T; +typedef UINT32 EFI_ULONG_T; + +/* These types reflect the compiler's size for long */ +#if defined(__GNUC__) + #if __GNUC_PREREQ__(4,4) + /* GCC 4.4 or later */ + typedef INT64 LONGN; + typedef UINT64 ULONGN; + #else + /* minGW gcc variant */ + typedef INT32 LONGN; + typedef UINT32 ULONGN; + #endif /* __GNUC_PREREQ__(4,4) */ +#else /* NOT GCC */ + /* Microsoft or Intel compilers */ + typedef INT32 LONGN; + typedef UINT32 ULONGN; +#endif /* defined(__GNUC__) */ + #endif /* _EFI_CDEFS_H */ diff --git a/StdLib/LibC/Stdio/vfwprintf.c b/StdLib/LibC/Stdio/vfwprintf.c index 0554edb..f5cf394 100644 --- a/StdLib/LibC/Stdio/vfwprintf.c +++ b/StdLib/LibC/Stdio/vfwprintf.c @@ -1003,7 +1003,12 @@ reswitch: switch (ch) { mbs = initial; mbseqlen = wcrtomb(buf, - (wchar_t)GETARG(wint_t), &mbs); + /* The compiler "knows" that wint_t may be smaller than an int so + it warns about it when used as the type argument to va_arg(). + Since any type of parameter smaller than an int is promoted to an int on a + function call, we must call GETARG with type int instead of wint_t. + */ + (wchar_t)GETARG(int), &mbs); if (mbseqlen == (size_t)-1) { fp->_flags |= __SERR; goto error; @@ -1015,7 +1020,7 @@ reswitch: switch (ch) { } #else if (flags & LONGINT) - *buf = (wchar_t)GETARG(wint_t); + *buf = (wchar_t)GETARG(int); else *buf = (wchar_t)btowc(GETARG(int)); size = 1; @@ -1915,7 +1920,7 @@ done: (*argtable) [n].pvoidarg = va_arg (ap, void *); break; case T_WINT: - (*argtable) [n].wintarg = va_arg (ap, wint_t); + (*argtable) [n].wintarg = va_arg (ap, int); break; case TP_WCHAR: (*argtable) [n].pwchararg = va_arg (ap, wchar_t *); -- cgit v1.1