Skip to content

Commit 4d35055

Browse files
committed
[libc] Add sigaction
Summary: This patch adds `sigaction` and the `sa_restorer` signal trampoline function `__restore_rt` Reviewers: sivachandra, MaskRay, PaulkaToast Reviewed By: sivachandra Subscribers: gchatelet, mgorny, tschuett, libc-commits Differential Revision: https://reviews.llvm.org/D75802
1 parent 9bca8fc commit 4d35055

File tree

11 files changed

+253
-2
lines changed

11 files changed

+253
-2
lines changed

libc/config/linux/api.td

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,28 @@ def SysMManAPI : PublicAPI<"sys/mman.h"> {
180180
];
181181
}
182182

183+
def StructSigactionDefn : TypeDecl<"struct sigaction"> {
184+
let Decl = [{
185+
struct __sigaction {
186+
union {
187+
void (*sa_handler)(int);
188+
void (*sa_action)(int, siginfo_t *, void *);
189+
};
190+
sigset_t sa_mask;
191+
int sa_flags;
192+
void (*sa_restorer)(void);
193+
};
194+
}];
195+
}
196+
183197
def SignalAPI : PublicAPI<"signal.h"> {
198+
let TypeDeclarations = [
199+
StructSigactionDefn,
200+
];
201+
184202
let Functions = [
185203
"raise",
204+
"sigaction",
186205
"sigprocmask",
187206
"sigemptyset",
188207
"sigaddset",

libc/config/linux/signal.h.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@
99
%%begin()
1010

1111
#include <linux/signal.h>
12+
13+
#ifndef __LLVM_LIBC_INTERNAL_SIGACTION
14+
#define sigaction __sigaction
15+
#endif

libc/lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ add_entrypoint_library(
1818

1919
# signal.h entrypoints
2020
raise
21+
sigaction
2122
sigaddset
2223
sigemptyset
2324
sigprocmask

libc/spec/posix.td

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ def ConstSigSetPtrType : ConstType<SigSetPtrType>;
44
def RestrictSigSetType : RestrictedPtrType<SigSetType>;
55
def ConstRestrictSigSetType : ConstType<RestrictSigSetType>;
66

7+
def StructSigaction : NamedType<"struct sigaction">;
8+
def StructSigactionPtr : PtrType<StructSigaction>;
9+
def ConstStructSigactionPtr : ConstType<StructSigactionPtr>;
10+
def RestrictStructSigactionPtr : RestrictedPtrType<StructSigaction>;
11+
def ConstRestrictStructSigactionPtr : ConstType<RestrictStructSigactionPtr>;
12+
713
def POSIX : StandardSpec<"POSIX"> {
814
NamedType OffTType = NamedType<"off_t">;
915

@@ -137,9 +143,19 @@ def POSIX : StandardSpec<"POSIX"> {
137143
HeaderSpec Signal = HeaderSpec<
138144
"signal.h",
139145
[], // Macros
140-
[], // Types
146+
[
147+
SigSetType,
148+
StructSigaction,
149+
],
141150
[], // Enumerations
142151
[
152+
FunctionSpec<
153+
"sigaction",
154+
RetValSpec<IntType>,
155+
[ArgSpec<IntType>,
156+
ArgSpec<ConstRestrictStructSigactionPtr>,
157+
ArgSpec<RestrictStructSigactionPtr>]
158+
>,
143159
FunctionSpec<
144160
"sigprocmask",
145161
RetValSpec<IntType>,

libc/spec/stdc.td

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ def StdC : StandardSpec<"stdc"> {
225225
Macro<"SIGTERM">
226226
],
227227
[
228-
NamedType<"sigset_t">,
229228
SizeTType,
230229
],
231230
[], // Enumerations

libc/src/signal/linux/CMakeLists.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,39 @@ add_entrypoint_object(
1212
signal_h
1313
)
1414

15+
add_object(
16+
__restore
17+
SRC
18+
__restore.cpp
19+
COMPILE_OPTIONS
20+
-fomit-frame-pointer
21+
-O3
22+
-Wframe-larger-than=0
23+
-Werror
24+
-Wno-attributes
25+
# asan creates asan.module_ctor which uses stack space, causing warinngs.
26+
-fno-sanitize=address
27+
DEPENDS
28+
linux_syscall_h
29+
sys_syscall_h
30+
)
31+
32+
add_entrypoint_object(
33+
sigaction
34+
SRCS
35+
sigaction.cpp
36+
HDRS
37+
signal.h
38+
../sigaction.h
39+
DEPENDS
40+
__restore
41+
sys_syscall_h
42+
linux_syscall_h
43+
signal_h
44+
SPECIAL_OBJECTS
45+
__restore
46+
)
47+
1548
add_entrypoint_object(
1649
sigprocmask
1750
SRCS
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===----------------- Linux implementation of __restore_rt ---------------===//
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+
// This file is implemented seperately from sigaction.cpp so that we can
10+
// strongly control the options this file is compiled with. __restore_rt cannot
11+
// make any stack allocations so we must ensure this.
12+
13+
#include "config/linux/syscall.h"
14+
#include "include/sys/syscall.h"
15+
16+
extern "C" void __restore_rt()
17+
__attribute__((no_sanitize("thread", "memory", "undefined", "fuzzer"),
18+
hidden));
19+
20+
extern "C" void __restore_rt() { __llvm_libc::syscall(SYS_rt_sigreturn); }
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//===----------------- Linux implementation of sigaction ------------------===//
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+
#define __LLVM_LIBC_INTERNAL_SIGACTION
10+
#include "src/signal/sigaction.h"
11+
#include "src/errno/llvmlibc_errno.h"
12+
#include "src/signal/linux/signal.h"
13+
14+
#include "src/__support/common.h"
15+
16+
namespace __llvm_libc {
17+
18+
// TOOD: Some architectures will have their signal trampoline functions in the
19+
// vdso, use those when available.
20+
21+
extern "C" void __restore_rt();
22+
23+
template <typename T, typename V>
24+
static void copySigaction(T &dest, const V &source) {
25+
dest.sa_handler = source.sa_handler;
26+
dest.sa_mask = source.sa_mask;
27+
dest.sa_flags = source.sa_flags;
28+
dest.sa_restorer = source.sa_restorer;
29+
}
30+
31+
int LLVM_LIBC_ENTRYPOINT(sigaction)(
32+
int signal, const struct __sigaction *__restrict libc_new,
33+
struct __sigaction *__restrict libc_old) {
34+
struct sigaction kernel_new;
35+
if (libc_new) {
36+
copySigaction(kernel_new, *libc_new);
37+
if (!(kernel_new.sa_flags & SA_RESTORER)) {
38+
kernel_new.sa_flags |= SA_RESTORER;
39+
kernel_new.sa_restorer = __restore_rt;
40+
}
41+
}
42+
43+
struct sigaction kernel_old;
44+
int ret = syscall(SYS_rt_sigaction, signal, libc_new ? &kernel_new : nullptr,
45+
libc_old ? &kernel_old : nullptr, sizeof(sigset_t));
46+
if (ret) {
47+
llvmlibc_errno = -ret;
48+
return -1;
49+
}
50+
51+
if (libc_old)
52+
copySigaction(*libc_old, kernel_old);
53+
return 0;
54+
}
55+
56+
} // namespace __llvm_libc

libc/src/signal/sigaction.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===------------ Implementation header for sigaction --------*- C++ -*--===//
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+
#ifndef LLVM_LIBC_SRC_SIGNAL_SIGACTION_H
10+
#define LLVM_LIBC_SRC_SIGNAL_SIGACTION_H
11+
12+
#define __LLVM_LIBC_INTERNAL_SIGACTION
13+
#include "include/signal.h"
14+
15+
namespace __llvm_libc {
16+
17+
int sigaction(int signal, const struct __sigaction *__restrict libc_new,
18+
struct __sigaction *__restrict libc_old);
19+
20+
} // namespace __llvm_libc
21+
22+
#endif // LLVM_LIBC_SRC_SIGNAL_SIGACTION_H

libc/test/src/signal/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ add_libc_unittest(
1111
signal_h
1212
)
1313

14+
add_libc_unittest(
15+
sigaction_test
16+
SUITE
17+
libc_signal_unittests
18+
SRCS
19+
sigaction_test.cpp
20+
DEPENDS
21+
sigaction
22+
raise
23+
signal_h
24+
errno_h
25+
__errno_location
26+
__restore
27+
)
28+
1429
add_libc_unittest(
1530
sigprocmask_test
1631
SUITE

0 commit comments

Comments
 (0)