# --- T2-COPYRIGHT-NOTE-BEGIN --- # T2 SDE: architecture/sparc/package/*/sparc-sigreturn.patch # Copyright (C) 2020 - 2022 The T2 SDE Project # # This Copyright note is generated by scripts/Create-CopyPatch, # more information can be found in the files COPYING and README. # # This patch file is dual-licensed. It is available under the license the # patched project is licensed under, as long as it is an OpenSource license # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms # of the GNU General Public License version 2 as used by the T2 SDE. # --- T2-COPYRIGHT-NOTE-END --- From 300540f2b486257284b079303e0207417d7c2d8a Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Thu, 5 Mar 2020 13:38:24 -0300 Subject: [PATCH 63/63] sparc: Move sigreturn stub to assembly It seems that some gcc versions might generates a stack frame for the sigreturn stub requires on sparc signal handling. For instance: $ cat test.c #define _GNU_SOURCE #include __attribute__ ((__optimize__ ("-fno-stack-protector"))) void __sigreturn_stub (void) { __asm__ ("mov %0, %%g1\n\t" "ta 0x10\n\t" : /* no outputs */ : "i" (SYS_rt_sigreturn)); } $ gcc -v [...] gcc version 9.2.1 20200224 (Debian 9.2.1-30) $ gcc -O2 -m64 test.c -S -o - [...] __sigreturn_stub: save %sp, -176, %sp #APP ! 9 "t.c" 1 mov 101, %g1 ta 0x10 ! 0 "" 2 #NO_APP .size __sigreturn_stub, .-__sigreturn_stub As indicated by kernel developers [1], the sigreturn stub can not change the register window or the stack pointer since the kernel has setup the restore frame at a precise location relative to the stack pointer when the stub is invoked. I tried to play with some compiler flags and even with _Noreturn and __builtin_unreachable after the asm does not help (and Sparc does not support naked functions). To avoid similar issues, as the stack-protector support also have stumbled, this patch moves the implementation of the sigreturn stubs to assembly. Checked on sparcv9-linux-gnu and sparc64-linux-gnu with gcc 9.2.1 and gcc 7.5.0. [1] https://lkml.org/lkml/2016/5/27/465 Signed-off-by: Sergei Trofimovich --- sysdeps/unix/sysv/linux/sparc/Makefile | 8 +++-- .../unix/sysv/linux/sparc/sparc32/sigaction.c | 26 ++------------ .../sysv/linux/sparc/sparc32/sigreturn_stub.S | 34 +++++++++++++++++++ .../unix/sysv/linux/sparc/sparc64/sigaction.c | 14 ++------ .../sysv/linux/sparc/sparc64/sigreturn_stub.S | 29 ++++++++++++++++ 5 files changed, 73 insertions(+), 38 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S --- glibc-2.22/sysdeps/unix/sysv/linux/sparc/Makefile.vanilla 2022-07-15 16:01:38.995102741 +0200 +++ glibc-2.22/sysdeps/unix/sysv/linux/sparc/Makefile 2022-07-15 16:01:50.016102302 +0200 @@ -4,6 +4,10 @@ abi-64-options := -D__sparc_v9__ -D__arch64__ abi-64-condition := __WORDSIZE == 64 +ifeq ($(subdir),signal) +sysdep_routines += sigreturn_stub +endif + ifeq ($(subdir),rt) librt-routines += rt-sysdep endif @@ -14,5 +18,5 @@ ifeq ($(subdir),nptl) # pull in __syscall_error routine -libpthread-routines += sysdep +libpthread-routines += sysdep sigreturn_stub endif --- glibc-2.22/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c.vanilla 2022-07-15 16:02:16.059101263 +0200 +++ glibc-2.22/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c 2022-07-15 16:02:29.960100709 +0200 @@ -28,7 +28,8 @@ /* SPARC 64bit userland requires a kernel that has rt signals anyway. */ -static void __rt_sigreturn_stub (void); +/* Defined on sigreturn_stub.S. */ +void __rt_sigreturn_stub (void); int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) @@ -64,13 +65,3 @@ libc_hidden_def (__libc_sigaction) #include - - -static void -__rt_sigreturn_stub (void) -{ - __asm__ ("mov %0, %%g1\n\t" - "ta 0x6d\n\t" - : /* no outputs */ - : "i" (__NR_rt_sigreturn)); -} --- glibc-2.22/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c.vanilla 2022-07-15 16:02:45.899100073 +0200 +++ glibc-2.22/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c 2022-07-15 16:02:51.856099836 +0200 @@ -63,22 +63,3 @@ libc_hidden_def (__libc_sigaction) #include - - -static void -__rt_sigreturn_stub (void) -{ - __asm__ ("mov %0, %%g1\n\t" - "ta 0x10\n\t" - : /* no outputs */ - : "i" (__NR_rt_sigreturn)); -} - -static void -__sigreturn_stub (void) -{ - __asm__ ("mov %0, %%g1\n\t" - "ta 0x10\n\t" - : /* no outputs */ - : "i" (__NR_sigreturn)); -} diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S new file mode 100644 index 0000000000..727cc94737 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S @@ -0,0 +1,34 @@ +/* Sigreturn stub function used on sa_restore field. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +/* These functions must not change the register window or the stack + pointer [1]. + + [1] https://lkml.org/lkml/2016/5/27/465 */ + +ENTRY (__rt_sigreturn_stub) + mov __NR_rt_sigreturn, %g1 + ta 0x10 +END (__rt_sigreturn_stub) + +ENTRY (__sigreturn_stub) + mov __NR_sigreturn, %g1 + ta 0x10 +END (__sigreturn_stub) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S new file mode 100644 index 0000000000..add4766831 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S @@ -0,0 +1,29 @@ +/* Sigreturn stub function used on sa_restore field. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +/* This function must not change the register window or the stack + pointer [1]. + + [1] https://lkml.org/lkml/2016/5/27/465 */ + +ENTRY (__rt_sigreturn_stub) + mov __NR_rt_sigreturn, %g1 + ta 0x6d +END (__rt_sigreturn_stub) -- 2.26.0