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