ia32_entry.S 13 KB

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