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
76
77
78
79 sa_handler = 0
80 sa_mask = 4
81 sa_flags = 8
82 sa_restorer = 12
83
84 ENOSYS = 38
85
86 .globl _system_call,_sys_execve
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
91 .globl _general_protection,_reserved
92 .globl _alignment_check,_page_fault
93 .globl ret_from_sys_call
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
114 .align 4
115 reschedule:
116 pushl $ret_from_sys_call
117 jmp _schedule
118 .align 4
119 _system_call:
120 pushl %eax # save orig_eax
121 SAVE_ALL
122 movl $-ENOSYS,EAX(%esp)
123 cmpl _NR_syscalls,%eax
124 jae ret_from_sys_call
125 call _sys_call_table(,%eax,4)
126 movl %eax,EAX(%esp) # save the return value
127 .align 4,0x90
128 ret_from_sys_call:
129 movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
130 testl $VM_MASK,%eax # different then
131 jne 4f
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
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
139 1: cmpl $0,_need_resched
140 jne reschedule
141 movl _current,%eax
142 cmpl _task,%eax # task[0] cannot have signals
143 je 2f
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
155 incl %ecx
156 movl %ebx,signal(%eax)
157 movl %esp,%ebx
158 testl $VM_MASK,EFLAGS(%esp)
159 je 3f
160 pushl %ebx
161 pushl %ecx
162 call _save_v86_state
163 popl %ecx
164 movl %eax,%ebx
165 movl %eax,%esp
166 3: pushl %ebx
167 pushl %ecx
168 call _do_signal
169 popl %ecx
170 popl %ebx
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
187 .align 4
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
195 .align 4
196 _divide_error:
197 pushl $0 # no error code
198 pushl $_do_divide_error
199 .align 4,0x90
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
229 .align 4
230 _coprocessor_error:
231 pushl $0
232 pushl $_do_coprocessor_error
233 jmp error_code
234
235 .align 4
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
249 .align 4
250 _debug:
251 pushl $0
252 pushl $_do_debug
253 jmp error_code
254
255 .align 4
256 _nmi:
257 pushl $0
258 pushl $_do_nmi
259 jmp error_code
260
261 .align 4
262 _int3:
263 pushl $0
264 pushl $_do_int3
265 jmp error_code
266
267 .align 4
268 _overflow:
269 pushl $0
270 pushl $_do_overflow
271 jmp error_code
272
273 .align 4
274 _bounds:
275 pushl $0
276 pushl $_do_bounds
277 jmp error_code
278
279 .align 4
280 _invalid_op:
281 pushl $0
282 pushl $_do_invalid_op
283 jmp error_code
284
285 .align 4
286 _coprocessor_segment_overrun:
287 pushl $0
288 pushl $_do_coprocessor_segment_overrun
289 jmp error_code
290
291 .align 4
292 _reserved:
293 pushl $0
294 pushl $_do_reserved
295 jmp error_code
296
297 .align 4
298 _double_fault:
299 pushl $_do_double_fault
300 jmp error_code
301
302 .align 4
303 _invalid_TSS:
304 pushl $_do_invalid_TSS
305 jmp error_code
306
307 .align 4
308 _segment_not_present:
309 pushl $_do_segment_not_present
310 jmp error_code
311
312 .align 4
313 _stack_segment:
314 pushl $_do_stack_segment
315 jmp error_code
316
317 .align 4
318 _general_protection:
319 pushl $_do_general_protection
320 jmp error_code
321
322 .align 4
323 _alignment_check:
324 pushl $_do_alignment_check
325 jmp error_code
326
327 .align 4
328 _page_fault:
329 pushl $_do_page_fault
330 jmp error_code