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