From b74c635bfd5d131f2848ce2cd2ffc838dc616ee8 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Tue, 27 Oct 2015 12:00:13 +0800 Subject: [PATCH] Cryptlib: Define the va functions for EFIAPI It turned out that my previous crash fix(*) was wrong. We actually always used the gcc built-in va functions instead of the "real" va functions for EFIAPI, and we are just lucky that ERR_add_error_data didn't crash before. This commit copies the va functions from MdePkg/Include/Base.h in edk2 and introdues NO_BUILTIN_VA_FUNCS for x86_64, so that all the x86_64 build will adopt the new va functions. For safety, I also added EFIAPI to all the functions which use va_* to avoid the potential trouble. (*) a7f4b26cc35204165bd04e75c34e8e7aa2a87ecc Signed-off-by: Gary Ching-Pang Lin --- Cryptlib/Include/OpenSslSupport.h | 75 +++++++++++++++++++++++++++++++++++ Cryptlib/Include/openssl/bio.h | 8 ++++ Cryptlib/Include/openssl/err.h | 4 -- Cryptlib/Makefile | 2 +- Cryptlib/OpenSSL/Makefile | 3 +- Cryptlib/OpenSSL/crypto/bio/b_print.c | 8 ++++ Cryptlib/OpenSSL/crypto/cryptlib.c | 4 ++ Cryptlib/OpenSSL/crypto/cryptlib.h | 4 ++ Cryptlib/OpenSSL/crypto/err/err.c | 4 -- Makefile | 1 + 10 files changed, 103 insertions(+), 10 deletions(-) diff --git a/Cryptlib/Include/OpenSslSupport.h b/Cryptlib/Include/OpenSslSupport.h index e5e1adc..004c3e8 100644 --- a/Cryptlib/Include/OpenSslSupport.h +++ b/Cryptlib/Include/OpenSslSupport.h @@ -47,6 +47,9 @@ typedef VOID *FILE; #define va_arg VA_ARG #define va_start VA_START #define va_end VA_END + +# if !defined(NO_BUILTIN_VA_FUNCS) + typedef __builtin_va_list VA_LIST; #define VA_START(Marker, Parameter) __builtin_va_start (Marker, Parameter) @@ -57,6 +60,78 @@ typedef __builtin_va_list VA_LIST; #define VA_COPY(Dest, Start) __builtin_va_copy (Dest, Start) +# else + +#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1)) +/// +/// Variable used to traverse the list of arguments. This type can vary by +/// implementation and could be an array or structure. +/// +typedef CHAR8 *VA_LIST; + +/** + Retrieves a pointer to the beginning of a variable argument list, based on + the name of the parameter that immediately precedes the variable argument list. + + This function initializes Marker to point to the beginning of the variable + argument list that immediately follows Parameter. The method for computing the + pointer to the next argument in the argument list is CPU-specific following the + EFIAPI ABI. + + @param Marker The VA_LIST used to traverse the list of arguments. + @param Parameter The name of the parameter that immediately precedes + the variable argument list. + + @return A pointer to the beginning of a variable argument list. + +**/ +#define VA_START(Marker, Parameter) (Marker = (VA_LIST) ((UINTN) & (Parameter) + _INT_SIZE_OF (Parameter))) + +/** + Returns an argument of a specified type from a variable argument list and updates + the pointer to the variable argument list to point to the next argument. + + This function returns an argument of the type specified by TYPE from the beginning + of the variable argument list specified by Marker. Marker is then updated to point + to the next argument in the variable argument list. The method for computing the + pointer to the next argument in the argument list is CPU-specific following the EFIAPI ABI. + + @param Marker VA_LIST used to traverse the list of arguments. + @param TYPE The type of argument to retrieve from the beginning + of the variable argument list. + + @return An argument of the type specified by TYPE. + +**/ +#define VA_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE)) - _INT_SIZE_OF (TYPE))) + +/** + Terminates the use of a variable argument list. + + This function initializes Marker so it can no longer be used with VA_ARG(). + After this macro is used, the only way to access the variable argument list is + by using VA_START() again. + + @param Marker VA_LIST used to traverse the list of arguments. + +**/ +#define VA_END(Marker) (Marker = (VA_LIST) 0) + +/** + Initializes a VA_LIST as a copy of an existing 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. + + @param Dest VA_LIST used to traverse the list of arguments. + @param Start VA_LIST used to traverse the list of arguments. + +**/ +#define VA_COPY(Dest, Start) ((void)((Dest) = (Start))) + +# endif + #else // __CC_ARM #define va_start(Marker, Parameter) __va_start(Marker, Parameter) #define va_arg(Marker, TYPE) __va_arg(Marker, TYPE) diff --git a/Cryptlib/Include/openssl/bio.h b/Cryptlib/Include/openssl/bio.h index 561ae2f..69bd48c 100644 --- a/Cryptlib/Include/openssl/bio.h +++ b/Cryptlib/Include/openssl/bio.h @@ -787,11 +787,19 @@ void BIO_copy_next_retry(BIO *b); # else # define __bio_h__attr__(x) # endif +# if defined(OPENSSL_SYS_UEFI) +int EFIAPI BIO_printf(BIO *bio, const char *format, ...) +# else int BIO_printf(BIO *bio, const char *format, ...) +# endif __bio_h__attr__((__format__(__printf__, 2, 3))); int BIO_vprintf(BIO *bio, const char *format, va_list args) __bio_h__attr__((__format__(__printf__, 2, 0))); +# if defined(OPENSSL_SYS_UEFI) +int EFIAPI BIO_snprintf(char *buf, size_t n, const char *format, ...) +# else int BIO_snprintf(char *buf, size_t n, const char *format, ...) +# endif __bio_h__attr__((__format__(__printf__, 3, 4))); int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) __bio_h__attr__((__format__(__printf__, 3, 0))); diff --git a/Cryptlib/Include/openssl/err.h b/Cryptlib/Include/openssl/err.h index da589f8..bbfdb95 100644 --- a/Cryptlib/Include/openssl/err.h +++ b/Cryptlib/Include/openssl/err.h @@ -352,11 +352,7 @@ void EFIAPI ERR_add_error_data(int num, ...); void ERR_add_error_data(int num, ...); #endif -#if defined(OPENSSL_SYS_UEFI) -void EFIAPI ERR_add_error_vdata(int num, va_list args); -#else void ERR_add_error_vdata(int num, va_list args); -#endif void ERR_load_strings(int lib, ERR_STRING_DATA str[]); void ERR_unload_strings(int lib, ERR_STRING_DATA str[]); void ERR_load_ERR_strings(void); diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile index 9a92304..c9cf379 100644 --- a/Cryptlib/Makefile +++ b/Cryptlib/Makefile @@ -7,7 +7,7 @@ CFLAGS = -ggdb -O0 -I. -fno-stack-protector -fno-strict-aliasing -fpic -fshort- ifeq ($(ARCH),x86_64) CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args \ - -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI + -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -DNO_BUILTIN_VA_FUNCS endif ifeq ($(ARCH),ia32) CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args -m32 diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile index ab6e7dd..f8055fd 100644 --- a/Cryptlib/OpenSSL/Makefile +++ b/Cryptlib/OpenSSL/Makefile @@ -7,7 +7,8 @@ CFLAGS = -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-st ifeq ($(ARCH),x86_64) CFLAGS += -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \ - -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -DSIXTY_FOUR_BIT_LONG + -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -DSIXTY_FOUR_BIT_LONG \ + -DNO_BUILTIN_VA_FUNCS endif ifeq ($(ARCH),ia32) CFLAGS += -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \ diff --git a/Cryptlib/OpenSSL/crypto/bio/b_print.c b/Cryptlib/OpenSSL/crypto/bio/b_print.c index 9091d56..4695827 100644 --- a/Cryptlib/OpenSSL/crypto/bio/b_print.c +++ b/Cryptlib/OpenSSL/crypto/bio/b_print.c @@ -751,7 +751,11 @@ doapr_outch(char **sbuffer, /***************************************************************************/ +#if defined(OPENSSL_SYS_UEFI) +int EFIAPI BIO_printf(BIO *bio, const char *format, ...) +#else int BIO_printf(BIO *bio, const char *format, ...) +#endif { va_list args; int ret; @@ -795,7 +799,11 @@ int BIO_vprintf(BIO *bio, const char *format, va_list args) * closely related to BIO_printf, and we need *some* name prefix ... (XXX the * function should be renamed, but to what?) */ +#if defined(OPENSSL_SYS_UEFI) +int EFIAPI BIO_snprintf(char *buf, size_t n, const char *format, ...) +#else int BIO_snprintf(char *buf, size_t n, const char *format, ...) +#endif { va_list args; int ret; diff --git a/Cryptlib/OpenSSL/crypto/cryptlib.c b/Cryptlib/OpenSSL/crypto/cryptlib.c index ca0e3cc..0a59342 100644 --- a/Cryptlib/OpenSSL/crypto/cryptlib.c +++ b/Cryptlib/OpenSSL/crypto/cryptlib.c @@ -962,7 +962,11 @@ void OPENSSL_showfatal(const char *fmta, ...) MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONSTOP); } #else +# if defined(OPENSSL_SYS_UEFI) +void EFIAPI OPENSSL_showfatal(const char *fmta, ...) +# else void OPENSSL_showfatal(const char *fmta, ...) +# endif { va_list ap; diff --git a/Cryptlib/OpenSSL/crypto/cryptlib.h b/Cryptlib/OpenSSL/crypto/cryptlib.h index fba180a..7ca4c99 100644 --- a/Cryptlib/OpenSSL/crypto/cryptlib.h +++ b/Cryptlib/OpenSSL/crypto/cryptlib.h @@ -100,7 +100,11 @@ extern "C" { void OPENSSL_cpuid_setup(void); extern unsigned int OPENSSL_ia32cap_P[]; +# if defined(OPENSSL_SYS_UEFI) +void EFIAPI OPENSSL_showfatal(const char *fmta, ...); +# else void OPENSSL_showfatal(const char *fmta, ...); +# endif void *OPENSSL_stderr(void); extern int OPENSSL_NONPIC_relocated; diff --git a/Cryptlib/OpenSSL/crypto/err/err.c b/Cryptlib/OpenSSL/crypto/err/err.c index 108b83a..f98cce6 100644 --- a/Cryptlib/OpenSSL/crypto/err/err.c +++ b/Cryptlib/OpenSSL/crypto/err/err.c @@ -1085,11 +1085,7 @@ void ERR_add_error_data(int num, ...) va_end(args); } -#if defined(OPENSSL_SYS_UEFI) -void EFIAPI ERR_add_error_vdata(int num, va_list args) -#else void ERR_add_error_vdata(int num, va_list args) -#endif { int i, n, s; char *str, *p, *a; diff --git a/Makefile b/Makefile index 2449fe4..b36e2a3 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ ifeq ($(ARCH),x86_64) CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc \ -maccumulate-outgoing-args \ -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \ + -DNO_BUILTIN_VA_FUNCS \ "-DEFI_ARCH=L\"x64\"" \ "-DDEBUGDIR=L\"/usr/lib/debug/usr/share/shim/x64-$(VERSION)$(RELEASE)/\"" endif -- 2.6.2