1 //===-- Linux implementation of sigaltstack -------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/signal/sigaltstack.h" 10 #include "src/errno/libc_errno.h" 11 #include "src/signal/linux/signal_utils.h" 12 13 #include "src/__support/common.h" 14 15 #include <signal.h> 16 #include <sys/syscall.h> 17 18 namespace __llvm_libc { 19 20 LLVM_LIBC_FUNCTION(int, sigaltstack, 21 (const stack_t *__restrict ss, stack_t *__restrict oss)) { 22 if (ss != nullptr) { 23 unsigned not_ss_disable = ~unsigned(SS_DISABLE); 24 if ((unsigned(ss->ss_flags) & not_ss_disable) != 0) { 25 // Flags cannot have anything other than SS_DISABLE set. 26 // We do the type-casting to unsigned because the |ss_flags| 27 // field of stack_t is of type "int". 28 libc_errno = EINVAL; 29 return -1; 30 } 31 if (ss->ss_size < MINSIGSTKSZ) { 32 libc_errno = ENOMEM; 33 return -1; 34 } 35 } 36 37 int ret = __llvm_libc::syscall_impl<int>(SYS_sigaltstack, ss, oss); 38 if (ret < 0) { 39 libc_errno = -ret; 40 return -1; 41 } 42 return 0; 43 } 44 45 } // namespace __llvm_libc 46