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