mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 23:51:56 +00:00
[libc] Add Initial Support for Signals
Summary: This patch adds signal support on Linux. The current implementation gets the SIG* macros and types like `sigset_t` from <linux/signals.h> This patch also adds raise(3), and internal routines `block_all_signals` and `restore_signals` Reviewers: sivachandra, MaskRay, gchatelet Reviewed By: sivachandra Subscribers: libc-commits, mgorny, tschuett Differential Revision: https://reviews.llvm.org/D74528
This commit is contained in:
parent
064cd2ecdb
commit
5d2baa956a
@ -133,3 +133,13 @@ def SysMManAPI : PublicAPI<"sys/mman.h"> {
|
||||
"munmap",
|
||||
];
|
||||
}
|
||||
|
||||
def SignalAPI : PublicAPI<"signal.h"> {
|
||||
let TypeDeclarations = [
|
||||
SizeT, // This is needed by <linux/signal.h>.
|
||||
];
|
||||
|
||||
let Functions = [
|
||||
"raise",
|
||||
];
|
||||
}
|
||||
|
11
libc/config/linux/signal.h.in
Normal file
11
libc/config/linux/signal.h.in
Normal file
@ -0,0 +1,11 @@
|
||||
//===---------------- Linux specific signal.h definitions -----------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
%%begin()
|
||||
|
||||
#include <linux/signal.h>
|
@ -45,6 +45,16 @@ add_gen_header(
|
||||
../config/${LIBC_TARGET_OS}/errno.h.in
|
||||
)
|
||||
|
||||
add_gen_header(
|
||||
signal_h
|
||||
DEF_FILE signal.h.def
|
||||
PARAMS
|
||||
platform_signal=../config/${LIBC_TARGET_OS}/signal.h.in
|
||||
GEN_HDR signal.h
|
||||
DATA_FILES
|
||||
../config/${LIBC_TARGET_OS}/signal.h.in
|
||||
)
|
||||
|
||||
# TODO: Not all platforms will have a include/sys directory. Add the sys
|
||||
# directory and the targets for sys/*.h files conditional to the OS requiring
|
||||
# them.
|
||||
|
18
libc/include/signal.h.def
Normal file
18
libc/include/signal.h.def
Normal file
@ -0,0 +1,18 @@
|
||||
//===---------------- C standard library header signal.h ------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SIGNAL_H
|
||||
#define LLVM_LIBC_SIGNAL_H
|
||||
|
||||
#include <__llvm-libc-common.h>
|
||||
|
||||
%%public_api()
|
||||
|
||||
%%include_file(${platform_signal})
|
||||
|
||||
#endif // LLVM_LIBC_SIGNAL_H
|
@ -12,6 +12,9 @@ add_entrypoint_library(
|
||||
# sys/mman.h entrypoints
|
||||
mmap
|
||||
munmap
|
||||
|
||||
# signal.h entrypoints
|
||||
raise
|
||||
)
|
||||
|
||||
add_entrypoint_library(
|
||||
|
@ -67,8 +67,53 @@ def Linux : StandardSpec<"Linux"> {
|
||||
[] // Functions
|
||||
>;
|
||||
|
||||
HeaderSpec Signal = HeaderSpec<
|
||||
"signal.h",
|
||||
[
|
||||
Macro<"NSIG">,
|
||||
|
||||
Macro<"SIGHUP">,
|
||||
Macro<"SIGINT">,
|
||||
Macro<"SIGQUIT">,
|
||||
Macro<"SIGILL">,
|
||||
Macro<"SIGTRAP">,
|
||||
Macro<"SIGABRT">,
|
||||
Macro<"SIGIOT">,
|
||||
Macro<"SIGBUS">,
|
||||
Macro<"SIGFPE">,
|
||||
Macro<"SIGKILL">,
|
||||
Macro<"SIGUSR1">,
|
||||
Macro<"SIGSEGV">,
|
||||
Macro<"SIGUSR2">,
|
||||
Macro<"SIGPIPE">,
|
||||
Macro<"SIGALRM">,
|
||||
Macro<"SIGTERM">,
|
||||
Macro<"SIGSTKFLT">,
|
||||
Macro<"SIGCHLD">,
|
||||
Macro<"SIGCONT">,
|
||||
Macro<"SIGSTOP">,
|
||||
Macro<"SIGTSTP">,
|
||||
Macro<"SIGTTIN">,
|
||||
Macro<"SIGTTOU">,
|
||||
Macro<"SIGURG">,
|
||||
Macro<"SIGXCPU">,
|
||||
Macro<"SIGXFSZ">,
|
||||
Macro<"SIGVTALRM">,
|
||||
Macro<"SIGPROF">,
|
||||
Macro<"SIGWINCH">,
|
||||
Macro<"SIGIO">,
|
||||
Macro<"SIGPOLL">,
|
||||
Macro<"SIGPWR">,
|
||||
Macro<"SIGSYS">,
|
||||
Macro<"SIGUNUSED">,
|
||||
],
|
||||
[], // Types
|
||||
[] // Functions
|
||||
>;
|
||||
|
||||
let Headers = [
|
||||
Errno,
|
||||
SysMMan,
|
||||
Signal,
|
||||
];
|
||||
}
|
||||
|
@ -179,10 +179,34 @@ def StdC : StandardSpec<"stdc"> {
|
||||
[] // Functions
|
||||
>;
|
||||
|
||||
HeaderSpec Signal = HeaderSpec<
|
||||
"signal.h",
|
||||
[
|
||||
Macro<"SIG_BLOCK">,
|
||||
Macro<"SIG_UNBLOCK">,
|
||||
Macro<"SIG_SETMASK">,
|
||||
|
||||
Macro<"SIGABRT">,
|
||||
Macro<"SIGFPE">,
|
||||
Macro<"SIGILL">,
|
||||
Macro<"SIGINT">,
|
||||
Macro<"SIGSEGV">,
|
||||
Macro<"SIGTERM">
|
||||
],
|
||||
[
|
||||
NamedType<"sigset_t">,
|
||||
SizeTType,
|
||||
],
|
||||
[
|
||||
FunctionSpec<"raise", RetValSpec<IntType>, [ArgSpec<IntType>]>,
|
||||
]
|
||||
>;
|
||||
|
||||
let Headers = [
|
||||
Errno,
|
||||
Math,
|
||||
String,
|
||||
StdIO,
|
||||
Signal,
|
||||
];
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
add_subdirectory(errno)
|
||||
add_subdirectory(math)
|
||||
add_subdirectory(signal)
|
||||
add_subdirectory(string)
|
||||
# TODO: Add this target conditional to the target OS.
|
||||
add_subdirectory(sys)
|
||||
|
4
libc/src/signal/CMakeLists.txt
Normal file
4
libc/src/signal/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
|
||||
add_subdirectory(${LIBC_TARGET_OS})
|
||||
endif()
|
14
libc/src/signal/linux/CMakeLists.txt
Normal file
14
libc/src/signal/linux/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
add_entrypoint_object(
|
||||
raise
|
||||
SRCS
|
||||
raise.cpp
|
||||
HDRS
|
||||
signal.h
|
||||
../raise.h
|
||||
DEPENDS
|
||||
sys_syscall_h
|
||||
linux_syscall_h
|
||||
__errno_location
|
||||
signal_h
|
||||
)
|
26
libc/src/signal/linux/raise.cpp
Normal file
26
libc/src/signal/linux/raise.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
//===------------------ Linux implementation of signal --------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/signal/raise.h"
|
||||
#include "src/signal/linux/signal.h"
|
||||
|
||||
#include "src/__support/common.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
int LLVM_LIBC_ENTRYPOINT(raise)(int sig) {
|
||||
__llvm_libc::Sigset sigset;
|
||||
int got = __llvm_libc::block_all_signals(sigset);
|
||||
long pid = __llvm_libc::syscall(SYS_getpid);
|
||||
long tid = __llvm_libc::syscall(SYS_gettid);
|
||||
int ret = __llvm_libc::syscall(SYS_tgkill, pid, tid, sig);
|
||||
__llvm_libc::restore_signals(sigset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
49
libc/src/signal/linux/signal.h
Normal file
49
libc/src/signal/linux/signal.h
Normal file
@ -0,0 +1,49 @@
|
||||
//===----------------- Internal header for Linux signals ------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_H
|
||||
#define LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_H
|
||||
|
||||
#include "config/linux/syscall.h" // For internal syscall function.
|
||||
#include "include/sys/syscall.h" // For syscall numbers.
|
||||
|
||||
#include "include/signal.h"
|
||||
|
||||
static_assert(sizeof(sigset_t) * 8 >= NSIG, "sigset_t cannot hold all signals");
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
// Using this internally defined type will make it easier in the future to port
|
||||
// to different architectures.
|
||||
struct Sigset {
|
||||
sigset_t nativeSigset;
|
||||
|
||||
constexpr static Sigset fullset() { return {-1UL}; }
|
||||
|
||||
operator sigset_t() const { return nativeSigset; }
|
||||
};
|
||||
|
||||
constexpr static Sigset all = Sigset::fullset();
|
||||
|
||||
static inline int block_all_signals(Sigset &set) {
|
||||
sigset_t nativeSigset = all;
|
||||
sigset_t oldSet = set;
|
||||
return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_BLOCK, &nativeSigset,
|
||||
&oldSet, sizeof(sigset_t));
|
||||
}
|
||||
|
||||
static inline int restore_signals(const Sigset &set) {
|
||||
sigset_t nativeSigset = set;
|
||||
return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_SETMASK,
|
||||
&nativeSigset, nullptr,
|
||||
sizeof(sigset_t));
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_H
|
20
libc/src/signal/raise.h
Normal file
20
libc/src/signal/raise.h
Normal file
@ -0,0 +1,20 @@
|
||||
//===------------- Implementation header for raise function ------ *-C++-* ===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_SIGNAL_RAISE_H
|
||||
#define LLVM_LIBC_SRC_SIGNAL_RAISE_H
|
||||
|
||||
#include "include/signal.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
int raise(int sig);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_SIGNAL_RAISE_H
|
@ -1,3 +1,4 @@
|
||||
add_subdirectory(errno)
|
||||
add_subdirectory(signal)
|
||||
add_subdirectory(string)
|
||||
add_subdirectory(sys)
|
||||
|
12
libc/test/src/signal/CMakeLists.txt
Normal file
12
libc/test/src/signal/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
add_libc_testsuite(libc_signal_unittests)
|
||||
|
||||
add_libc_unittest(
|
||||
raise_test
|
||||
SUITE
|
||||
libc_signal_unittests
|
||||
SRCS
|
||||
raise_test.cpp
|
||||
DEPENDS
|
||||
raise
|
||||
signal_h
|
||||
)
|
17
libc/test/src/signal/raise_test.cpp
Normal file
17
libc/test/src/signal/raise_test.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
//===----------------------- Unittests for raise --------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/signal.h"
|
||||
#include "src/signal/raise.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
TEST(SignalTest, Raise) {
|
||||
// SIGCONT is ingored unless stopped, so we can use it to check the return
|
||||
// value of raise without needing to block.
|
||||
EXPECT_EQ(__llvm_libc::raise(SIGCONT), 0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user