From 9beca885c29c77bb901547321a5ce6fd3c9c8ee3 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 9 Mar 2021 14:40:03 -0500 Subject: Fix stdarg to work the same everywhere. This gets us the same working definition for VA_* va_* etc everywhere, and it's the same definition edk2 is using. Signed-off-by: Peter Jones --- Cryptlib/Include/OpenSslSupport.h | 125 ++++++-------------------------------- Cryptlib/Library/BaseLib.h | 16 +++++ Cryptlib/Makefile | 3 +- Cryptlib/OpenSSL/Makefile | 3 +- Make.defaults | 4 +- errlog.c | 24 ++++---- include/console.h | 2 +- include/hexdump.h | 10 +-- include/system/efistdarg.h | 15 +++++ include/system/stdarg.h | 41 ++++++++----- lib/Makefile | 3 +- lib/console.c | 12 ++-- shim.h | 23 +++++-- 13 files changed, 120 insertions(+), 161 deletions(-) create mode 100644 include/system/efistdarg.h diff --git a/Cryptlib/Include/OpenSslSupport.h b/Cryptlib/Include/OpenSslSupport.h index 6bb7ba64..1f475a32 100644 --- a/Cryptlib/Include/OpenSslSupport.h +++ b/Cryptlib/Include/OpenSslSupport.h @@ -15,6 +15,22 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef __OPEN_SSL_SUPPORT_H__ #define __OPEN_SSL_SUPPORT_H__ +#if defined(__x86_64__) +/* shim.h will check if the compiler is new enough in some other CU */ + +#if !defined(GNU_EFI_USE_EXTERNAL_STDARG) +#define GNU_EFI_USE_EXTERNAL_STDARG +#endif + +#if !defined(GNU_EFI_USE_MS_ABI) +#define GNU_EFI_USE_MS_ABI +#endif + +#ifdef NO_BUILTIN_VA_FUNCS +#undef NO_BUILTIN_VA_FUNCS +#endif +#endif + /* * Include stddef.h to avoid redefining "offsetof" */ @@ -64,113 +80,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // typedef VOID *FILE; -// -// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h -// -#if !defined(__CC_ARM) || defined(_STDARG_H) // if va_list is not already defined -/* - * These are now unconditionally #defined by GNU_EFI's efistdarg.h, - * so we should #undef them here before providing a new definition. - */ -#undef va_arg -#undef va_start -#undef va_end - -#define va_list VA_LIST -#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) - -#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_va_end (Marker) - -#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) -#define va_end(Marker) ((void)0) -#endif - // // #defines from EFI Application Toolkit required to buiild Open SSL // @@ -318,7 +227,7 @@ size_t fwrite (const void *, size_t, size_t, FILE *); char *fgets (char *, int, FILE *); int fputs (const char *, FILE *); int fprintf (FILE *, const char *, ...); -int vfprintf (FILE *, const char *, VA_LIST); +int vfprintf (FILE *, const char *, va_list); int fflush (FILE *); int fclose (FILE *); DIR *opendir (const char *); diff --git a/Cryptlib/Library/BaseLib.h b/Cryptlib/Library/BaseLib.h index 93d5c691..94b25c93 100644 --- a/Cryptlib/Library/BaseLib.h +++ b/Cryptlib/Library/BaseLib.h @@ -1,3 +1,19 @@ +#if defined(__x86_64__) +/* shim.h will check if the compiler is new enough in some other CU */ + +#if !defined(GNU_EFI_USE_EXTERNAL_STDARG) +#define GNU_EFI_USE_EXTERNAL_STDARG +#endif + +#if !defined(GNU_EFI_USE_MS_ABI) +#define GNU_EFI_USE_MS_ABI +#endif + +#ifdef NO_BUILTIN_VA_FUNCS +#undef NO_BUILTIN_VA_FUNCS +#endif +#endif + #include #include diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile index 27614618..547fd106 100644 --- a/Cryptlib/Makefile +++ b/Cryptlib/Makefile @@ -22,8 +22,7 @@ CLANG_BUGS = $(if $(findstring gcc,$(CC)),-maccumulate-outgoing-args,) ifeq ($(ARCH),x86_64) FEATUREFLAGS += -m64 -mno-mmx -mno-sse -mno-red-zone $(CLANG_BUGS) -DEFINES += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \ - -DNO_BUILTIN_VA_FUNCS -DMDE_CPU_X64 +DEFINES += -DMDE_CPU_X64 endif ifeq ($(ARCH),ia32) FEATUREFLAGS += -m32 -mno-mmx -mno-sse -mno-red-zone $(CLANG_BUGS) diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile index 294e889a..1b8ca318 100644 --- a/Cryptlib/OpenSSL/Makefile +++ b/Cryptlib/OpenSSL/Makefile @@ -36,8 +36,7 @@ CLANG_BUGS = $(if $(findstring gcc,$(CC)),-maccumulate-outgoing-args,) ifeq ($(ARCH),x86_64) FEATUREFLAGS += -m64 -mno-mmx -mno-sse -mno-red-zone $(CLANG_BUGS) -DEFINES += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \ - -UNO_BUILTIN_VA_FUNCS -DMDE_CPU_X64 +DEFINES += -DMDE_CPU_X64 endif ifeq ($(ARCH),ia32) FEATUREFLAGS += -m32 -mno-mmx -mno-sse -mno-red-zone -nostdinc $(CLANG_BUGS) diff --git a/Make.defaults b/Make.defaults index 50164ae8..f956c005 100644 --- a/Make.defaults +++ b/Make.defaults @@ -53,9 +53,7 @@ COMMIT_ID ?= $(shell if [ -e .git ] ; then git log -1 --pretty=format:%H ; elif ifeq ($(ARCH),x86_64) ARCH_CFLAGS ?= -mno-mmx -mno-sse -mno-red-zone -nostdinc \ $(CLANG_BUGS) -m64 \ - -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \ - -UNO_BUILTIN_VA_FUNCS -DMDE_CPU_X64 \ - -DPAGE_SIZE=4096 + -DMDE_CPU_X64 -DPAGE_SIZE=4096 ARCH_GNUEFI ?= x86_64 ARCH_SUFFIX ?= x64 ARCH_SUFFIX_UPPER ?= X64 diff --git a/errlog.c b/errlog.c index 16af23b0..ac657151 100644 --- a/errlog.c +++ b/errlog.c @@ -10,24 +10,26 @@ static CHAR16 **errs = NULL; static UINTN nerrs = 0; EFI_STATUS EFIAPI -vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, elf_va_list args) +vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, + va_list args) { - elf_va_list args2; + va_list args2; EFI_STATUS efi_status = EFI_SUCCESS; if (verbose) { - elf_va_copy(args2, args); + va_copy(args2, args); console_print(L"%a:%d:%a() ", file, line, func); efi_status = VPrint(fmt, args2); - elf_va_end(args2); + va_end(args2); } return efi_status; } EFI_STATUS EFIAPI -VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, elf_va_list args) +VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, + va_list args) { - elf_va_list args2; + va_list args2; CHAR16 **newerrs; newerrs = ReallocatePool(errs, (nerrs + 1) * sizeof(*errs), @@ -38,11 +40,11 @@ VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, elf_v newerrs[nerrs] = PoolPrint(L"%a:%d %a() ", file, line, func); if (!newerrs[nerrs]) return EFI_OUT_OF_RESOURCES; - elf_va_copy(args2, args); + va_copy(args2, args); newerrs[nerrs+1] = VPoolPrint(fmt, args2); if (!newerrs[nerrs+1]) return EFI_OUT_OF_RESOURCES; - elf_va_end(args2); + va_end(args2); nerrs += 2; newerrs[nerrs] = NULL; @@ -54,12 +56,12 @@ VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, elf_v EFI_STATUS EFIAPI LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...) { - elf_va_list args; + va_list args; EFI_STATUS efi_status; - elf_va_start(args, fmt); + va_start(args, fmt); efi_status = VLogError(file, line, func, fmt, args); - elf_va_end(args); + va_end(args); return efi_status; } diff --git a/include/console.h b/include/console.h index d8af3cd3..00982744 100644 --- a/include/console.h +++ b/include/console.h @@ -102,7 +102,7 @@ extern UINT32 verbose; dprint_(L"%a:%d:%a() " fmt, __FILE__, __LINE__ - 1, __func__, \ ##__VA_ARGS__) extern EFI_STATUS EFIAPI vdprint_(const CHAR16 *fmt, const char *file, int line, - const char *func, elf_va_list args); + const char *func, va_list args); #define vdprint(fmt, ...) \ vdprint_(fmt, __FILE__, __LINE__ - 1, __func__, ##__VA_ARGS__) diff --git a/include/hexdump.h b/include/hexdump.h index a6aa2bfa..f778de9a 100644 --- a/include/hexdump.h +++ b/include/hexdump.h @@ -81,7 +81,7 @@ prepare_text(const void *data, size_t size, char *buf, unsigned int position) */ static inline void UNUSED EFIAPI vhexdumpf(const char *file, int line, const char *func, const CHAR16 *const fmt, - const void *data, unsigned long size, size_t at, elf_va_list ap) + const void *data, unsigned long size, size_t at, va_list ap) { unsigned long display_offset = at; unsigned long offset = 0; @@ -114,15 +114,15 @@ vhexdumpf(const char *file, int line, const char *func, const CHAR16 *const fmt, * hexdump formatted * think of it as: printf("%s%s", format(fmt, ...), hexdump(data,size)[lineN]); */ -static inline void UNUSED +static inline void UNUSED EFIAPI hexdumpf(const char *file, int line, const char *func, const CHAR16 *const fmt, const void *data, unsigned long size, size_t at, ...) { - elf_va_list ap; + va_list ap; - elf_va_start(ap, at); + va_start(ap, at); vhexdumpf(file, line, func, fmt, data, size, at, ap); - elf_va_end(ap); + va_end(ap); } static inline void UNUSED diff --git a/include/system/efistdarg.h b/include/system/efistdarg.h new file mode 100644 index 00000000..837c4f23 --- /dev/null +++ b/include/system/efistdarg.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent +/* + * efistdarg.h - AAAARGGGG + * Copyright Peter Jones + */ + +#ifndef SHIM_UNIT_TEST +#ifndef _EFISTDARG_H_ +#define _EFISTDARG_H_ + +#include + +#endif /* !_EFISTDARG_H_ */ +#endif +// vim:fenc=utf-8:tw=75:noet diff --git a/include/system/stdarg.h b/include/system/stdarg.h index 346b760d..af1ac59b 100644 --- a/include/system/stdarg.h +++ b/include/system/stdarg.h @@ -8,24 +8,33 @@ #ifndef _STDARG_H #define _STDARG_H -#include - -#endif /* !_STDARG_H */ +#ifndef GNU_EFI_USE_EXTERNAL_STDARG +#define GNU_EFI_USE_EXTERNAL_STDARG #endif -#ifndef SHIM_STDARG_H_ -#define SHIM_STDARG_H_ -typedef __builtin_ms_va_list ms_va_list; -#define ms_va_copy(dest, start) __builtin_ms_va_copy(dest, start) -#define ms_va_start(marker, arg) __builtin_ms_va_start(marker, arg) -#define ms_va_arg(marker, type) __builtin_va_arg(marker, type) -#define ms_va_end(marker) __builtin_ms_va_end(marker) +#if defined(__aarch64__) || defined(__arm__) || defined(__i386__) || \ + defined(__i486__) || defined(__i686__) || defined(SHIM_UNIT_TEST) +typedef __builtin_va_list va_list; +#define va_copy(dest, start) __builtin_va_copy(dest, start) +#define va_start(marker, arg) __builtin_va_start(marker, arg) +#define va_arg(marker, type) __builtin_va_arg(marker, type) +#define va_end(marker) __builtin_va_end(marker) +#elif defined(__x86_64__) +typedef __builtin_ms_va_list va_list; +#define va_copy(dest, start) __builtin_ms_va_copy(dest, start) +#define va_start(marker, arg) __builtin_ms_va_start(marker, arg) +#define va_arg(marker, type) __builtin_va_arg(marker, type) +#define va_end(marker) __builtin_ms_va_end(marker) +#else +#error what arch is this +#endif -typedef __builtin_va_list elf_va_list; -#define elf_va_copy(dest, start) __builtin_va_copy(dest, start) -#define elf_va_start(marker, arg) __builtin_va_start(marker, arg) -#define elf_va_arg(marker, type) __builtin_va_arg(marker, type) -#define elf_va_end(marker) __builtin_va_end(marker) +typedef va_list VA_LIST; +#define VA_COPY(dest, start) va_copy(dest, start) +#define VA_START(marker, arg) va_start(marker, arg) +#define VA_END(marker) va_end(marker) +#define VA_ARG(marker, type) va_arg(marker, type) -#endif /* !SHIM_STDARG_H_ */ +#endif /* !_STDARG_H */ +#endif /* !SHIM_UNIT_TEST */ // vim:fenc=utf-8:tw=75:noet diff --git a/lib/Makefile b/lib/Makefile index 63893c3e..0d2d0a9d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -17,8 +17,7 @@ CLANG_BUGS = $(if $(findstring gcc,$(CC)),-maccumulate-outgoing-args,) ifeq ($(ARCH),x86_64) FEATUREFLAGS += -m64 -mno-mmx -mno-sse -mno-red-zone -nostdinc $(CLANG_BUGS) -DEFINES += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \ - -UNO_BUILTIN_VA_FUNCS -DMDE_CPU_X64 +DEFINES += -DMDE_CPU_X64 endif ifeq ($(ARCH),ia32) FEATUREFLAGS += -m32 -mno-mmx -mno-sse -mno-red-zone -nostdinc $(CLANG_BUGS) diff --git a/lib/console.c b/lib/console.c index 32c6d55d..2da20b31 100644 --- a/lib/console.c +++ b/lib/console.c @@ -86,15 +86,15 @@ VOID console_fini(VOID) UINTN EFIAPI console_print(const CHAR16 *fmt, ...) { - elf_va_list args; + va_list args; UINTN ret; if (!console_text_mode) setup_console(1); - elf_va_start(args, fmt); + va_start(args, fmt); ret = VPrint(fmt, args); - elf_va_end(args); + va_end(args); return ret; } @@ -103,7 +103,7 @@ UINTN EFIAPI console_print_at(UINTN col, UINTN row, const CHAR16 *fmt, ...) { SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut; - elf_va_list args; + va_list args; UINTN ret; if (!console_text_mode) @@ -111,9 +111,9 @@ console_print_at(UINTN col, UINTN row, const CHAR16 *fmt, ...) co->SetCursorPosition(co, col, row); - elf_va_start(args, fmt); + va_start(args, fmt); ret = VPrint(fmt, args); - elf_va_end(args); + va_end(args); return ret; } diff --git a/shim.h b/shim.h index 3d2ac2d4..0ea182eb 100644 --- a/shim.h +++ b/shim.h @@ -17,20 +17,29 @@ #endif #if defined(__x86_64__) -#if !defined(GNU_EFI_USE_MS_ABI) -#error On x86_64 you must use ms_abi (GNU_EFI_USE_MS_ABI) in gnu-efi and shim. -#endif /* gcc 4.5.4 is the first documented release with -mabi=ms */ #if !GNUC_PREREQ(4, 7) && !CLANG_PREREQ(3, 4) #error On x86_64 you must have a compiler new enough to support __attribute__((__ms_abi__)) #endif + +#if !defined(GNU_EFI_USE_EXTERNAL_STDARG) +#define GNU_EFI_USE_EXTERNAL_STDARG +#endif + +#if !defined(GNU_EFI_USE_MS_ABI) +#define GNU_EFI_USE_MS_ABI +#endif + +#ifdef NO_BUILTIN_VA_FUNCS +#undef NO_BUILTIN_VA_FUNCS +#endif #endif #include #include #include #include -#include +#include #include #include @@ -40,6 +49,10 @@ #undef uefi_call_wrapper #include #include + +#if defined(__x86_64__) && !defined(HAVE_USE_MS_ABI) +#error something has gone wrong with the gnu-efi includes and defines +#endif #endif #ifdef SHIM_UNIT_TEST @@ -209,7 +222,7 @@ extern void shim_fini(void); extern EFI_STATUS EFIAPI LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...); extern EFI_STATUS EFIAPI VLogError(const char *file, int line, const char *func, - const CHAR16 *fmt, elf_va_list args); + const CHAR16 *fmt, va_list args); extern VOID LogHexdump_(const char *file, int line, const char *func, const void *data, size_t sz); extern VOID PrintErrors(VOID); -- cgit v1.2.3