From d0b03541bf89a5db76abf70eb1702bc57be89dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Tempel?= Date: Sat, 10 Feb 2024 00:13:28 +0100 Subject: [PATCH] common-trampoline: Ensure omission of frame-pointer Some architecture-specific implementations of the FETCH_LINKPTR (e.g. the one for x86) attempt to find the linkptr relative to the stack pointer. Therefore, they make assumption about the value of the SP at the point where the FETCH_LINKPTR code is executed. This means that we don't want the C compiler to mess with our SP. For this purpose, local variables in this function are currently declared using the register storage specifier. Additionally, we need to make sure that a frame pointer is /always/ omitted for this function. On x86 Alpine, the frame pointer is presently not omitted with GCC 13 when using -Os, therefore the tests segfault with -Os on Alpine presently. Fixes #52 --- arch/common/common-trampoline.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/common/common-trampoline.c b/arch/common/common-trampoline.c index 5b52327..41f994b 100644 --- a/arch/common/common-trampoline.c +++ b/arch/common/common-trampoline.c @@ -14,7 +14,19 @@ #include #include +/* We need to make sure that the C compiler doesn't push any + * additional data to the stack frame. Otherwise, assumptions + * made by the architecture-specific implementation of the + * FETCH_LINKPTR() macro about the location of the linkptr, + * relative to the stack pointer, will not hold. + * + * Hence, we compile this function with -fomit-frame-pointer + * and use the register storage-class specifier for all local + * vars. Note that the latter is just a "suggestion" (see C99). + */ + __attribute__ ((visibility ("hidden"))) +__attribute__ ((optimize ("omit-frame-pointer"))) void libucontext_trampoline(void) {