]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/uclibc/lib/contrib/uclibc/docs/sigaction.txt
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / contrib / uclibc / docs / sigaction.txt
1         All what you never wanted to know about sigaction(),
2         struct sigaction, and sigset_t.
3
4
5 Before vda started messing with sigset_t, struct sigaction
6 and sigaction() functions, things looked this way:
7
8
9         Structures
10
11 MIPS:
12
13 Ignoring bogus "#if defined(__mips__) ..." block in
14 libc/sysdeps/linux/common/bits/kernel_sigaction.h
15 and using
16 libc/sysdeps/linux/mips/bits/kernel_sigaction.h
17 as an authoritative source:
18
19 HAVE_SA_RESTORER is #defined
20 struct old_kernel_sigaction {
21         unsigned      sa_flags;
22         sighandler_t  k_sa_handler;
23         unsigned long sa_mask;
24         unsigned      pad0[3]; /* reserved, keep size constant */
25         /* Abi says here follows reserved int[2] */
26         void          (*sa_restorer)(void);
27 #if (_MIPS_SZPTR < 64)
28         /* For 32 bit code we have to pad struct sigaction to get
29          * constant size for the ABI */
30         int           pad1[1]; /* reserved */
31 #endif
32 };
33 struct kernel_sigaction {
34         unsigned int  sa_flags;
35         sighandler_t  k_sa_handler;
36         kernel_sigset_t sa_mask;
37         void          (*sa_restorer)(void);
38         int           s_resv[1]; /* reserved */
39 };
40 struct sigaction {
41         unsigned      sa_flags;
42         sighandler_t  sa_handler;
43         sigset_t      sa_mask;
44         /* The ABI says here are two unused ints following. */
45         /* Restore handler.  */
46         void          (*sa_restorer)(void);
47 #if _MIPS_SZPTR < 64
48         int           sa_resv[1];
49 #endif
50 };
51
52 IA64:
53
54 Has no old_sigaction. What a relief.
55
56 struct kernel_sigaction {
57         sighandler_t  k_sa_handler;
58         unsigned long sa_flags;
59         sigset_t      sa_mask;
60 };
61 struct sigaction {
62         sighandler_t  sa_handler;
63         unsigned long sa_flags;
64         sigset_t      sa_mask;
65 };
66
67 Alpha:
68
69 struct old_kernel_sigaction {
70         sighandler_t  k_sa_handler;
71         unsigned long sa_mask;
72         unsigned      sa_flags;
73 };
74 struct kernel_sigaction {
75         sighandler_t  k_sa_handler;
76         unsigned      sa_flags;
77         sigset_t      sa_mask;
78 };
79 struct sigaction {
80         sighandler_t  sa_handler;
81         sigset_t      sa_mask;
82         unsigned      sa_flags;
83 };
84
85 HPPA:
86
87 struct kernel_sigaction {
88         sighandler_t  k_sa_handler;
89         unsigned long sa_flags;
90         sigset_t      sa_mask;
91 };
92 struct sigaction {
93         sighandler_t  sa_handler;
94         unsigned long sa_flags;
95         sigset_t      sa_mask;
96 };
97
98 The rest, kernel side:
99
100 HAVE_SA_RESTORER #defined
101 struct old_kernel_sigaction {
102         sighandler_t  k_sa_handler;
103         unsigned long sa_mask;
104         unsigned long sa_flags;
105         void          (*sa_restorer)(void);
106 };
107 struct kernel_sigaction {
108         sighandler_t  k_sa_handler;
109         unsigned long sa_flags;
110         void          (*sa_restorer)(void);
111         sigset_t      sa_mask;
112 };
113
114 On userspace side, Sparc has special struct sigaction:
115
116 struct sigaction {
117         sighandler_t  sa_handler;
118         sigset_t      sa_mask;
119         unsigned long sa_flags;
120         void          (*sa_restorer)(void); /* Not used by Linux/Sparc */
121 };
122
123 And finally the rest has:
124
125 struct sigaction {
126         sighandler_t  sa_handler;
127         sigset_t      sa_mask;
128         int           sa_flags;
129         void          (*sa_restorer)(void);
130 };
131
132 Userspace sigset_t was uniformly defined as vector of longs
133 big enough to hold 1024 (!) bits - carried over from glibc.
134 Since the only arch whose struct kernel_sigaction contains sa_mask
135 not as a last member is MIPS, MIPS has special kernel_sigset_t,
136 which is an array of longs long enough for 128 bits.
137 Other arches still used userspace sigset_t in struct kernel_sigaction,
138 but it did not really matter because overlong kernel_sigaction
139 does not hurt in sigaction() [explained below].
140 On kernel side, all arches define _NSIG to 65 (meaning
141 there are 64 signals, 1..64) except MIPS, which define it to 129.
142
143
144         Functions
145
146 sigaction() [libc function] usually has two kernel_sigaction's
147 on stack and copy (userspace) struct sigaction members into
148 first one, executes syscall, then pulls out the result from
149 second one. This accomodates differences in layouts of structs.
150
151 The only typically present quirk is what to do with sa_restorer.
152
153     libc/sysdeps/linux/arm/sigaction.c
154
155 if HAVE_SA_RESTORER and (sa_flags & SA_RESTORER) is not set,
156 sets sa_restorer to
157 (flags & SA_SIGINFO) ? __default_rt_sa_restorer : __default_sa_restorer,
158 and sets SA_RESTORER,
159 otherwise passes it as-is. Which is kinda strange, because AFAICS
160 HAVE_SA_RESTORER is *not* defined for ARM.
161
162     libc/sysdeps/linux/i386/sigaction.c
163
164 Forcibly sets SA_RESTORER and sa_restorer:
165 kact.sa_flags = act->sa_flags | SA_RESTORER;
166 kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore);
167
168     libc/sysdeps/linux/x86_64/sigaction.c
169
170 Forcibly sets SA_RESTORER and sa_restorer:
171 kact.sa_flags = act->sa_flags | SA_RESTORER;
172 kact.sa_restorer = &restore_rt;
173
174     libc/sysdeps/linux/mips/sigaction.c
175
176 # ifdef HAVE_SA_RESTORER
177 #  if _MIPS_SIM == _ABIO32
178                 kact.sa_restorer = act->sa_restorer;
179 #  else
180                 kact.sa_restorer = &restore_rt;
181 #  endif
182 # endif
183 No confusion here, HAVE_SA_RESTORER is #defined for MIPS
184
185     libc/sysdeps/linux/avr32/sigaction.c
186
187 if (kact.sa_flags & SA_RESTORER) {
188         kact.sa_restorer = act->sa_restorer;
189 } else {
190         kact.sa_restorer = __default_rt_sa_restorer;
191         kact.sa_flags |= SA_RESTORER;
192 }
193 Does not check HAVE_SA_RESTORER, but avr32 falls
194 in "completely ordinary" category on both kernel and
195 userspace sides, and those have it defined.
196
197     libc/sysdeps/linux/xtensa/sigaction.c
198
199 if (kact.sa_flags & SA_RESTORER) {
200         kact.sa_restorer = act->sa_restorer;
201 } else {
202         kact.sa_restorer = __default_sa_restorer;
203         kact.sa_flags |= SA_RESTORER;
204 }
205 Thus, similar to avr32.
206
207     libc/signal/sigaction.c (i.e. the all other arches)
208
209 # ifdef HAVE_SA_RESTORER
210         kact.sa_restorer = act->sa_restorer;
211 # endif
212 Plain translation, just sa_restorer copy is protected
213 by HAVE_SA_RESTORER #define check. Looks like here
214 HAVE_SA_RESTORER will be undef'ed only for IA64,
215 Alpha an HPPA.
216
217
218         Proposed overhaul past 0.9.30
219
220 Since we can define libc-side structures at will:
221 make sigset_t and struct sigaction identical on kernel side and libc side
222 within each arch. If arches do not need special handling of sa_restorer,
223 then sigaction() can directly use passed struct sigaction as-is.
224 Otherwise, a copy is still needed, although sigaction() might have
225 just one struct kernel_sigaction on stack and use it both for passing
226 data to kernel and for receiving it back. Might save a few bytes.
227
228 To this effect:
229
230 * Make sigset_t size match kernel side on all arches.
231   This is easy since all arches have 64 signals and only MIPS has 128.
232
233 * Modify libc/sysdeps/linux/$ARCH/bits/sigaction.h
234   so that its struct sigaction matches kernel's. If sa_restorer
235   field is present in libc but is missing in kernel_sigaction,
236   add it at the bottom in order to not mess up kernel_sigaction layout.
237
238 * Modify libc/sysdeps/linux/$ARCH/sigaction.c
239   to implement the logic above. In "common" pseudo-arch
240   (libc/signal/sigaction.c file),
241   we would not even need to do any copying, as described above.
242
243 * Document discovered arch quirks while debugging this mess.
244
245 * struct old_kernel_sigaction can't be disposed of in a similar way,
246   we need to have userspace struct sigaction unchanged regardless
247   whether we use "old" or "new" kernel sigaction() syscall.
248   It's moot anyway because "old" one is long unused, it's from
249   pre-2.2 kernels.