Annotation of linux/kernel/sys_call.S, revision 1.1.1.5
1.1 root 1: /*
2: * linux/kernel/sys_call.S
3: *
1.1.1.4 root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1 root 5: */
6:
7: /*
8: * sys_call.S contains the system-call and fault low-level handling routines.
9: * This also contains the timer-interrupt handler, as well as all interrupts
10: * and faults that can result in a task-switch.
11: *
12: * NOTE: This code handles signal-recognition, which happens every time
13: * after a timer-interrupt and after each system call.
14: *
1.1.1.5 ! root 15: * I changed all the .align's to 4 (16 byte alignment), as that's faster
! 16: * on a 486.
! 17: *
1.1 root 18: * Stack layout in 'ret_from_system_call':
19: * ptrace needs to have all regs on the stack.
20: * if the order here is changed, it needs to be
21: * updated in fork.c:copy_process, signal.c:do_signal,
22: * ptrace.c and ptrace.h
23: *
24: * 0(%esp) - %ebx
25: * 4(%esp) - %ecx
26: * 8(%esp) - %edx
27: * C(%esp) - %esi
28: * 10(%esp) - %edi
29: * 14(%esp) - %ebp
30: * 18(%esp) - %eax
31: * 1C(%esp) - %ds
32: * 20(%esp) - %es
33: * 24(%esp) - %fs
34: * 28(%esp) - %gs
35: * 2C(%esp) - orig_eax
36: * 30(%esp) - %eip
37: * 34(%esp) - %cs
38: * 38(%esp) - %eflags
39: * 3C(%esp) - %oldesp
40: * 40(%esp) - %oldss
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:
1.1.1.5 ! root 61: IF_MASK = 0x00000200
! 62: NT_MASK = 0x00004000
! 63: VM_MASK = 0x00020000
! 64:
1.1 root 65: /*
66: * these are offsets into the task-struct.
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)
1.1.1.5 ! root 74: saved_kernel_stack = ((33*16)+4)
1.1 root 75:
76: /*
77: * offsets within sigaction
78: */
79: sa_handler = 0
80: sa_mask = 4
81: sa_flags = 8
82: sa_restorer = 12
83:
84: ENOSYS = 38
85:
1.1.1.4 root 86: .globl _system_call,_sys_execve
1.1 root 87: .globl _device_not_available, _coprocessor_error
88: .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
89: .globl _double_fault,_coprocessor_segment_overrun
90: .globl _invalid_TSS,_segment_not_present,_stack_segment
1.1.1.4 root 91: .globl _general_protection,_reserved
1.1 root 92: .globl _alignment_check,_page_fault
1.1.1.4 root 93: .globl ret_from_sys_call
1.1 root 94:
95: #define SAVE_ALL \
96: cld; \
97: push %gs; \
98: push %fs; \
99: push %es; \
100: push %ds; \
101: pushl %eax; \
102: pushl %ebp; \
103: pushl %edi; \
104: pushl %esi; \
105: pushl %edx; \
106: pushl %ecx; \
107: pushl %ebx; \
108: movl $0x10,%edx; \
109: mov %dx,%ds; \
110: mov %dx,%es; \
111: movl $0x17,%edx; \
112: mov %dx,%fs
113:
1.1.1.5 ! root 114: .align 4
1.1 root 115: reschedule:
116: pushl $ret_from_sys_call
117: jmp _schedule
1.1.1.5 ! root 118: .align 4
1.1 root 119: _system_call:
1.1.1.4 root 120: pushl %eax # save orig_eax
1.1 root 121: SAVE_ALL
1.1.1.4 root 122: movl $-ENOSYS,EAX(%esp)
1.1 root 123: cmpl _NR_syscalls,%eax
1.1.1.4 root 124: jae ret_from_sys_call
1.1 root 125: call _sys_call_table(,%eax,4)
126: movl %eax,EAX(%esp) # save the return value
1.1.1.5 ! root 127: .align 4,0x90
1.1 root 128: ret_from_sys_call:
1.1.1.5 ! root 129: movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
! 130: testl $VM_MASK,%eax # different then
! 131: jne 4f
1.1 root 132: cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
133: jne 2f
134: cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
135: jne 2f
1.1.1.5 ! root 136: 4: orl $IF_MASK,%eax # these just try to make sure
! 137: andl $~NT_MASK,%eax # the program doesn't do anything
! 138: movl %eax,EFLAGS(%esp) # stupid
1.1.1.4 root 139: 1: cmpl $0,_need_resched
1.1 root 140: jne reschedule
1.1.1.4 root 141: movl _current,%eax
1.1.1.5 ! root 142: cmpl _task,%eax # task[0] cannot have signals
! 143: je 2f
1.1 root 144: cmpl $0,state(%eax) # state
145: jne reschedule
146: cmpl $0,counter(%eax) # counter
147: je reschedule
148: movl signal(%eax),%ebx
149: movl blocked(%eax),%ecx
150: notl %ecx
151: andl %ebx,%ecx
152: bsfl %ecx,%ecx
153: je 2f
154: btrl %ecx,%ebx
1.1.1.5 ! root 155: incl %ecx
1.1 root 156: movl %ebx,signal(%eax)
1.1.1.2 root 157: movl %esp,%ebx
1.1.1.5 ! root 158: testl $VM_MASK,EFLAGS(%esp)
! 159: je 3f
1.1.1.2 root 160: pushl %ebx
1.1.1.5 ! root 161: pushl %ecx
! 162: call _save_v86_state
! 163: popl %ecx
! 164: movl %eax,%ebx
! 165: movl %eax,%esp
! 166: 3: pushl %ebx
1.1 root 167: pushl %ecx
168: call _do_signal
169: popl %ecx
1.1.1.2 root 170: popl %ebx
1.1 root 171: testl %eax, %eax
172: jne 1b # see if we need to switch tasks, or do more signals
173: 2: popl %ebx
174: popl %ecx
175: popl %edx
176: popl %esi
177: popl %edi
178: popl %ebp
179: popl %eax
180: pop %ds
181: pop %es
182: pop %fs
183: pop %gs
184: addl $4,%esp # skip the orig_eax
185: iret
186:
1.1.1.5 ! root 187: .align 4
1.1 root 188: _sys_execve:
189: lea (EIP+4)(%esp),%eax # don't forget about the return address.
190: pushl %eax
191: call _do_execve
192: addl $4,%esp
193: ret
194:
1.1.1.5 ! root 195: .align 4
1.1 root 196: _divide_error:
197: pushl $0 # no error code
198: pushl $_do_divide_error
1.1.1.5 ! root 199: .align 4,0x90
1.1 root 200: error_code:
201: push %fs
202: push %es
203: push %ds
204: pushl %eax
205: pushl %ebp
206: pushl %edi
207: pushl %esi
208: pushl %edx
209: pushl %ecx
210: pushl %ebx
211: cld
212: movl $-1, %eax
213: xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
214: xorl %ebx,%ebx # zero ebx
215: mov %gs,%bx # get the lower order bits of gs
216: xchgl %ebx, GS(%esp) # get the address and save gs.
217: pushl %eax # push the error code
218: lea 52(%esp),%edx
219: pushl %edx
220: movl $0x10,%edx
221: mov %dx,%ds
222: mov %dx,%es
223: movl $0x17,%edx
224: mov %dx,%fs
225: call *%ebx
226: addl $8,%esp
227: jmp ret_from_sys_call
228:
1.1.1.5 ! root 229: .align 4
1.1.1.4 root 230: _coprocessor_error:
231: pushl $0
232: pushl $_do_coprocessor_error
233: jmp error_code
234:
1.1.1.5 ! root 235: .align 4
1.1.1.4 root 236: _device_not_available:
237: pushl $-1 # mark this as an int
238: SAVE_ALL
239: pushl $ret_from_sys_call
240: clts # clear TS so that we can use math
241: movl %cr0,%eax
242: testl $0x4,%eax # EM (math emulation bit)
243: je _math_state_restore
244: pushl $0 # temporary storage for ORIG_EIP
245: call _math_emulate
246: addl $4,%esp
247: ret
248:
1.1.1.5 ! root 249: .align 4
1.1 root 250: _debug:
251: pushl $0
1.1.1.4 root 252: pushl $_do_debug
1.1 root 253: jmp error_code
254:
1.1.1.5 ! root 255: .align 4
1.1 root 256: _nmi:
257: pushl $0
258: pushl $_do_nmi
259: jmp error_code
260:
1.1.1.5 ! root 261: .align 4
1.1 root 262: _int3:
263: pushl $0
264: pushl $_do_int3
265: jmp error_code
266:
1.1.1.5 ! root 267: .align 4
1.1 root 268: _overflow:
269: pushl $0
270: pushl $_do_overflow
271: jmp error_code
272:
1.1.1.5 ! root 273: .align 4
1.1 root 274: _bounds:
275: pushl $0
276: pushl $_do_bounds
277: jmp error_code
278:
1.1.1.5 ! root 279: .align 4
1.1 root 280: _invalid_op:
281: pushl $0
282: pushl $_do_invalid_op
283: jmp error_code
284:
1.1.1.5 ! root 285: .align 4
1.1 root 286: _coprocessor_segment_overrun:
287: pushl $0
288: pushl $_do_coprocessor_segment_overrun
289: jmp error_code
290:
1.1.1.5 ! root 291: .align 4
1.1 root 292: _reserved:
293: pushl $0
294: pushl $_do_reserved
295: jmp error_code
296:
1.1.1.5 ! root 297: .align 4
1.1 root 298: _double_fault:
299: pushl $_do_double_fault
300: jmp error_code
301:
1.1.1.5 ! root 302: .align 4
1.1 root 303: _invalid_TSS:
304: pushl $_do_invalid_TSS
305: jmp error_code
306:
1.1.1.5 ! root 307: .align 4
1.1 root 308: _segment_not_present:
309: pushl $_do_segment_not_present
310: jmp error_code
311:
1.1.1.5 ! root 312: .align 4
1.1 root 313: _stack_segment:
314: pushl $_do_stack_segment
315: jmp error_code
316:
1.1.1.5 ! root 317: .align 4
1.1 root 318: _general_protection:
319: pushl $_do_general_protection
320: jmp error_code
321:
1.1.1.5 ! root 322: .align 4
1.1 root 323: _alignment_check:
324: pushl $_do_alignment_check
325: jmp error_code
326:
1.1.1.5 ! root 327: .align 4
1.1 root 328: _page_fault:
329: pushl $_do_page_fault
330: jmp error_code
unix.superglobalmegacorp.com