1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 EBX = 0x00
41 ECX = 0x04
42 EDX = 0x08
43 ESI = 0x0C
44 EDI = 0x10
45 EBP = 0x14
46 EAX = 0x18
47 DS = 0x1C
48 ES = 0x20
49 FS = 0x24
50 GS = 0x28
51 ORIG_EAX = 0x2C
52 EIP = 0x30
53 CS = 0x34
54 EFLAGS = 0x38
55 OLDESP = 0x3C
56 OLDSS = 0x40
57
58
59
60
61 state = 0
62 counter = 4
63 priority = 8
64 signal = 12
65 sigaction = 16 # MUST be 16 (=len of sigaction)
66 blocked = (33*16)
67
68
69
70
71 sa_handler = 0
72 sa_mask = 4
73 sa_flags = 8
74 sa_restorer = 12
75
76 ENOSYS = 38
77
78
79
80
81
82 .globl _system_call,_sys_execve
83 .globl _device_not_available, _coprocessor_error
84 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
85 .globl _double_fault,_coprocessor_segment_overrun
86 .globl _invalid_TSS,_segment_not_present,_stack_segment
87 .globl _general_protection,_reserved
88 .globl _alignment_check,_page_fault
89 .globl ret_from_sys_call
90
91 #define SAVE_ALL \
92 cld; \
93 push %gs; \
94 push %fs; \
95 push %es; \
96 push %ds; \
97 pushl %eax; \
98 pushl %ebp; \
99 pushl %edi; \
100 pushl %esi; \
101 pushl %edx; \
102 pushl %ecx; \
103 pushl %ebx; \
104 movl $0x10,%edx; \
105 mov %dx,%ds; \
106 mov %dx,%es; \
107 movl $0x17,%edx; \
108 mov %dx,%fs
109
110 .align 2
111 reschedule:
112 pushl $ret_from_sys_call
113 jmp _schedule
114 .align 2
115 _system_call:
116 pushl %eax # save orig_eax
117 SAVE_ALL
118 movl $-ENOSYS,EAX(%esp)
119 cmpl _NR_syscalls,%eax
120 jae ret_from_sys_call
121 call _sys_call_table(,%eax,4)
122 movl %eax,EAX(%esp) # save the return value
123 ret_from_sys_call:
124 cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
125 jne 2f
126 cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
127 jne 2f
128 1: cmpl $0,_need_resched
129 jne reschedule
130 movl _current,%eax
131 cmpl $0,state(%eax) # state
132 jne reschedule
133 cmpl $0,counter(%eax) # counter
134 je reschedule
135 movl $1,_need_resched
136 cmpl _task,%eax # task[0] cannot have signals
137 je 2f
138 movl $0,_need_resched
139 movl signal(%eax),%ebx
140 movl blocked(%eax),%ecx
141 notl %ecx
142 andl %ebx,%ecx
143 bsfl %ecx,%ecx
144 je 2f
145 btrl %ecx,%ebx
146 movl %ebx,signal(%eax)
147 movl %esp,%ebx
148 pushl %ebx
149 incl %ecx
150 pushl %ecx
151 call _do_signal
152 popl %ecx
153 popl %ebx
154 testl %eax, %eax
155 jne 1b # see if we need to switch tasks, or do more signals
156 2: popl %ebx
157 popl %ecx
158 popl %edx
159 popl %esi
160 popl %edi
161 popl %ebp
162 popl %eax
163 pop %ds
164 pop %es
165 pop %fs
166 pop %gs
167 addl $4,%esp # skip the orig_eax
168 iret
169
170 .align 2
171 _sys_execve:
172 lea (EIP+4)(%esp),%eax # don't forget about the return address.
173 pushl %eax
174 call _do_execve
175 addl $4,%esp
176 ret
177
178 _divide_error:
179 pushl $0 # no error code
180 pushl $_do_divide_error
181 error_code:
182 push %fs
183 push %es
184 push %ds
185 pushl %eax
186 pushl %ebp
187 pushl %edi
188 pushl %esi
189 pushl %edx
190 pushl %ecx
191 pushl %ebx
192 cld
193 movl $-1, %eax
194 xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
195 xorl %ebx,%ebx # zero ebx
196 mov %gs,%bx # get the lower order bits of gs
197 xchgl %ebx, GS(%esp) # get the address and save gs.
198 pushl %eax # push the error code
199 lea 52(%esp),%edx
200 pushl %edx
201 movl $0x10,%edx
202 mov %dx,%ds
203 mov %dx,%es
204 movl $0x17,%edx
205 mov %dx,%fs
206 call *%ebx
207 addl $8,%esp
208 jmp ret_from_sys_call
209
210 .align 2
211 _coprocessor_error:
212 pushl $0
213 pushl $_do_coprocessor_error
214 jmp error_code
215
216 .align 2
217 _device_not_available:
218 pushl $-1 # mark this as an int
219 SAVE_ALL
220 pushl $ret_from_sys_call
221 clts # clear TS so that we can use math
222 movl %cr0,%eax
223 testl $0x4,%eax # EM (math emulation bit)
224 je _math_state_restore
225 pushl $0 # temporary storage for ORIG_EIP
226 call _math_emulate
227 addl $4,%esp
228 ret
229
230 _debug:
231 pushl $0
232 pushl $_do_debug
233 jmp error_code
234
235 _nmi:
236 pushl $0
237 pushl $_do_nmi
238 jmp error_code
239
240 _int3:
241 pushl $0
242 pushl $_do_int3
243 jmp error_code
244
245 _overflow:
246 pushl $0
247 pushl $_do_overflow
248 jmp error_code
249
250 _bounds:
251 pushl $0
252 pushl $_do_bounds
253 jmp error_code
254
255 _invalid_op:
256 pushl $0
257 pushl $_do_invalid_op
258 jmp error_code
259
260 _coprocessor_segment_overrun:
261 pushl $0
262 pushl $_do_coprocessor_segment_overrun
263 jmp error_code
264
265 _reserved:
266 pushl $0
267 pushl $_do_reserved
268 jmp error_code
269
270 _double_fault:
271 pushl $_do_double_fault
272 jmp error_code
273
274 _invalid_TSS:
275 pushl $_do_invalid_TSS
276 jmp error_code
277
278 _segment_not_present:
279 pushl $_do_segment_not_present
280 jmp error_code
281
282 _stack_segment:
283 pushl $_do_stack_segment
284 jmp error_code
285
286 _general_protection:
287 pushl $_do_general_protection
288 jmp error_code
289
290 _alignment_check:
291 pushl $_do_alignment_check
292 jmp error_code
293
294 _page_fault:
295 pushl $_do_page_fault
296 jmp error_code