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 #include <linux/segment.h>
44 #include <linux/sys.h>
45
46 EBX = 0x00
47 ECX = 0x04
48 EDX = 0x08
49 ESI = 0x0C
50 EDI = 0x10
51 EBP = 0x14
52 EAX = 0x18
53 DS = 0x1C
54 ES = 0x20
55 FS = 0x24
56 GS = 0x28
57 ORIG_EAX = 0x2C
58 EIP = 0x30
59 CS = 0x34
60 EFLAGS = 0x38
61 OLDESP = 0x3C
62 OLDSS = 0x40
63
64 CF_MASK = 0x00000001
65 IF_MASK = 0x00000200
66 NT_MASK = 0x00004000
67 VM_MASK = 0x00020000
68
69
70
71
72 state = 0
73 counter = 4
74 priority = 8
75 signal = 12
76 blocked = 16
77 flags = 20
78 errno = 24
79 dbgreg6 = 52
80 dbgreg7 = 56
81 lcall7 = 60
82
83 ENOSYS = 38
84
85 .globl _system_call,_lcall7
86 .globl _device_not_available, _coprocessor_error
87 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
88 .globl _double_fault,_coprocessor_segment_overrun
89 .globl _invalid_TSS,_segment_not_present,_stack_segment
90 .globl _general_protection,_reserved
91 .globl _alignment_check,_page_fault
92 .globl ret_from_sys_call, _sys_call_table
93
94 #define SAVE_ALL \
95 cld; \
96 push %gs; \
97 push %fs; \
98 push %es; \
99 push %ds; \
100 pushl %eax; \
101 pushl %ebp; \
102 pushl %edi; \
103 pushl %esi; \
104 pushl %edx; \
105 pushl %ecx; \
106 pushl %ebx; \
107 movl $(KERNEL_DS),%edx; \
108 mov %dx,%ds; \
109 mov %dx,%es; \
110 movl $(USER_DS),%edx; \
111 mov %dx,%fs;
112
113 #define RESTORE_ALL \
114 cmpw $(KERNEL_CS),CS(%esp); \
115 je 1f; \
116 movl _current,%eax; \
117 movl dbgreg7(%eax),%ebx; \
118 movl %ebx,%db7; \
119 1: popl %ebx; \
120 popl %ecx; \
121 popl %edx; \
122 popl %esi; \
123 popl %edi; \
124 popl %ebp; \
125 popl %eax; \
126 pop %ds; \
127 pop %es; \
128 pop %fs; \
129 pop %gs; \
130 addl $4,%esp; \
131 iret
132
133 .align 4
134 _lcall7:
135 pushfl # We get a different stack layout with call gates,
136 pushl %eax # which has to be cleaned up later..
137 SAVE_ALL
138 movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
139 movl CS(%esp),%edx # this is eip..
140 movl EFLAGS(%esp),%ecx # and this is cs..
141 movl %eax,EFLAGS(%esp) #
142 movl %edx,EIP(%esp) # Now we move them to their "normal" places
143 movl %ecx,CS(%esp) #
144 movl %esp,%eax
145 movl _current,%edx
146 pushl %eax
147 movl lcall7(%edx),%edx
148 call *%edx
149 popl %eax
150 jmp ret_from_sys_call
151
152 .align 4
153 handle_bottom_half:
154 pushfl
155 incl _intr_count
156 sti
157 call _do_bottom_half
158 popfl
159 decl _intr_count
160 jmp 9f
161 .align 4
162 reschedule:
163 pushl $ret_from_sys_call
164 jmp _schedule
165 .align 4
166 _system_call:
167 pushl %eax # save orig_eax
168 SAVE_ALL
169 movl $-ENOSYS,EAX(%esp)
170 cmpl $(NR_syscalls),%eax
171 jae ret_from_sys_call
172 movl _sys_call_table(,%eax,4),%eax
173 testl %eax,%eax
174 je ret_from_sys_call
175 movl _current,%ebx
176 andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors
177 movl $0,errno(%ebx)
178 movl %db6,%edx
179 movl %edx,dbgreg6(%ebx) # save current hardware debugging status
180 testb $0x20,flags(%ebx) # PF_TRACESYS
181 jne 1f
182 call *%eax
183 movl %eax,EAX(%esp) # save the return value
184 movl errno(%ebx),%edx
185 negl %edx
186 je ret_from_sys_call
187 movl %edx,EAX(%esp)
188 orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error
189 jmp ret_from_sys_call
190 .align 4
191 1: call _syscall_trace
192 movl ORIG_EAX(%esp),%eax
193 call _sys_call_table(,%eax,4)
194 movl %eax,EAX(%esp) # save the return value
195 movl _current,%eax
196 movl errno(%eax),%edx
197 negl %edx
198 je 1f
199 movl %edx,EAX(%esp)
200 orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error
201 1: call _syscall_trace
202
203 .align 4,0x90
204 ret_from_sys_call:
205 cmpl $0,_intr_count
206 jne 2f
207 movl _bh_mask,%eax
208 andl _bh_active,%eax
209 jne handle_bottom_half
210 9: movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
211 testl $(VM_MASK),%eax # different then
212 jne 1f
213 cmpw $(KERNEL_CS),CS(%esp) # was old code segment supervisor ?
214 je 2f
215 1: sti
216 orl $(IF_MASK),%eax # these just try to make sure
217 andl $~NT_MASK,%eax # the program doesn't do anything
218 movl %eax,EFLAGS(%esp) # stupid
219 cmpl $0,_need_resched
220 jne reschedule
221 movl _current,%eax
222 cmpl _task,%eax # task[0] cannot have signals
223 je 2f
224 cmpl $0,state(%eax) # state
225 jne reschedule
226 cmpl $0,counter(%eax) # counter
227 je reschedule
228 movl blocked(%eax),%ecx
229 movl %ecx,%ebx # save blocked in %ebx for signal handling
230 notl %ecx
231 andl signal(%eax),%ecx
232 jne signal_return
233 2: RESTORE_ALL
234 .align 4
235 signal_return:
236 movl %esp,%ecx
237 pushl %ecx
238 testl $(VM_MASK),EFLAGS(%ecx)
239 jne v86_signal_return
240 pushl %ebx
241 call _do_signal
242 popl %ebx
243 popl %ebx
244 RESTORE_ALL
245 .align 4
246 v86_signal_return:
247 call _save_v86_state
248 movl %eax,%esp
249 pushl %eax
250 pushl %ebx
251 call _do_signal
252 popl %ebx
253 popl %ebx
254 RESTORE_ALL
255
256 .align 4
257 _divide_error:
258 pushl $0 # no error code
259 pushl $_do_divide_error
260 .align 4,0x90
261 error_code:
262 push %fs
263 push %es
264 push %ds
265 pushl %eax
266 pushl %ebp
267 pushl %edi
268 pushl %esi
269 pushl %edx
270 pushl %ecx
271 pushl %ebx
272 movl $0,%eax
273 movl %eax,%db7 # disable hardware debugging...
274 cld
275 movl $-1, %eax
276 xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
277 xorl %ebx,%ebx # zero ebx
278 mov %gs,%bx # get the lower order bits of gs
279 xchgl %ebx, GS(%esp) # get the address and save gs.
280 pushl %eax # push the error code
281 lea 4(%esp),%edx
282 pushl %edx
283 movl $(KERNEL_DS),%edx
284 mov %dx,%ds
285 mov %dx,%es
286 movl $(USER_DS),%edx
287 mov %dx,%fs
288 pushl %eax
289 movl _current,%eax
290 movl %db6,%edx
291 movl %edx,dbgreg6(%eax) # save current hardware debugging status
292 popl %eax
293 call *%ebx
294 addl $8,%esp
295 jmp ret_from_sys_call
296
297 .align 4
298 _coprocessor_error:
299 pushl $0
300 pushl $_do_coprocessor_error
301 jmp error_code
302
303 .align 4
304 _device_not_available:
305 pushl $-1 # mark this as an int
306 SAVE_ALL
307 pushl $ret_from_sys_call
308 movl %cr0,%eax
309 testl $0x4,%eax # EM (math emulation bit)
310 je _math_state_restore
311 pushl $0 # temporary storage for ORIG_EIP
312 call _math_emulate
313 addl $4,%esp
314 ret
315
316 .align 4
317 _debug:
318 pushl $0
319 pushl $_do_debug
320 jmp error_code
321
322 .align 4
323 _nmi:
324 pushl $0
325 pushl $_do_nmi
326 jmp error_code
327
328 .align 4
329 _int3:
330 pushl $0
331 pushl $_do_int3
332 jmp error_code
333
334 .align 4
335 _overflow:
336 pushl $0
337 pushl $_do_overflow
338 jmp error_code
339
340 .align 4
341 _bounds:
342 pushl $0
343 pushl $_do_bounds
344 jmp error_code
345
346 .align 4
347 _invalid_op:
348 pushl $0
349 pushl $_do_invalid_op
350 jmp error_code
351
352 .align 4
353 _coprocessor_segment_overrun:
354 pushl $0
355 pushl $_do_coprocessor_segment_overrun
356 jmp error_code
357
358 .align 4
359 _reserved:
360 pushl $0
361 pushl $_do_reserved
362 jmp error_code
363
364 .align 4
365 _double_fault:
366 pushl $_do_double_fault
367 jmp error_code
368
369 .align 4
370 _invalid_TSS:
371 pushl $_do_invalid_TSS
372 jmp error_code
373
374 .align 4
375 _segment_not_present:
376 pushl $_do_segment_not_present
377 jmp error_code
378
379 .align 4
380 _stack_segment:
381 pushl $_do_stack_segment
382 jmp error_code
383
384 .align 4
385 _general_protection:
386 pushl $_do_general_protection
387 jmp error_code
388
389 .align 4
390 _alignment_check:
391 pushl $_do_alignment_check
392 jmp error_code
393
394 .align 4
395 _page_fault:
396 pushl $_do_page_fault
397 jmp error_code
398
399 .data
400 .align 4
401 _sys_call_table:
402 .long _sys_setup
403 .long _sys_exit
404 .long _sys_fork
405 .long _sys_read
406 .long _sys_write
407 .long _sys_open
408 .long _sys_close
409 .long _sys_waitpid
410 .long _sys_creat
411 .long _sys_link
412 .long _sys_unlink
413 .long _sys_execve
414 .long _sys_chdir
415 .long _sys_time
416 .long _sys_mknod
417 .long _sys_chmod
418 .long _sys_chown
419 .long _sys_break
420 .long _sys_stat
421 .long _sys_lseek
422 .long _sys_getpid
423 .long _sys_mount
424 .long _sys_umount
425 .long _sys_setuid
426 .long _sys_getuid
427 .long _sys_stime
428 .long _sys_ptrace
429 .long _sys_alarm
430 .long _sys_fstat
431 .long _sys_pause
432 .long _sys_utime
433 .long _sys_stty
434 .long _sys_gtty
435 .long _sys_access
436 .long _sys_nice
437 .long _sys_ftime
438 .long _sys_sync
439 .long _sys_kill
440 .long _sys_rename
441 .long _sys_mkdir
442 .long _sys_rmdir
443 .long _sys_dup
444 .long _sys_pipe
445 .long _sys_times
446 .long _sys_prof
447 .long _sys_brk
448 .long _sys_setgid
449 .long _sys_getgid
450 .long _sys_signal
451 .long _sys_geteuid
452 .long _sys_getegid
453 .long _sys_acct
454 .long _sys_phys
455 .long _sys_lock
456 .long _sys_ioctl
457 .long _sys_fcntl
458 .long _sys_mpx
459 .long _sys_setpgid
460 .long _sys_ulimit
461 .long _sys_olduname
462 .long _sys_umask
463 .long _sys_chroot
464 .long _sys_ustat
465 .long _sys_dup2
466 .long _sys_getppid
467 .long _sys_getpgrp
468 .long _sys_setsid
469 .long _sys_sigaction
470 .long _sys_sgetmask
471 .long _sys_ssetmask
472 .long _sys_setreuid
473 .long _sys_setregid
474 .long _sys_sigsuspend
475 .long _sys_sigpending
476 .long _sys_sethostname
477 .long _sys_setrlimit
478 .long _sys_getrlimit
479 .long _sys_getrusage
480 .long _sys_gettimeofday
481 .long _sys_settimeofday
482 .long _sys_getgroups
483 .long _sys_setgroups
484 .long _sys_select
485 .long _sys_symlink
486 .long _sys_lstat
487 .long _sys_readlink
488 .long _sys_uselib
489 .long _sys_swapon
490 .long _sys_reboot
491 .long _sys_readdir
492 .long _sys_mmap
493 .long _sys_munmap
494 .long _sys_truncate
495 .long _sys_ftruncate
496 .long _sys_fchmod
497 .long _sys_fchown
498 .long _sys_getpriority
499 .long _sys_setpriority
500 .long _sys_profil
501 .long _sys_statfs
502 .long _sys_fstatfs
503 .long _sys_ioperm
504 .long _sys_socketcall
505 .long _sys_syslog
506 .long _sys_setitimer
507 .long _sys_getitimer
508 .long _sys_newstat
509 .long _sys_newlstat
510 .long _sys_newfstat
511 .long _sys_uname
512 .long _sys_iopl
513 .long _sys_vhangup
514 .long _sys_idle
515 .long _sys_vm86
516 .long _sys_wait4
517 .long _sys_swapoff
518 .long _sys_sysinfo
519 .long _sys_ipc
520 .long _sys_fsync
521 .long _sys_sigreturn
522 .long _sys_clone
523 .long _sys_setdomainname
524 .long _sys_newuname
525 .long _sys_modify_ldt
526 .long _sys_adjtimex
527 .long _sys_mprotect
528 .long _sys_sigprocmask
529 .long _sys_create_module
530 .long _sys_init_module
531 .long _sys_delete_module
532 .long _sys_get_kernel_syms
533 .long _sys_quotactl
534 .long _sys_getpgid
535 .long _sys_fchdir
536 .long _sys_bdflush
537 .long _sys_sysfs
538
539 .space (NR_syscalls-135)*4