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
41
42
43 EBX = 0x00
44 ECX = 0x04
45 EDX = 0x08
46 ESI = 0x0C
47 EDI = 0x10
48 EBP = 0x14
49 EAX = 0x18
50 DS = 0x1C
51 ES = 0x20
52 FS = 0x24
53 GS = 0x28
54 ORIG_EAX = 0x2C
55 EIP = 0x30
56 CS = 0x34
57 EFLAGS = 0x38
58 OLDESP = 0x3C
59 OLDSS = 0x40
60
61 IF_MASK = 0x00000200
62 NT_MASK = 0x00004000
63 VM_MASK = 0x00020000
64
65
66
67
68 state = 0
69 counter = 4
70 priority = 8
71 signal = 12
72 sigaction = 16 # MUST be 16 (=len of sigaction)
73 blocked = (33*16)
74 saved_kernel_stack = ((33*16)+4)
75 kernel_stack_page = ((33*16)+8)
76 flags = ((33*16)+12)
77
78
79
80
81 sa_handler = 0
82 sa_mask = 4
83 sa_flags = 8
84 sa_restorer = 12
85
86 ENOSYS = 38
87
88 .globl _system_call,_sys_execve
89 .globl _device_not_available, _coprocessor_error
90 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
91 .globl _double_fault,_coprocessor_segment_overrun
92 .globl _invalid_TSS,_segment_not_present,_stack_segment
93 .globl _general_protection,_reserved
94 .globl _alignment_check,_page_fault
95 .globl ret_from_sys_call
96
97 #define SAVE_ALL \
98 cld; \
99 push %gs; \
100 push %fs; \
101 push %es; \
102 push %ds; \
103 pushl %eax; \
104 pushl %ebp; \
105 pushl %edi; \
106 pushl %esi; \
107 pushl %edx; \
108 pushl %ecx; \
109 pushl %ebx; \
110 movl $0x10,%edx; \
111 mov %dx,%ds; \
112 mov %dx,%es; \
113 movl $0x17,%edx; \
114 mov %dx,%fs
115
116 .align 4
117 reschedule:
118 pushl $ret_from_sys_call
119 jmp _schedule
120 .align 4
121 _system_call:
122 pushl %eax # save orig_eax
123 SAVE_ALL
124 movl $-ENOSYS,EAX(%esp)
125 cmpl _NR_syscalls,%eax
126 jae ret_from_sys_call
127 movl _current,%ebx
128 testl $0x20,flags(%ebx) # PF_TRACESYS
129 je 1f
130 pushl $0
131 pushl %ebx
132 pushl $5 # SIGTRAP
133 call _send_sig
134 addl $12,%esp
135 call _schedule
136 movl ORIG_EAX(%esp),%eax
137 1: call _sys_call_table(,%eax,4)
138 movl %eax,EAX(%esp) # save the return value
139 movl _current,%eax
140 testl $0x20,flags(%eax) # PF_TRACESYS
141 je ret_from_sys_call
142 cmpl $0,signal(%eax)
143 jne ret_from_sys_call # ptrace would clear signal
144 pushl $0
145 pushl %eax
146 pushl $5 # SIGTRAP
147 call _send_sig
148 addl $12,%esp
149 call _schedule
150 .align 4,0x90
151 ret_from_sys_call:
152 movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
153 testl $VM_MASK,%eax # different then
154 jne 4f
155 cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
156 jne 2f
157 cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
158 jne 2f
159 4: sti # slow interrupts get here with interrupts disabled
160 orl $IF_MASK,%eax # these just try to make sure
161 andl $~NT_MASK,%eax # the program doesn't do anything
162 movl %eax,EFLAGS(%esp) # stupid
163 1: cmpl $0,_need_resched
164 jne reschedule
165 movl _current,%eax
166 cmpl _task,%eax # task[0] cannot have signals
167 je 2f
168 cmpl $0,state(%eax) # state
169 jne reschedule
170 cmpl $0,counter(%eax) # counter
171 je reschedule
172 movl signal(%eax),%ebx
173 movl blocked(%eax),%ecx
174 notl %ecx
175 andl %ebx,%ecx
176 je 2f # XXX - branch is almost always taken
177 bsfl %ecx,%ecx
178 btrl %ecx,signal(%eax) # change atomically (%ebx is stale)
179 jnc 2f # bit became clear (can't happen?)
180 incl %ecx
181 movl %esp,%ebx
182 testl $VM_MASK,EFLAGS(%esp)
183 je 3f
184 pushl %ebx
185 pushl %ecx
186 call _save_v86_state
187 popl %ecx
188 movl %eax,%ebx
189 movl %eax,%esp
190 3: pushl %ebx
191 pushl %ecx
192 call _do_signal
193 popl %ecx
194 popl %ebx
195 testl %eax, %eax
196 jne 1b # see if we need to switch tasks, or do more signals
197 2: popl %ebx
198 popl %ecx
199 popl %edx
200 popl %esi
201 popl %edi
202 popl %ebp
203 popl %eax
204 pop %ds
205 pop %es
206 pop %fs
207 pop %gs
208 addl $4,%esp # skip the orig_eax
209 iret
210
211 .align 4
212 _sys_execve:
213 lea (EIP+4)(%esp),%eax # don't forget about the return address.
214 pushl %eax
215 call _do_execve
216 addl $4,%esp
217 ret
218
219 .align 4
220 _divide_error:
221 pushl $0 # no error code
222 pushl $_do_divide_error
223 .align 4,0x90
224 error_code:
225 push %fs
226 push %es
227 push %ds
228 pushl %eax
229 pushl %ebp
230 pushl %edi
231 pushl %esi
232 pushl %edx
233 pushl %ecx
234 pushl %ebx
235 cld
236 movl $-1, %eax
237 xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
238 xorl %ebx,%ebx # zero ebx
239 mov %gs,%bx # get the lower order bits of gs
240 xchgl %ebx, GS(%esp) # get the address and save gs.
241 pushl %eax # push the error code
242 lea 52(%esp),%edx
243 pushl %edx
244 movl $0x10,%edx
245 mov %dx,%ds
246 mov %dx,%es
247 movl $0x17,%edx
248 mov %dx,%fs
249 call *%ebx
250 addl $8,%esp
251 jmp ret_from_sys_call
252
253 .align 4
254 _coprocessor_error:
255 pushl $0
256 pushl $_do_coprocessor_error
257 jmp error_code
258
259 .align 4
260 _device_not_available:
261 pushl $-1 # mark this as an int
262 SAVE_ALL
263 pushl $ret_from_sys_call
264 clts # clear TS so that we can use math
265 movl %cr0,%eax
266 testl $0x4,%eax # EM (math emulation bit)
267 je _math_state_restore
268 pushl $0 # temporary storage for ORIG_EIP
269 call _math_emulate
270 addl $4,%esp
271 ret
272
273 .align 4
274 _debug:
275 pushl $0
276 pushl $_do_debug
277 jmp error_code
278
279 .align 4
280 _nmi:
281 pushl $0
282 pushl $_do_nmi
283 jmp error_code
284
285 .align 4
286 _int3:
287 pushl $0
288 pushl $_do_int3
289 jmp error_code
290
291 .align 4
292 _overflow:
293 pushl $0
294 pushl $_do_overflow
295 jmp error_code
296
297 .align 4
298 _bounds:
299 pushl $0
300 pushl $_do_bounds
301 jmp error_code
302
303 .align 4
304 _invalid_op:
305 pushl $0
306 pushl $_do_invalid_op
307 jmp error_code
308
309 .align 4
310 _coprocessor_segment_overrun:
311 pushl $0
312 pushl $_do_coprocessor_segment_overrun
313 jmp error_code
314
315 .align 4
316 _reserved:
317 pushl $0
318 pushl $_do_reserved
319 jmp error_code
320
321 .align 4
322 _double_fault:
323 pushl $_do_double_fault
324 jmp error_code
325
326 .align 4
327 _invalid_TSS:
328 pushl $_do_invalid_TSS
329 jmp error_code
330
331 .align 4
332 _segment_not_present:
333 pushl $_do_segment_not_present
334 jmp error_code
335
336 .align 4
337 _stack_segment:
338 pushl $_do_stack_segment
339 jmp error_code
340
341 .align 4
342 _general_protection:
343 pushl $_do_general_protection
344 jmp error_code
345
346 .align 4
347 _alignment_check:
348 pushl $_do_alignment_check
349 jmp error_code
350
351 .align 4
352 _page_fault:
353 pushl $_do_page_fault
354 jmp error_code