]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #include <asm/asmmacro.h> |
2 | #include <asm/ia32.h> | |
39e01cb8 | 3 | #include <asm/asm-offsets.h> |
1da177e4 LT |
4 | #include <asm/signal.h> |
5 | #include <asm/thread_info.h> | |
6 | ||
7 | #include "../kernel/minstate.h" | |
8 | ||
9 | /* | |
10 | * execve() is special because in case of success, we need to | |
11 | * setup a null register window frame (in case an IA-32 process | |
12 | * is exec'ing an IA-64 program). | |
13 | */ | |
14 | ENTRY(ia32_execve) | |
15 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3) | |
16 | alloc loc1=ar.pfs,3,2,4,0 | |
17 | mov loc0=rp | |
18 | .body | |
19 | zxt4 out0=in0 // filename | |
20 | ;; // stop bit between alloc and call | |
21 | zxt4 out1=in1 // argv | |
22 | zxt4 out2=in2 // envp | |
23 | add out3=16,sp // regs | |
24 | br.call.sptk.few rp=sys32_execve | |
25 | 1: cmp.ge p6,p0=r8,r0 | |
26 | mov ar.pfs=loc1 // restore ar.pfs | |
27 | ;; | |
28 | (p6) mov ar.pfs=r0 // clear ar.pfs in case of success | |
29 | sxt4 r8=r8 // return 64-bit result | |
30 | mov rp=loc0 | |
31 | br.ret.sptk.few rp | |
32 | END(ia32_execve) | |
33 | ||
34 | ENTRY(ia32_clone) | |
35 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) | |
36 | alloc r16=ar.pfs,5,2,6,0 | |
37 | DO_SAVE_SWITCH_STACK | |
38 | mov loc0=rp | |
39 | mov loc1=r16 // save ar.pfs across do_fork | |
40 | .body | |
41 | zxt4 out1=in1 // newsp | |
42 | mov out3=16 // stacksize (compensates for 16-byte scratch area) | |
43 | adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s | |
44 | mov out0=in0 // out0 = clone_flags | |
45 | zxt4 out4=in2 // out4 = parent_tidptr | |
46 | zxt4 out5=in4 // out5 = child_tidptr | |
47 | br.call.sptk.many rp=do_fork | |
48 | .ret0: .restore sp | |
49 | adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack | |
50 | mov ar.pfs=loc1 | |
51 | mov rp=loc0 | |
52 | br.ret.sptk.many rp | |
53 | END(ia32_clone) | |
54 | ||
1da177e4 LT |
55 | GLOBAL_ENTRY(ia32_ret_from_clone) |
56 | PT_REGS_UNWIND_INFO(0) | |
57 | { /* | |
58 | * Some versions of gas generate bad unwind info if the first instruction of a | |
59 | * procedure doesn't go into the first slot of a bundle. This is a workaround. | |
60 | */ | |
61 | nop.m 0 | |
62 | nop.i 0 | |
63 | /* | |
64 | * We need to call schedule_tail() to complete the scheduling process. | |
65 | * Called by ia64_switch_to after do_fork()->copy_thread(). r8 contains the | |
66 | * address of the previously executing task. | |
67 | */ | |
68 | br.call.sptk.many rp=ia64_invoke_schedule_tail | |
69 | } | |
70 | .ret1: | |
71 | adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 | |
72 | ;; | |
73 | ld4 r2=[r2] | |
74 | ;; | |
75 | mov r8=0 | |
76 | and r2=_TIF_SYSCALL_TRACEAUDIT,r2 | |
77 | ;; | |
78 | cmp.ne p6,p0=r2,r0 | |
79 | (p6) br.cond.spnt .ia32_strace_check_retval | |
80 | ;; // prevent RAW on r8 | |
81 | END(ia32_ret_from_clone) | |
af901ca1 | 82 | // fall through |
1da177e4 LT |
83 | GLOBAL_ENTRY(ia32_ret_from_syscall) |
84 | PT_REGS_UNWIND_INFO(0) | |
85 | ||
86 | cmp.ge p6,p7=r8,r0 // syscall executed successfully? | |
87 | adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 | |
88 | ;; | |
89 | alloc r3=ar.pfs,0,0,0,0 // drop the syscall argument frame | |
90 | st8 [r2]=r8 // store return value in slot for r8 | |
91 | br.cond.sptk.many ia64_leave_kernel | |
92 | END(ia32_ret_from_syscall) | |
93 | ||
94 | // | |
95 | // Invoke a system call, but do some tracing before and after the call. | |
96 | // We MUST preserve the current register frame throughout this routine | |
97 | // because some system calls (such as ia64_execve) directly | |
98 | // manipulate ar.pfs. | |
99 | // | |
100 | // Input: | |
101 | // r8 = syscall number | |
102 | // b6 = syscall entry point | |
103 | // | |
104 | GLOBAL_ENTRY(ia32_trace_syscall) | |
105 | PT_REGS_UNWIND_INFO(0) | |
106 | mov r3=-38 | |
107 | adds r2=IA64_PT_REGS_R8_OFFSET+16,sp | |
108 | ;; | |
109 | st8 [r2]=r3 // initialize return code to -ENOSYS | |
110 | br.call.sptk.few rp=syscall_trace_enter // give parent a chance to catch syscall args | |
f14488cc SL |
111 | cmp.lt p6,p0=r8,r0 // check tracehook |
112 | adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 | |
113 | ;; | |
114 | (p6) st8.spill [r2]=r8 // store return value in slot for r8 | |
115 | (p6) br.spnt.few .ret4 | |
1da177e4 LT |
116 | .ret2: // Need to reload arguments (they may be changed by the tracing process) |
117 | adds r2=IA64_PT_REGS_R1_OFFSET+16,sp // r2 = &pt_regs.r1 | |
118 | adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 | |
119 | mov r15=IA32_NR_syscalls | |
120 | ;; | |
121 | ld4 r8=[r2],IA64_PT_REGS_R9_OFFSET-IA64_PT_REGS_R1_OFFSET | |
122 | movl r16=ia32_syscall_table | |
123 | ;; | |
124 | ld4 r33=[r2],8 // r9 == ecx | |
125 | ld4 r37=[r3],16 // r13 == ebp | |
126 | cmp.ltu.unc p6,p7=r8,r15 | |
127 | ;; | |
128 | ld4 r34=[r2],8 // r10 == edx | |
129 | ld4 r36=[r3],8 // r15 == edi | |
130 | (p6) shladd r16=r8,3,r16 // force ni_syscall if not valid syscall number | |
131 | ;; | |
132 | ld8 r16=[r16] | |
133 | ;; | |
134 | ld4 r32=[r2],8 // r11 == ebx | |
135 | mov b6=r16 | |
136 | ld4 r35=[r3],8 // r14 == esi | |
137 | br.call.sptk.few rp=b6 // do the syscall | |
138 | .ia32_strace_check_retval: | |
139 | cmp.lt p6,p0=r8,r0 // syscall failed? | |
140 | adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 | |
141 | ;; | |
142 | st8.spill [r2]=r8 // store return value in slot for r8 | |
143 | br.call.sptk.few rp=syscall_trace_leave // give parent a chance to catch return value | |
144 | .ret4: alloc r2=ar.pfs,0,0,0,0 // drop the syscall argument frame | |
145 | br.cond.sptk.many ia64_leave_kernel | |
146 | END(ia32_trace_syscall) | |
147 | ||
148 | GLOBAL_ENTRY(sys32_vfork) | |
149 | alloc r16=ar.pfs,2,2,4,0;; | |
150 | mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD // out0 = clone_flags | |
151 | br.cond.sptk.few .fork1 // do the work | |
152 | END(sys32_vfork) | |
153 | ||
154 | GLOBAL_ENTRY(sys32_fork) | |
155 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) | |
156 | alloc r16=ar.pfs,2,2,4,0 | |
157 | mov out0=SIGCHLD // out0 = clone_flags | |
158 | ;; | |
159 | .fork1: | |
160 | mov loc0=rp | |
161 | mov loc1=r16 // save ar.pfs across do_fork | |
162 | DO_SAVE_SWITCH_STACK | |
163 | ||
164 | .body | |
165 | ||
166 | mov out1=0 | |
167 | mov out3=0 | |
168 | adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s | |
169 | br.call.sptk.few rp=do_fork | |
170 | .ret5: .restore sp | |
171 | adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack | |
172 | mov ar.pfs=loc1 | |
173 | mov rp=loc0 | |
174 | br.ret.sptk.many rp | |
175 | END(sys32_fork) | |
176 | ||
177 | .rodata | |
178 | .align 8 | |
179 | .globl ia32_syscall_table | |
180 | ia32_syscall_table: | |
181 | data8 sys_ni_syscall /* 0 - old "setup(" system call*/ | |
182 | data8 sys_exit | |
183 | data8 sys32_fork | |
184 | data8 sys_read | |
185 | data8 sys_write | |
e922efc3 | 186 | data8 compat_sys_open /* 5 */ |
1da177e4 LT |
187 | data8 sys_close |
188 | data8 sys32_waitpid | |
189 | data8 sys_creat | |
190 | data8 sys_link | |
191 | data8 sys_unlink /* 10 */ | |
192 | data8 ia32_execve | |
193 | data8 sys_chdir | |
194 | data8 compat_sys_time | |
195 | data8 sys_mknod | |
196 | data8 sys_chmod /* 15 */ | |
197 | data8 sys_lchown /* 16-bit version */ | |
198 | data8 sys_ni_syscall /* old break syscall holder */ | |
199 | data8 sys_ni_syscall | |
200 | data8 sys32_lseek | |
201 | data8 sys_getpid /* 20 */ | |
202 | data8 compat_sys_mount | |
203 | data8 sys_oldumount | |
204 | data8 sys_setuid /* 16-bit version */ | |
205 | data8 sys_getuid /* 16-bit version */ | |
206 | data8 compat_sys_stime /* 25 */ | |
680973ed | 207 | data8 compat_sys_ptrace |
1da177e4 LT |
208 | data8 sys32_alarm |
209 | data8 sys_ni_syscall | |
9f3541ed | 210 | data8 sys_pause |
1da177e4 LT |
211 | data8 compat_sys_utime /* 30 */ |
212 | data8 sys_ni_syscall /* old stty syscall holder */ | |
213 | data8 sys_ni_syscall /* old gtty syscall holder */ | |
214 | data8 sys_access | |
215 | data8 sys_nice | |
216 | data8 sys_ni_syscall /* 35 */ /* old ftime syscall holder */ | |
217 | data8 sys_sync | |
218 | data8 sys_kill | |
219 | data8 sys_rename | |
220 | data8 sys_mkdir | |
221 | data8 sys_rmdir /* 40 */ | |
222 | data8 sys_dup | |
1134723e | 223 | data8 sys_ia64_pipe |
1da177e4 LT |
224 | data8 compat_sys_times |
225 | data8 sys_ni_syscall /* old prof syscall holder */ | |
226 | data8 sys32_brk /* 45 */ | |
227 | data8 sys_setgid /* 16-bit version */ | |
228 | data8 sys_getgid /* 16-bit version */ | |
229 | data8 sys32_signal | |
230 | data8 sys_geteuid /* 16-bit version */ | |
231 | data8 sys_getegid /* 16-bit version */ /* 50 */ | |
232 | data8 sys_acct | |
233 | data8 sys_umount /* recycled never used phys( */ | |
234 | data8 sys_ni_syscall /* old lock syscall holder */ | |
235 | data8 compat_sys_ioctl | |
236 | data8 compat_sys_fcntl /* 55 */ | |
237 | data8 sys_ni_syscall /* old mpx syscall holder */ | |
238 | data8 sys_setpgid | |
239 | data8 sys_ni_syscall /* old ulimit syscall holder */ | |
240 | data8 sys_ni_syscall | |
241 | data8 sys_umask /* 60 */ | |
242 | data8 sys_chroot | |
2b1c6bd7 | 243 | data8 compat_sys_ustat |
1da177e4 LT |
244 | data8 sys_dup2 |
245 | data8 sys_getppid | |
246 | data8 sys_getpgrp /* 65 */ | |
247 | data8 sys_setsid | |
248 | data8 sys32_sigaction | |
249 | data8 sys_ni_syscall | |
250 | data8 sys_ni_syscall | |
251 | data8 sys_setreuid /* 16-bit version */ /* 70 */ | |
252 | data8 sys_setregid /* 16-bit version */ | |
253 | data8 sys32_sigsuspend | |
254 | data8 compat_sys_sigpending | |
255 | data8 sys_sethostname | |
256 | data8 compat_sys_setrlimit /* 75 */ | |
257 | data8 compat_sys_old_getrlimit | |
258 | data8 compat_sys_getrusage | |
b418da16 CH |
259 | data8 compat_sys_gettimeofday |
260 | data8 compat_sys_settimeofday | |
1da177e4 LT |
261 | data8 sys32_getgroups16 /* 80 */ |
262 | data8 sys32_setgroups16 | |
263 | data8 sys32_old_select | |
264 | data8 sys_symlink | |
265 | data8 sys_ni_syscall | |
266 | data8 sys_readlink /* 85 */ | |
267 | data8 sys_uselib | |
268 | data8 sys_swapon | |
269 | data8 sys_reboot | |
37c23e7f | 270 | data8 compat_sys_old_readdir |
1da177e4 LT |
271 | data8 sys32_mmap /* 90 */ |
272 | data8 sys32_munmap | |
273 | data8 sys_truncate | |
274 | data8 sys_ftruncate | |
275 | data8 sys_fchmod | |
276 | data8 sys_fchown /* 16-bit version */ /* 95 */ | |
277 | data8 sys_getpriority | |
278 | data8 sys_setpriority | |
279 | data8 sys_ni_syscall /* old profil syscall holder */ | |
280 | data8 compat_sys_statfs | |
281 | data8 compat_sys_fstatfs /* 100 */ | |
282 | data8 sys_ni_syscall /* ioperm */ | |
283 | data8 compat_sys_socketcall | |
284 | data8 sys_syslog | |
285 | data8 compat_sys_setitimer | |
286 | data8 compat_sys_getitimer /* 105 */ | |
287 | data8 compat_sys_newstat | |
288 | data8 compat_sys_newlstat | |
289 | data8 compat_sys_newfstat | |
290 | data8 sys_ni_syscall | |
291 | data8 sys_ni_syscall /* iopl */ /* 110 */ | |
292 | data8 sys_vhangup | |
293 | data8 sys_ni_syscall /* used to be sys_idle */ | |
294 | data8 sys_ni_syscall | |
295 | data8 compat_sys_wait4 | |
296 | data8 sys_swapoff /* 115 */ | |
d4d23add | 297 | data8 compat_sys_sysinfo |
1da177e4 LT |
298 | data8 sys32_ipc |
299 | data8 sys_fsync | |
300 | data8 sys32_sigreturn | |
301 | data8 ia32_clone /* 120 */ | |
302 | data8 sys_setdomainname | |
303 | data8 sys32_newuname | |
304 | data8 sys32_modify_ldt | |
c6180deb | 305 | data8 compat_sys_adjtimex |
1da177e4 LT |
306 | data8 sys32_mprotect /* 125 */ |
307 | data8 compat_sys_sigprocmask | |
308 | data8 sys_ni_syscall /* create_module */ | |
309 | data8 sys_ni_syscall /* init_module */ | |
310 | data8 sys_ni_syscall /* delete_module */ | |
311 | data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */ | |
b716395e | 312 | data8 sys32_quotactl |
1da177e4 LT |
313 | data8 sys_getpgid |
314 | data8 sys_fchdir | |
315 | data8 sys_ni_syscall /* sys_bdflush */ | |
316 | data8 sys_sysfs /* 135 */ | |
317 | data8 sys32_personality | |
318 | data8 sys_ni_syscall /* for afs_syscall */ | |
319 | data8 sys_setfsuid /* 16-bit version */ | |
320 | data8 sys_setfsgid /* 16-bit version */ | |
321 | data8 sys_llseek /* 140 */ | |
322 | data8 compat_sys_getdents | |
323 | data8 compat_sys_select | |
324 | data8 sys_flock | |
325 | data8 sys32_msync | |
326 | data8 compat_sys_readv /* 145 */ | |
327 | data8 compat_sys_writev | |
328 | data8 sys_getsid | |
329 | data8 sys_fdatasync | |
330 | data8 sys32_sysctl | |
331 | data8 sys_mlock /* 150 */ | |
332 | data8 sys_munlock | |
333 | data8 sys_mlockall | |
334 | data8 sys_munlockall | |
335 | data8 sys_sched_setparam | |
336 | data8 sys_sched_getparam /* 155 */ | |
337 | data8 sys_sched_setscheduler | |
338 | data8 sys_sched_getscheduler | |
339 | data8 sys_sched_yield | |
340 | data8 sys_sched_get_priority_max | |
341 | data8 sys_sched_get_priority_min /* 160 */ | |
342 | data8 sys32_sched_rr_get_interval | |
343 | data8 compat_sys_nanosleep | |
344 | data8 sys32_mremap | |
345 | data8 sys_setresuid /* 16-bit version */ | |
346 | data8 sys32_getresuid16 /* 16-bit version */ /* 165 */ | |
347 | data8 sys_ni_syscall /* vm86 */ | |
348 | data8 sys_ni_syscall /* sys_query_module */ | |
349 | data8 sys_poll | |
350 | data8 sys_ni_syscall /* nfsservctl */ | |
351 | data8 sys_setresgid /* 170 */ | |
352 | data8 sys32_getresgid16 | |
353 | data8 sys_prctl | |
354 | data8 sys32_rt_sigreturn | |
355 | data8 sys32_rt_sigaction | |
356 | data8 sys32_rt_sigprocmask /* 175 */ | |
357 | data8 sys_rt_sigpending | |
358 | data8 compat_sys_rt_sigtimedwait | |
359 | data8 sys32_rt_sigqueueinfo | |
4a177cbf | 360 | data8 compat_sys_rt_sigsuspend |
1da177e4 LT |
361 | data8 sys32_pread /* 180 */ |
362 | data8 sys32_pwrite | |
363 | data8 sys_chown /* 16-bit version */ | |
364 | data8 sys_getcwd | |
365 | data8 sys_capget | |
366 | data8 sys_capset /* 185 */ | |
367 | data8 sys32_sigaltstack | |
368 | data8 sys32_sendfile | |
369 | data8 sys_ni_syscall /* streams1 */ | |
370 | data8 sys_ni_syscall /* streams2 */ | |
371 | data8 sys32_vfork /* 190 */ | |
372 | data8 compat_sys_getrlimit | |
373 | data8 sys32_mmap2 | |
374 | data8 sys32_truncate64 | |
375 | data8 sys32_ftruncate64 | |
376 | data8 sys32_stat64 /* 195 */ | |
377 | data8 sys32_lstat64 | |
378 | data8 sys32_fstat64 | |
379 | data8 sys_lchown | |
380 | data8 sys_getuid | |
381 | data8 sys_getgid /* 200 */ | |
382 | data8 sys_geteuid | |
383 | data8 sys_getegid | |
384 | data8 sys_setreuid | |
385 | data8 sys_setregid | |
386 | data8 sys_getgroups /* 205 */ | |
387 | data8 sys_setgroups | |
388 | data8 sys_fchown | |
389 | data8 sys_setresuid | |
390 | data8 sys_getresuid | |
391 | data8 sys_setresgid /* 210 */ | |
392 | data8 sys_getresgid | |
393 | data8 sys_chown | |
394 | data8 sys_setuid | |
395 | data8 sys_setgid | |
396 | data8 sys_setfsuid /* 215 */ | |
397 | data8 sys_setfsgid | |
398 | data8 sys_pivot_root | |
399 | data8 sys_mincore | |
400 | data8 sys_madvise | |
401 | data8 compat_sys_getdents64 /* 220 */ | |
402 | data8 compat_sys_fcntl64 | |
403 | data8 sys_ni_syscall /* reserved for TUX */ | |
404 | data8 sys_ni_syscall /* reserved for Security */ | |
405 | data8 sys_gettid | |
406 | data8 sys_readahead /* 225 */ | |
407 | data8 sys_setxattr | |
408 | data8 sys_lsetxattr | |
409 | data8 sys_fsetxattr | |
410 | data8 sys_getxattr | |
411 | data8 sys_lgetxattr /* 230 */ | |
412 | data8 sys_fgetxattr | |
413 | data8 sys_listxattr | |
414 | data8 sys_llistxattr | |
415 | data8 sys_flistxattr | |
416 | data8 sys_removexattr /* 235 */ | |
417 | data8 sys_lremovexattr | |
418 | data8 sys_fremovexattr | |
419 | data8 sys_tkill | |
420 | data8 sys_sendfile64 | |
421 | data8 compat_sys_futex /* 240 */ | |
422 | data8 compat_sys_sched_setaffinity | |
423 | data8 compat_sys_sched_getaffinity | |
424 | data8 sys32_set_thread_area | |
425 | data8 sys32_get_thread_area | |
426 | data8 compat_sys_io_setup /* 245 */ | |
427 | data8 sys_io_destroy | |
428 | data8 compat_sys_io_getevents | |
429 | data8 compat_sys_io_submit | |
430 | data8 sys_io_cancel | |
431 | data8 sys_fadvise64 /* 250 */ | |
432 | data8 sys_ni_syscall | |
433 | data8 sys_exit_group | |
434 | data8 sys_lookup_dcookie | |
435 | data8 sys_epoll_create | |
436 | data8 sys32_epoll_ctl /* 255 */ | |
437 | data8 sys32_epoll_wait | |
438 | data8 sys_remap_file_pages | |
439 | data8 sys_set_tid_address | |
3a0f69d5 | 440 | data8 compat_sys_timer_create |
1da177e4 LT |
441 | data8 compat_sys_timer_settime /* 260 */ |
442 | data8 compat_sys_timer_gettime | |
443 | data8 sys_timer_getoverrun | |
444 | data8 sys_timer_delete | |
445 | data8 compat_sys_clock_settime | |
446 | data8 compat_sys_clock_gettime /* 265 */ | |
447 | data8 compat_sys_clock_getres | |
448 | data8 compat_sys_clock_nanosleep | |
449 | data8 compat_sys_statfs64 | |
450 | data8 compat_sys_fstatfs64 | |
451 | data8 sys_tgkill /* 270 */ | |
452 | data8 compat_sys_utimes | |
453 | data8 sys32_fadvise64_64 | |
454 | data8 sys_ni_syscall | |
455 | data8 sys_ni_syscall | |
456 | data8 sys_ni_syscall /* 275 */ | |
457 | data8 sys_ni_syscall | |
458 | data8 compat_sys_mq_open | |
459 | data8 sys_mq_unlink | |
460 | data8 compat_sys_mq_timedsend | |
461 | data8 compat_sys_mq_timedreceive /* 280 */ | |
462 | data8 compat_sys_mq_notify | |
463 | data8 compat_sys_mq_getsetattr | |
464 | data8 sys_ni_syscall /* reserved for kexec */ | |
465 | data8 compat_sys_waitid | |
466 | ||
467 | // guard against failures to increase IA32_NR_syscalls | |
468 | .org ia32_syscall_table + 8*IA32_NR_syscalls |