]>
Commit | Line | Data |
---|---|---|
c9cf6dde | 1 | /* POSIX.1 `sigaction' call for Linux/x86-64. |
bf293afe | 2 | Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. |
c9cf6dde AJ |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
19 | ||
20 | #include <sysdep.h> | |
21 | #include <errno.h> | |
22 | #include <stddef.h> | |
23 | #include <signal.h> | |
24 | #include <string.h> | |
25 | ||
26 | #include <sysdep.h> | |
27 | #include <sys/syscall.h> | |
28 | ||
29 | #include <kernel-features.h> | |
30 | ||
31 | /* The difference here is that the sigaction structure used in the | |
32 | kernel is not the same as we use in the libc. Therefore we must | |
33 | translate it here. */ | |
34 | #include <kernel_sigaction.h> | |
35 | ||
36 | /* We do not globally define the SA_RESTORER flag so do it here. */ | |
37 | #define SA_RESTORER 0x04000000 | |
38 | ||
39 | extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded, | |
40 | struct kernel_sigaction *__unbounded, size_t); | |
41 | ||
a7a2ea5a RM |
42 | /* Using the hidden attribute here does not change the code but it |
43 | helps to avoid warnings. */ | |
1ad5bec8 AJ |
44 | #if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \ |
45 | && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE | |
a7a2ea5a RM |
46 | extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; |
47 | #else | |
c9cf6dde | 48 | static void restore_rt (void) asm ("__restore_rt"); |
a7a2ea5a | 49 | #endif |
c9cf6dde AJ |
50 | |
51 | ||
52 | /* If ACT is not NULL, change the action for SIG to *ACT. | |
53 | If OACT is not NULL, put the old action for SIG in *OACT. */ | |
54 | int | |
55 | __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) | |
56 | { | |
57 | int result; | |
58 | struct kernel_sigaction kact, koact; | |
59 | ||
60 | if (act) | |
61 | { | |
62 | kact.k_sa_handler = act->sa_handler; | |
63 | memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); | |
64 | kact.sa_flags = act->sa_flags | SA_RESTORER; | |
65 | ||
66 | kact.sa_restorer = &restore_rt; | |
67 | } | |
68 | ||
69 | /* XXX The size argument hopefully will have to be changed to the | |
70 | real size of the user-level sigset_t. */ | |
71 | result = INLINE_SYSCALL (rt_sigaction, 4, | |
72 | sig, act ? __ptrvalue (&kact) : NULL, | |
73 | oact ? __ptrvalue (&koact) : NULL, _NSIG / 8); | |
74 | if (oact && result >= 0) | |
75 | { | |
76 | oact->sa_handler = koact.k_sa_handler; | |
77 | memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); | |
78 | oact->sa_flags = koact.sa_flags; | |
79 | oact->sa_restorer = koact.sa_restorer; | |
80 | } | |
81 | return result; | |
82 | } | |
5ec5c857 | 83 | libc_hidden_def (__libc_sigaction) |
bf293afe UD |
84 | |
85 | #ifndef LIBC_SIGACTION | |
c9cf6dde | 86 | weak_alias (__libc_sigaction, __sigaction) |
37ba7d66 | 87 | libc_hidden_weak (__sigaction) |
c9cf6dde | 88 | weak_alias (__libc_sigaction, sigaction) |
bf293afe | 89 | #endif |
c9cf6dde AJ |
90 | |
91 | /* NOTE: Please think twice before making any changes to the bits of | |
92 | code below. GDB needs some intimate knowledge about it to | |
93 | recognize them as signal trampolines, and make backtraces through | |
94 | signal handlers work right. Important are both the names | |
95 | (__restore_rt) and the exact instruction sequence. | |
96 | If you ever feel the need to make any changes, please notify the | |
97 | appropriate GDB maintainer. */ | |
98 | ||
99 | #define RESTORE(name, syscall) RESTORE2 (name, syscall) | |
100 | #define RESTORE2(name, syscall) \ | |
101 | asm \ | |
102 | ( \ | |
103 | ".align 16\n" \ | |
104 | "__" #name ":\n" \ | |
105 | " movq $" #syscall ", %rax\n" \ | |
106 | " syscall\n" \ | |
107 | ); | |
108 | ||
109 | /* The return code for realtime-signals. */ | |
110 | RESTORE (restore_rt, __NR_rt_sigreturn) |