blob: a8cf199588508e23c0d6e40e869b8540a37d965a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#include <asm/asmmacro.h>
2#include <asm/ia32.h>
Sam Ravnborg39e01cb2005-09-09 22:03:13 +02003#include <asm/asm-offsets.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07004#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 */
14ENTRY(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
251: 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
32END(ia32_execve)
33
34ENTRY(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 = &regs
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
53END(ia32_clone)
54
Linus Torvalds1da177e2005-04-16 15:20:36 -070055GLOBAL_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
81END(ia32_ret_from_clone)
82 // fall thrugh
83GLOBAL_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
92END(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 //
104GLOBAL_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
Shaohua Lif14488c2008-10-06 10:43:06 -0700111 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116.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
146END(ia32_trace_syscall)
147
148GLOBAL_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
152END(sys32_vfork)
153
154GLOBAL_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 = &regs
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
175END(sys32_fork)
176
177 .rodata
178 .align 8
179 .globl ia32_syscall_table
180ia32_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
Miklos Szeredie922efc2005-09-06 15:18:25 -0700186 data8 compat_sys_open /* 5 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 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 */
Shaohua Li680973e2008-09-18 15:50:26 +0800207 data8 compat_sys_ptrace
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 data8 sys32_alarm
209 data8 sys_ni_syscall
Christoph Hellwig9f3541ed2c2008-09-01 18:16:52 +0200210 data8 sys_pause
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 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
Christoph Hellwig0f32dc92008-09-01 18:18:10 +0200223 data8 sys_pipe
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 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
243 data8 sys_ustat
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
Christoph Hellwigb418da12008-10-15 22:02:06 -0700259 data8 compat_sys_gettimeofday
260 data8 compat_sys_settimeofday
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 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
Christoph Hellwig37c23e72008-08-16 19:50:28 +0200270 data8 compat_sys_old_readdir
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 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 */
Kyle McMartind4d23ad2007-02-10 01:46:00 -0800297 data8 compat_sys_sysinfo
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 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
Luck, Tonyc6180de2006-04-18 21:14:22 -0700305 data8 compat_sys_adjtimex
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 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 */
Vasily Tarasovb7163952007-07-15 23:41:12 -0700312 data8 sys32_quotactl
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 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
Alexey Dobriyan4a177cb2007-01-23 19:03:17 +0300360 data8 compat_sys_rt_sigsuspend
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 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
Christoph Hellwig3a0f69d2006-01-09 20:52:08 -0800440 data8 compat_sys_timer_create
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 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