From 6f333cfc914e7cfacc4d3ef3e034e4483f0ba8b2 Mon Sep 17 00:00:00 2001 From: Callum Farmer Date: Wed, 21 Jun 2023 20:27:43 +0100 Subject: [PATCH] Tail calls break ctors/dtors Add macro EFI_NO_TAIL_CALL which disables tail call optimization on a per-function basis Signed-off-by: Callum Farmer --- apps/ctors_dtors_priority_test.c | 8 ++++---- apps/ctors_fns.c | 4 ++-- inc/eficompiler.h | 10 ++++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/apps/ctors_dtors_priority_test.c b/apps/ctors_dtors_priority_test.c index 0458c08..e8a3990 100644 --- a/apps/ctors_dtors_priority_test.c +++ b/apps/ctors_dtors_priority_test.c @@ -2,22 +2,22 @@ #include // 101 in init_array, 65434 in ctors -static void __attribute__((constructor(101))) ctors101() { +static void __attribute__((constructor(101))) EFI_NO_TAIL_CALL ctors101() { Print(L"1) ctor with lower numbered priority \r\n"); } // 65434 in init_array, 101 in ctors -static void __attribute__((constructor(65434))) ctors65434() { +static void __attribute__((constructor(65434))) EFI_NO_TAIL_CALL ctors65434() { Print(L"2) ctor with higher numbered priority \r\n"); } // 101 in fini_array, 65434 in dtors -static void __attribute__((destructor(101))) dtors101() { +static void __attribute__((destructor(101))) EFI_NO_TAIL_CALL dtors101() { Print(L"4) dtor with lower numbered priority \r\n"); } // 65434 in fini_array, 101 in dtors -static void __attribute__((destructor(65434))) dtors65434() { +static void __attribute__((destructor(65434))) EFI_NO_TAIL_CALL dtors65434() { Print(L"3) dtor with higher numbered priority \r\n"); } diff --git a/apps/ctors_fns.c b/apps/ctors_fns.c index 6241904..7027447 100644 --- a/apps/ctors_fns.c +++ b/apps/ctors_fns.c @@ -9,14 +9,14 @@ int constructed_value = 0; -static void __attribute__((__constructor__)) ctor(void) +static void __attribute__((__constructor__)) EFI_NO_TAIL_CALL ctor(void) { Print(L"%a:%d:%a() constructed_value:%d\n", __FILE__, __LINE__, __func__, constructed_value); constructed_value = 1; Print(L"%a:%d:%a() constructed_value:%d\n", __FILE__, __LINE__, __func__, constructed_value); } -static void __attribute__((__destructor__)) dtor(void) +static void __attribute__((__destructor__)) EFI_NO_TAIL_CALL dtor(void) { Print(L"%a:%d:%a() constructed_value:%d\n", __FILE__, __LINE__, __func__, constructed_value); constructed_value = 0; diff --git a/inc/eficompiler.h b/inc/eficompiler.h index 26636c7..3b66eb6 100644 --- a/inc/eficompiler.h +++ b/inc/eficompiler.h @@ -18,6 +18,16 @@ Abstract: #define EFI_UNUSED __attribute__((__unused__)) #endif +#ifdef _MSC_EXTENSIONS +#define EFI_NO_TAIL_CALL +#else +#ifdef __clang__ +#define EFI_NO_TAIL_CALL __attribute__((disable_tail_calls)) +#else +#define EFI_NO_TAIL_CALL __attribute__((optimize("no-optimize-sibling-calls"))) +#endif +#endif + #ifdef _MSC_EXTENSIONS #define ALIGN(x) __declspec(align(x)) #else