]> sourceware.org Git - glibc.git/blob - nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
b7009d753fe3df5e05840510dea35d60089fecaf
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / sysdep-cancel.h
1 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
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 <tls.h>
22 #ifndef __ASSEMBLER__
23 # include <nptl/pthreadP.h>
24 #endif
25
26 #if !defined NOT_IN_libc || defined IS_IN_libpthread
27
28 # undef PSEUDO
29 # define PSEUDO(name, syscall_name, args) \
30 .text; \
31 ENTRY (name) \
32 L(name##START): \
33 cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \
34 jne L(pseudo_cancel); \
35 DO_CALL (syscall_name, args); \
36 cmpl $-4095, %eax; \
37 jae SYSCALL_ERROR_LABEL; \
38 ret; \
39 L(pseudo_cancel): \
40 CENABLE \
41 SAVE_OLDTYPE_##args \
42 PUSHCARGS_##args \
43 DOCARGS_##args \
44 movl $SYS_ify (syscall_name), %eax; \
45 /* Until we can handle unwinding from the sysenter page the kernel \
46 provides we cannot use ENTER_KERNEL here. */ \
47 int $0x80; \
48 POPCARGS_##args; \
49 POPSTATE_##args \
50 cmpl $-4095, %eax; \
51 jae SYSCALL_ERROR_LABEL; \
52 L(pseudo_end): \
53 \
54 /* Create unwinding information for the syscall wrapper. */ \
55 .section .eh_frame,"a",@progbits; \
56 L(STARTFRAME): \
57 /* Length of the CIE. */ \
58 .long L(ENDCIE)-L(STARTCIE); \
59 L(STARTCIE): \
60 /* CIE ID. */ \
61 .long 0; \
62 /* Version number. */ \
63 .byte 1; \
64 /* NUL-terminated augmentation string. Note "z" means there is an \
65 augmentation value later on. */ \
66 .string "zR"; \
67 /* Code alignment factor. */ \
68 .uleb128 1; \
69 /* Data alignment factor. */ \
70 .sleb128 -4; \
71 /* Return address register column. */ \
72 .byte 8; \
73 /* Augmentation value length. */ \
74 .uleb128 1; \
75 /* Encoding: DW_EH_PE_pcrel + DW_EH_PE_sdata4. */ \
76 .byte 0x1b; \
77 /* Start of the table initialization. */ \
78 .byte 0xc; \
79 .uleb128 4; \
80 .uleb128 4; \
81 .byte 0x88; \
82 .uleb128 1; \
83 .align 4; \
84 L(ENDCIE): \
85 /* Length of the FDE. */ \
86 .long L(ENDFDE)-L(STARTFDE); \
87 L(STARTFDE): \
88 /* CIE pointer. */ \
89 .long L(STARTFDE)-L(STARTFRAME); \
90 /* PC-relative start address of the code. */ \
91 .long L(name##START)-.; \
92 /* Length of the code. */ \
93 .long L(name##END)-L(name##START); \
94 /* No augmentation data. */ \
95 .uleb128 0; \
96 /* The rest of the code depends on the number of parameters the syscall \
97 takes. */ \
98 EH_FRAME_##args(name); \
99 .align 4; \
100 L(ENDFDE): \
101 .previous
102
103 /* Callframe description for syscalls without parameters. This is very
104 simple. The only place the stack pointer is changed is when the old
105 cancellation state value is saved. */
106 # define EH_FRAME_0(name) \
107 .byte 4; \
108 .long L(PUSHSTATE)-name; \
109 .byte 14; \
110 .uleb128 8; \
111 .byte 4; \
112 .long L(POPSTATE)-L(PUSHSTATE); \
113 .byte 14; \
114 .uleb128 4
115
116 /* For syscalls with one and two parameters the code is the same as for
117 those which take no parameter. */
118 # define EH_FRAME_1(name) EH_FRAME_0 (name)
119 # define EH_FRAME_2(name) EH_FRAME_1 (name)
120
121 /* For syscalls with three parameters the stack pointer is changed
122 also to save the content of the %ebx register. */
123 # define EH_FRAME_3(name) \
124 .byte 4; \
125 .long L(PUSHBX1)-name; \
126 .byte 14; \
127 .uleb128 8; \
128 .byte 4; \
129 .long L(POPBX1)-L(PUSHBX1); \
130 .byte 14; \
131 .uleb128 4; \
132 .byte 4; \
133 .long L(PUSHSTATE)-L(POPBX1); \
134 .byte 14; \
135 .uleb128 8; \
136 .byte 4; \
137 .long L(PUSHBX2)-L(PUSHSTATE); \
138 .byte 14; \
139 .uleb128 12; \
140 .byte 4; \
141 .long L(POPBX2)-L(PUSHBX2); \
142 .byte 14; \
143 .uleb128 8; \
144 .byte 4; \
145 .long L(POPSTATE)-L(POPBX2); \
146 .byte 14; \
147 .uleb128 4
148
149 /* With four parameters the syscall wrappers have to save %ebx and %esi. */
150 # define EH_FRAME_4(name) \
151 .byte 4; \
152 .long L(PUSHSI1)-name; \
153 .byte 14; \
154 .uleb128 8; \
155 .byte 4; \
156 .long L(PUSHBX1)-L(PUSHSI1); \
157 .byte 14; \
158 .uleb128 12; \
159 .byte 4; \
160 .long L(POPBX1)-L(PUSHBX1); \
161 .byte 14; \
162 .uleb128 8; \
163 .byte 4; \
164 .long L(POPSI1)-L(POPBX1); \
165 .byte 14; \
166 .uleb128 4; \
167 .byte 4; \
168 .long L(PUSHSTATE)-L(POPSI1); \
169 .byte 14; \
170 .uleb128 8; \
171 .byte 4; \
172 .long L(PUSHSI2)-L(PUSHSTATE); \
173 .byte 14; \
174 .uleb128 12; \
175 .byte 4; \
176 .long L(PUSHBX2)-L(PUSHSI2); \
177 .byte 14; \
178 .uleb128 16; \
179 .byte 4; \
180 .long L(POPBX2)-L(PUSHBX2); \
181 .byte 14; \
182 .uleb128 12; \
183 .byte 4; \
184 .long L(POPSI2)-L(POPBX2); \
185 .byte 14; \
186 .uleb128 8; \
187 .byte 4; \
188 .long L(POPSTATE)-L(POPSI2); \
189 .byte 14; \
190 .uleb128 4
191
192 /* With five parameters the syscall wrappers have to save %ebx, %esi,
193 and %edi. */
194 # define EH_FRAME_5(name) \
195 .byte 4; \
196 .long L(PUSHDI1)-name; \
197 .byte 14; \
198 .uleb128 8; \
199 .byte 4; \
200 .long L(PUSHSI1)-L(PUSHDI1); \
201 .byte 14; \
202 .uleb128 12; \
203 .byte 4; \
204 .long L(PUSHBX1)-L(PUSHSI1); \
205 .byte 14; \
206 .uleb128 16; \
207 .byte 4; \
208 .long L(POPBX1)-L(PUSHBX1); \
209 .byte 14; \
210 .uleb128 12; \
211 .byte 4; \
212 .long L(POPSI1)-L(POPBX1); \
213 .byte 14; \
214 .uleb128 8; \
215 .byte 4; \
216 .long L(POPDI1)-L(POPSI1); \
217 .byte 14; \
218 .uleb128 4; \
219 .byte 4; \
220 .long L(PUSHSTATE)-L(POPDI1); \
221 .byte 14; \
222 .uleb128 8; \
223 .byte 4; \
224 .long L(PUSHDI2)-L(PUSHSTATE); \
225 .byte 14; \
226 .uleb128 12; \
227 .byte 4; \
228 .long L(PUSHSI2)-L(PUSHDI2); \
229 .byte 14; \
230 .uleb128 16; \
231 .byte 4; \
232 .long L(PUSHBX2)-L(PUSHSI2); \
233 .byte 14; \
234 .uleb128 20; \
235 .byte 4; \
236 .long L(POPBX2)-L(PUSHBX2); \
237 .byte 14; \
238 .uleb128 16; \
239 .byte 4; \
240 .long L(POPSI2)-L(POPBX2); \
241 .byte 14; \
242 .uleb128 12; \
243 .byte 4; \
244 .long L(POPDI2)-L(POPSI2); \
245 .byte 14; \
246 .uleb128 8; \
247 .byte 4; \
248 .long L(POPSTATE)-L(POPDI2); \
249 .byte 14; \
250 .uleb128 4
251
252
253 # undef ASM_SIZE_DIRECTIVE
254 # define ASM_SIZE_DIRECTIVE(name) L(name##END): .size name,.-name;
255
256 # define SAVE_OLDTYPE_0 movl %eax, %edx;
257 # define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0
258 # define SAVE_OLDTYPE_2 pushl %eax; L(PUSHSTATE):
259 # define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2
260 # define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
261 # define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
262
263 # define PUSHCARGS_0 /* No arguments to push. */
264 # define DOCARGS_0 /* No arguments to frob. */
265 # define POPCARGS_0 /* No arguments to pop. */
266 # define _PUSHCARGS_0 /* No arguments to push. */
267 # define _POPCARGS_0 /* No arguments to pop. */
268
269 # define PUSHCARGS_1 movl %ebx, %edx; PUSHCARGS_0
270 # define DOCARGS_1 _DOARGS_1 (4)
271 # define POPCARGS_1 POPCARGS_0; movl %edx, %ebx
272 # define _PUSHCARGS_1 pushl %ebx; L(PUSHBX2): _PUSHCARGS_0
273 # define _POPCARGS_1 _POPCARGS_0; popl %ebx; L(POPBX2):
274
275 # define PUSHCARGS_2 PUSHCARGS_1
276 # define DOCARGS_2 _DOARGS_2 (12)
277 # define POPCARGS_2 POPCARGS_1
278 # define _PUSHCARGS_2 _PUSHCARGS_1
279 # define _POPCARGS_2 _POPCARGS_1
280
281 # define PUSHCARGS_3 _PUSHCARGS_2
282 # define DOCARGS_3 _DOARGS_3 (20)
283 # define POPCARGS_3 _POPCARGS_3
284 # define _PUSHCARGS_3 _PUSHCARGS_2
285 # define _POPCARGS_3 _POPCARGS_2
286
287 # define PUSHCARGS_4 _PUSHCARGS_4
288 # define DOCARGS_4 _DOARGS_4 (28)
289 # define POPCARGS_4 _POPCARGS_4
290 # define _PUSHCARGS_4 pushl %esi; L(PUSHSI2): _PUSHCARGS_3
291 # define _POPCARGS_4 _POPCARGS_3; popl %esi; L(POPSI2):
292
293 # define PUSHCARGS_5 _PUSHCARGS_5
294 # define DOCARGS_5 _DOARGS_5 (36)
295 # define POPCARGS_5 _POPCARGS_5
296 # define _PUSHCARGS_5 pushl %edi; L(PUSHDI2): _PUSHCARGS_4
297 # define _POPCARGS_5 _POPCARGS_4; popl %edi; L(POPDI2):
298
299 # ifdef IS_IN_libpthread
300 # define CENABLE call __pthread_enable_asynccancel;
301 # define CDISABLE call __pthread_disable_asynccancel
302 # else
303 # define CENABLE call __libc_enable_asynccancel;
304 # define CDISABLE call __libc_disable_asynccancel
305 # endif
306 # define POPSTATE_0 \
307 pushl %eax; L(PUSHSTATE): movl %ecx, %eax; CDISABLE; popl %eax; L(POPSTATE):
308 # define POPSTATE_1 POPSTATE_0
309 # define POPSTATE_2 xchgl (%esp), %eax; CDISABLE; popl %eax; L(POPSTATE):
310 # define POPSTATE_3 POPSTATE_2
311 # define POPSTATE_4 POPSTATE_3
312 # define POPSTATE_5 POPSTATE_4
313
314 # ifndef __ASSEMBLER__
315 # define SINGLE_THREAD_P \
316 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
317 header.multiple_threads) == 0, 1)
318 # else
319 # define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
320 # endif
321
322 #elif !defined __ASSEMBLER__
323
324 /* This code should never be used but we define it anyhow. */
325 # define SINGLE_THREAD_P (1)
326
327 #endif
This page took 0.047717 seconds and 4 git commands to generate.