]>
Commit | Line | Data |
---|---|---|
842a39cd | 1 | /* Copyright (C) 2002-2012 Free Software Foundation, Inc. |
86b2dc40 UD |
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 | |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
86b2dc40 UD |
18 | |
19 | #include <sysdep.h> | |
20 | #include <tls.h> | |
a4baf360 | 21 | #ifndef __ASSEMBLER__ |
6ee8d334 UD |
22 | # include <nptl/pthreadP.h> |
23 | #endif | |
86b2dc40 | 24 | |
7a114794 | 25 | #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt |
86b2dc40 | 26 | |
6ee8d334 UD |
27 | # undef PSEUDO |
28 | # define PSEUDO(name, syscall_name, args) \ | |
86b2dc40 UD |
29 | .text; \ |
30 | ENTRY (name) \ | |
31 | cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \ | |
32 | jne L(pseudo_cancel); \ | |
8348dcc8 UD |
33 | .type __##syscall_name##_nocancel,@function; \ |
34 | .globl __##syscall_name##_nocancel; \ | |
35 | __##syscall_name##_nocancel: \ | |
86b2dc40 UD |
36 | DO_CALL (syscall_name, args); \ |
37 | cmpl $-4095, %eax; \ | |
38 | jae SYSCALL_ERROR_LABEL; \ | |
39 | ret; \ | |
8348dcc8 | 40 | .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ |
86b2dc40 | 41 | L(pseudo_cancel): \ |
6ee8d334 | 42 | CENABLE \ |
86b2dc40 | 43 | SAVE_OLDTYPE_##args \ |
09d65ff3 | 44 | PUSHCARGS_##args \ |
86b2dc40 UD |
45 | DOCARGS_##args \ |
46 | movl $SYS_ify (syscall_name), %eax; \ | |
4ae7142d | 47 | ENTER_KERNEL; \ |
09d65ff3 UD |
48 | POPCARGS_##args; \ |
49 | POPSTATE_##args \ | |
86b2dc40 | 50 | cmpl $-4095, %eax; \ |
842a39cd | 51 | jae SYSCALL_ERROR_LABEL |
86b2dc40 | 52 | |
4d961dc7 | 53 | # define SAVE_OLDTYPE_0 movl %eax, %ecx; |
e700a908 | 54 | # define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0 |
5085cd1f | 55 | # define SAVE_OLDTYPE_2 pushl %eax; cfi_adjust_cfa_offset (4); |
e700a908 UD |
56 | # define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2 |
57 | # define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2 | |
58 | # define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2 | |
11bf311e | 59 | # define SAVE_OLDTYPE_6 SAVE_OLDTYPE_2 |
6ee8d334 | 60 | |
09d65ff3 UD |
61 | # define PUSHCARGS_0 /* No arguments to push. */ |
62 | # define DOCARGS_0 /* No arguments to frob. */ | |
63 | # define POPCARGS_0 /* No arguments to pop. */ | |
64 | # define _PUSHCARGS_0 /* No arguments to push. */ | |
65 | # define _POPCARGS_0 /* No arguments to pop. */ | |
66 | ||
5085cd1f | 67 | # define PUSHCARGS_1 movl %ebx, %edx; cfi_register (ebx, edx); PUSHCARGS_0 |
e700a908 | 68 | # define DOCARGS_1 _DOARGS_1 (4) |
5085cd1f UD |
69 | # define POPCARGS_1 POPCARGS_0; movl %edx, %ebx; cfi_restore (ebx); |
70 | # define _PUSHCARGS_1 pushl %ebx; cfi_adjust_cfa_offset (4); \ | |
71 | cfi_rel_offset (ebx, 0); _PUSHCARGS_0 | |
72 | # define _POPCARGS_1 _POPCARGS_0; popl %ebx; \ | |
73 | cfi_adjust_cfa_offset (-4); cfi_restore (ebx); | |
09d65ff3 UD |
74 | |
75 | # define PUSHCARGS_2 PUSHCARGS_1 | |
6ee8d334 | 76 | # define DOCARGS_2 _DOARGS_2 (12) |
09d65ff3 UD |
77 | # define POPCARGS_2 POPCARGS_1 |
78 | # define _PUSHCARGS_2 _PUSHCARGS_1 | |
79 | # define _POPCARGS_2 _POPCARGS_1 | |
80 | ||
81 | # define PUSHCARGS_3 _PUSHCARGS_2 | |
6ee8d334 | 82 | # define DOCARGS_3 _DOARGS_3 (20) |
09d65ff3 UD |
83 | # define POPCARGS_3 _POPCARGS_3 |
84 | # define _PUSHCARGS_3 _PUSHCARGS_2 | |
85 | # define _POPCARGS_3 _POPCARGS_2 | |
86 | ||
87 | # define PUSHCARGS_4 _PUSHCARGS_4 | |
6ee8d334 | 88 | # define DOCARGS_4 _DOARGS_4 (28) |
09d65ff3 | 89 | # define POPCARGS_4 _POPCARGS_4 |
5085cd1f UD |
90 | # define _PUSHCARGS_4 pushl %esi; cfi_adjust_cfa_offset (4); \ |
91 | cfi_rel_offset (esi, 0); _PUSHCARGS_3 | |
92 | # define _POPCARGS_4 _POPCARGS_3; popl %esi; \ | |
93 | cfi_adjust_cfa_offset (-4); cfi_restore (esi); | |
09d65ff3 UD |
94 | |
95 | # define PUSHCARGS_5 _PUSHCARGS_5 | |
6ee8d334 | 96 | # define DOCARGS_5 _DOARGS_5 (36) |
09d65ff3 | 97 | # define POPCARGS_5 _POPCARGS_5 |
5085cd1f UD |
98 | # define _PUSHCARGS_5 pushl %edi; cfi_adjust_cfa_offset (4); \ |
99 | cfi_rel_offset (edi, 0); _PUSHCARGS_4 | |
100 | # define _POPCARGS_5 _POPCARGS_4; popl %edi; \ | |
101 | cfi_adjust_cfa_offset (-4); cfi_restore (edi); | |
6ee8d334 | 102 | |
11bf311e UD |
103 | # define PUSHCARGS_6 _PUSHCARGS_6 |
104 | # define DOCARGS_6 _DOARGS_6 (44) | |
105 | # define POPCARGS_6 _POPCARGS_6 | |
106 | # define _PUSHCARGS_6 pushl %ebp; cfi_adjust_cfa_offset (4); \ | |
107 | cfi_rel_offset (ebp, 0); _PUSHCARGS_5 | |
108 | # define _POPCARGS_6 _POPCARGS_5; popl %ebp; \ | |
109 | cfi_adjust_cfa_offset (-4); cfi_restore (ebp); | |
110 | ||
6ee8d334 UD |
111 | # ifdef IS_IN_libpthread |
112 | # define CENABLE call __pthread_enable_asynccancel; | |
113 | # define CDISABLE call __pthread_disable_asynccancel | |
bbde8527 | 114 | # elif !defined NOT_IN_libc |
6ee8d334 UD |
115 | # define CENABLE call __libc_enable_asynccancel; |
116 | # define CDISABLE call __libc_disable_asynccancel | |
bbde8527 UD |
117 | # elif defined IS_IN_librt |
118 | # define CENABLE call __librt_enable_asynccancel; | |
119 | # define CDISABLE call __librt_disable_asynccancel | |
120 | # else | |
121 | # error Unsupported library | |
6ee8d334 | 122 | # endif |
09d65ff3 | 123 | # define POPSTATE_0 \ |
5085cd1f UD |
124 | pushl %eax; cfi_adjust_cfa_offset (4); movl %ecx, %eax; \ |
125 | CDISABLE; popl %eax; cfi_adjust_cfa_offset (-4); | |
e700a908 | 126 | # define POPSTATE_1 POPSTATE_0 |
5085cd1f UD |
127 | # define POPSTATE_2 xchgl (%esp), %eax; CDISABLE; popl %eax; \ |
128 | cfi_adjust_cfa_offset (-4); | |
09d65ff3 UD |
129 | # define POPSTATE_3 POPSTATE_2 |
130 | # define POPSTATE_4 POPSTATE_3 | |
131 | # define POPSTATE_5 POPSTATE_4 | |
11bf311e | 132 | # define POPSTATE_6 POPSTATE_5 |
6ee8d334 | 133 | |
a4baf360 | 134 | # ifndef __ASSEMBLER__ |
bd499a3b | 135 | # define SINGLE_THREAD_P \ |
55c11fbd RM |
136 | __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ |
137 | header.multiple_threads) == 0, 1) | |
bd499a3b UD |
138 | # else |
139 | # define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET | |
140 | # endif | |
86b2dc40 | 141 | |
a4baf360 | 142 | #elif !defined __ASSEMBLER__ |
86b2dc40 | 143 | |
6e627806 | 144 | # define SINGLE_THREAD_P (1) |
ce6e047f | 145 | # define NO_CANCELLATION 1 |
86b2dc40 UD |
146 | |
147 | #endif | |
6e627806 UD |
148 | |
149 | #ifndef __ASSEMBLER__ | |
150 | # define RTLD_SINGLE_THREAD_P \ | |
151 | __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ | |
152 | header.multiple_threads) == 0, 1) | |
153 | #endif |