brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 8c252c4 Raw
81 lines · cpp
1//===-- Unittests for 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "hdr/signal_macros.h"10#include "hdr/stdint_proxy.h"11#include "src/__support/OSUtil/syscall.h" // For internal syscall function.12#include "src/signal/linux/signal_utils.h"13#include "src/signal/raise.h"14#include "src/signal/sigaction.h"15#include "src/signal/sigaltstack.h"16#include "test/UnitTest/ErrnoCheckingTest.h"17#include "test/UnitTest/ErrnoSetterMatcher.h"18#include "test/UnitTest/Test.h"19 20#include <sys/syscall.h>21 22constexpr int LOCAL_VAR_SIZE = 512;23constexpr int ALT_STACK_SIZE = SIGSTKSZ + LOCAL_VAR_SIZE * 2;24static uint8_t alt_stack[ALT_STACK_SIZE];25 26using LlvmLibcSigaltstackTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;27using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;28using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;29 30static bool good_stack;31static void handler(int) {32  // Allocate a large stack variable so that it does not get optimized33  // out or mapped to a register.34  uint8_t var[LOCAL_VAR_SIZE];35  for (int i = 0; i < LOCAL_VAR_SIZE; ++i)36    var[i] = i;37  // Verify that array is completely on the alt_stack.38  for (int i = 0; i < LOCAL_VAR_SIZE; ++i) {39    if (!(uintptr_t(var + i) < uintptr_t(alt_stack + ALT_STACK_SIZE) &&40          uintptr_t(alt_stack) <= uintptr_t(var + i))) {41      good_stack = false;42      return;43    }44  }45  good_stack = true;46}47 48TEST_F(LlvmLibcSigaltstackTest, SigaltstackRunOnAltStack) {49  struct sigaction action;50  ASSERT_THAT(LIBC_NAMESPACE::sigaction(SIGUSR1, nullptr, &action),51              Succeeds(0));52  action.sa_handler = handler;53  // Indicate that the signal should be delivered on an alternate stack.54  action.sa_flags = SA_ONSTACK;55  ASSERT_THAT(LIBC_NAMESPACE::sigaction(SIGUSR1, &action, nullptr),56              Succeeds(0));57 58  stack_t ss;59  ss.ss_sp = alt_stack;60  ss.ss_size = ALT_STACK_SIZE;61  ss.ss_flags = 0;62  // Setup the alternate stack.63  ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss, nullptr), Succeeds(0));64 65  good_stack = false;66  LIBC_NAMESPACE::raise(SIGUSR1);67  EXPECT_TRUE(good_stack);68}69 70// This tests for invalid input.71TEST_F(LlvmLibcSigaltstackTest, SigaltstackInvalidStack) {72  stack_t ss;73  ss.ss_sp = alt_stack;74  ss.ss_size = 0;75  ss.ss_flags = SS_ONSTACK;76  ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss, nullptr), Fails(EINVAL));77 78  ss.ss_flags = 0;79  ASSERT_THAT(LIBC_NAMESPACE::sigaltstack(&ss, nullptr), Fails(ENOMEM));80}81