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 blocked = 16
73 flags = 20
74
75 ENOSYS = 38
76
77 .globl _system_call,_sys_execve
78 .globl _device_not_available, _coprocessor_error
79 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
80 .globl _double_fault,_coprocessor_segment_overrun
81 .globl _invalid_TSS,_segment_not_present,_stack_segment
82 .globl _general_protection,_reserved
83 .globl _alignment_check,_page_fault
84 .globl ret_from_sys_call
85
86 #define SAVE_ALL \
87 cld; \
88 push %gs; \
89 push %fs; \
90 push %es; \
91 push %ds; \
92 pushl %eax; \
93 pushl %ebp; \
94 pushl %edi; \
95 pushl %esi; \
96 pushl %edx; \
97 pushl %ecx; \
98 pushl %ebx; \
99 movl $0x10,%edx; \
100 mov %dx,%ds; \
101 mov %dx,%es; \
102 movl $0x17,%edx; \
103 mov %dx,%fs
104
105 #define RESTORE_ALL \
106 popl %ebx; \
107 popl %ecx; \
108 popl %edx; \
109 popl %esi; \
110 popl %edi; \
111 popl %ebp; \
112 popl %eax; \
113 pop %ds; \
114 pop %es; \
115 pop %fs; \
116 pop %gs; \
117 addl $4,%esp; \
118 iret
119
120 .align 4
121 reschedule:
122 pushl $ret_from_sys_call
123 jmp _schedule
124 .align 4
125 _system_call:
126 pushl %eax # save orig_eax
127 SAVE_ALL
128 movl $-ENOSYS,EAX(%esp)
129 cmpl _NR_syscalls,%eax
130 jae ret_from_sys_call
131 movl _current,%ebx
132 testl $0x20,flags(%ebx) # PF_TRACESYS
133 je 1f
134 pushl $0
135 pushl %ebx
136 pushl $5 # SIGTRAP
137 call _send_sig
138 addl $12,%esp
139 call _schedule
140 movl ORIG_EAX(%esp),%eax
141 1: call _sys_call_table(,%eax,4)
142 movl %eax,EAX(%esp) # save the return value
143 movl _current,%eax
144 testl $0x20,flags(%eax) # PF_TRACESYS
145 je ret_from_sys_call
146 cmpl $0,signal(%eax)
147 jne ret_from_sys_call # ptrace would clear signal
148 pushl $0
149 pushl %eax
150 pushl $5 # SIGTRAP
151 call _send_sig
152 addl $12,%esp
153 call _schedule
154 .align 4,0x90
155 ret_from_sys_call:
156 movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
157 testl $VM_MASK,%eax # different then
158 jne 1f
159 cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
160 jne 2f
161 cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
162 jne 2f
163 1: sti # slow interrupts get here with interrupts disabled
164 orl $IF_MASK,%eax # these just try to make sure
165 andl $~NT_MASK,%eax # the program doesn't do anything
166 movl %eax,EFLAGS(%esp) # stupid
167 cmpl $0,_need_resched
168 jne reschedule
169 movl _current,%eax
170 cmpl _task,%eax # task[0] cannot have signals
171 je 2f
172 cmpl $0,state(%eax) # state
173 jne reschedule
174 cmpl $0,counter(%eax) # counter
175 je reschedule
176 movl blocked(%eax),%ecx
177 notl %ecx
178 andl signal(%eax),%ecx
179 jne signal_return
180 2: RESTORE_ALL
181 .align 4
182 signal_return:
183 movl %esp,%ebx
184 pushl %ebx
185 testl $VM_MASK,EFLAGS(%ebx)
186 jne v86_signal_return
187 pushl blocked(%eax)
188 call _do_signal
189 popl %ebx
190 popl %ebx
191 RESTORE_ALL
192 .align 4
193 v86_signal_return:
194 call _save_v86_state
195 movl %eax,%esp
196 pushl %eax
197 pushl blocked(%eax)
198 call _do_signal
199 popl %ebx
200 popl %ebx
201 RESTORE_ALL
202
203 .align 4
204 _sys_execve:
205 lea (EIP+4)(%esp),%eax # don't forget about the return address.
206 pushl %eax
207 call _do_execve
208 addl $4,%esp
209 ret
210
211 .align 4
212 _divide_error:
213 pushl $0 # no error code
214 pushl $_do_divide_error
215 .align 4,0x90
216 error_code:
217 push %fs
218 push %es
219 push %ds
220 pushl %eax
221 pushl %ebp
222 pushl %edi
223 pushl %esi
224 pushl %edx
225 pushl %ecx
226 pushl %ebx
227 cld
228 movl $-1, %eax
229 xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
230 xorl %ebx,%ebx # zero ebx
231 mov %gs,%bx # get the lower order bits of gs
232 xchgl %ebx, GS(%esp) # get the address and save gs.
233 pushl %eax # push the error code
234 lea 52(%esp),%edx
235 pushl %edx
236 movl $0x10,%edx
237 mov %dx,%ds
238 mov %dx,%es
239 movl $0x17,%edx
240 mov %dx,%fs
241 call *%ebx
242 addl $8,%esp
243 jmp ret_from_sys_call
244
245 .align 4
246 _coprocessor_error:
247 pushl $0
248 pushl $_do_coprocessor_error
249 jmp error_code
250
251 .align 4
252 _device_not_available:
253 pushl $-1 # mark this as an int
254 SAVE_ALL
255 pushl $ret_from_sys_call
256 clts # clear TS so that we can use math
257 movl %cr0,%eax
258 testl $0x4,%eax # EM (math emulation bit)
259 je _math_state_restore
260 pushl $0 # temporary storage for ORIG_EIP
261 call _math_emulate
262 addl $4,%esp
263 ret
264
265 .align 4
266 _debug:
267 pushl $0
268 pushl $_do_debug
269 jmp error_code
270
271 .align 4
272 _nmi:
273 pushl $0
274 pushl $_do_nmi
275 jmp error_code
276
277 .align 4
278 _int3:
279 pushl $0
280 pushl $_do_int3
281 jmp error_code
282
283 .align 4
284 _overflow:
285 pushl $0
286 pushl $_do_overflow
287 jmp error_code
288
289 .align 4
290 _bounds:
291 pushl $0
292 pushl $_do_bounds
293 jmp error_code
294
295 .align 4
296 _invalid_op:
297 pushl $0
298 pushl $_do_invalid_op
299 jmp error_code
300
301 .align 4
302 _coprocessor_segment_overrun:
303 pushl $0
304 pushl $_do_coprocessor_segment_overrun
305 jmp error_code
306
307 .align 4
308 _reserved:
309 pushl $0
310 pushl $_do_reserved
311 jmp error_code
312
313 .align 4
314 _double_fault:
315 pushl $_do_double_fault
316 jmp error_code
317
318 .align 4
319 _invalid_TSS:
320 pushl $_do_invalid_TSS
321 jmp error_code
322
323 .align 4
324 _segment_not_present:
325 pushl $_do_segment_not_present
326 jmp error_code
327
328 .align 4
329 _stack_segment:
330 pushl $_do_stack_segment
331 jmp error_code
332
333 .align 4
334 _general_protection:
335 pushl $_do_general_protection
336 jmp error_code
337
338 .align 4
339 _alignment_check:
340 pushl $_do_alignment_check
341 jmp error_code
342
343 .align 4
344 _page_fault:
345 pushl $_do_page_fault
346 jmp error_code