wrappers.S 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * Linux/PARISC Project (http://www.parisc-linux.org/)
  3. *
  4. * HP-UX System Call Wrapper routines and System Call Return Path
  5. *
  6. * Copyright (C) 2000 Hewlett-Packard (John Marvin)
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2, or (at your option)
  11. * any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. #ifdef __LP64__
  23. #warning PA64 support needs more work...did first cut
  24. #endif
  25. #include <asm/offsets.h>
  26. #include <asm/assembly.h>
  27. #include <asm/signal.h>
  28. #ifdef __LP64__
  29. .level 2.0w
  30. #else
  31. .level 1.1
  32. #endif
  33. .text
  34. /* These should probably go in a header file somewhere.
  35. * They are duplicated in kernel/wrappers.S
  36. * Possibly we should consider consolidating these
  37. * register save/restore macros.
  38. */
  39. .macro reg_save regs
  40. #ifdef __LP64__
  41. #warning NEEDS WORK for 64-bit
  42. #endif
  43. STREG %r3, PT_GR3(\regs)
  44. STREG %r4, PT_GR4(\regs)
  45. STREG %r5, PT_GR5(\regs)
  46. STREG %r6, PT_GR6(\regs)
  47. STREG %r7, PT_GR7(\regs)
  48. STREG %r8, PT_GR8(\regs)
  49. STREG %r9, PT_GR9(\regs)
  50. STREG %r10,PT_GR10(\regs)
  51. STREG %r11,PT_GR11(\regs)
  52. STREG %r12,PT_GR12(\regs)
  53. STREG %r13,PT_GR13(\regs)
  54. STREG %r14,PT_GR14(\regs)
  55. STREG %r15,PT_GR15(\regs)
  56. STREG %r16,PT_GR16(\regs)
  57. STREG %r17,PT_GR17(\regs)
  58. STREG %r18,PT_GR18(\regs)
  59. .endm
  60. .macro reg_restore regs
  61. LDREG PT_GR3(\regs), %r3
  62. LDREG PT_GR4(\regs), %r4
  63. LDREG PT_GR5(\regs), %r5
  64. LDREG PT_GR6(\regs), %r6
  65. LDREG PT_GR7(\regs), %r7
  66. LDREG PT_GR8(\regs), %r8
  67. LDREG PT_GR9(\regs), %r9
  68. LDREG PT_GR10(\regs),%r10
  69. LDREG PT_GR11(\regs),%r11
  70. LDREG PT_GR12(\regs),%r12
  71. LDREG PT_GR13(\regs),%r13
  72. LDREG PT_GR14(\regs),%r14
  73. LDREG PT_GR15(\regs),%r15
  74. LDREG PT_GR16(\regs),%r16
  75. LDREG PT_GR17(\regs),%r17
  76. LDREG PT_GR18(\regs),%r18
  77. .endm
  78. .export hpux_fork_wrapper
  79. .export hpux_child_return
  80. .import sys_fork
  81. hpux_fork_wrapper:
  82. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  83. ;! pointer in task
  84. reg_save %r1
  85. STREG %r2,-20(%r30)
  86. ldo 64(%r30),%r30
  87. STREG %r2,PT_GR19(%r1) ;! save for child
  88. STREG %r30,PT_GR21(%r1) ;! save for child
  89. LDREG PT_GR30(%r1),%r25
  90. mtctl %r25,%cr29
  91. copy %r1,%r24
  92. bl sys_clone,%r2
  93. ldi SIGCHLD,%r26
  94. LDREG -84(%r30),%r2
  95. fork_return:
  96. ldo -64(%r30),%r30
  97. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  98. reg_restore %r1
  99. /*
  100. * HP-UX wants pid (child gets parent pid, parent gets child pid)
  101. * in r28 and a flag in r29 (r29 == 1 for child, 0 for parent).
  102. * Linux fork returns 0 for child, pid for parent. Since HP-UX
  103. * libc stub throws away parent pid and returns 0 for child,
  104. * we'll just return 0 for parent pid now. Only applications
  105. * that jump directly to the gateway page (not supported) will
  106. * know the difference. We can fix this later if necessary.
  107. */
  108. ldo -1024(%r0),%r1
  109. comb,>>=,n %r28,%r1,fork_exit /* just let the syscall exit handle it */
  110. or,= %r28,%r0,%r0
  111. or,tr %r0,%r0,%r29 /* r28 <> 0, we are parent, set r29 to 0 */
  112. ldo 1(%r0),%r29 /* r28 == 0, we are child, set r29 to 1 */
  113. fork_exit:
  114. bv %r0(%r2)
  115. nop
  116. /* Set the return value for the child */
  117. hpux_child_return:
  118. #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
  119. bl schedule_tail, %r2
  120. nop
  121. #endif
  122. LDREG TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
  123. b fork_return
  124. copy %r0,%r28
  125. .export hpux_execve_wrapper
  126. .export hpux_execv_wrapper
  127. .import hpux_execve
  128. hpux_execv_wrapper:
  129. copy %r0,%r24 /* NULL environment */
  130. hpux_execve_wrapper:
  131. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  132. /*
  133. * Do we need to save/restore r3-r18 here?
  134. * I don't think so. why would new thread need old
  135. * threads registers?
  136. */
  137. /* Store arg0, arg1 and arg2 so that hpux_execve will find them */
  138. STREG %r26,PT_GR26(%r1)
  139. STREG %r25,PT_GR25(%r1)
  140. STREG %r24,PT_GR24(%r1)
  141. STREG %r2,-20(%r30)
  142. ldo 64(%r30),%r30
  143. bl hpux_execve,%r2
  144. copy %r1,%arg0
  145. ldo -64(%r30),%r30
  146. LDREG -20(%r30),%r2
  147. /* If exec succeeded we need to load the args */
  148. ldo -1024(%r0),%r1
  149. comb,>>= %r28,%r1,exec_error
  150. copy %r2,%r19
  151. ldo -TASK_SZ_ALGN-64(%r30),%r1 ;! get task ptr
  152. LDREG TASK_PT_GR26(%r1),%r26
  153. LDREG TASK_PT_GR25(%r1),%r25
  154. LDREG TASK_PT_GR24(%r1),%r24
  155. LDREG TASK_PT_GR23(%r1),%r23
  156. copy %r0,%r2 /* Flag to syscall_exit not to clear args */
  157. exec_error:
  158. bv %r0(%r19)
  159. nop
  160. .export hpux_pipe_wrapper
  161. .import hpux_pipe
  162. /* HP-UX expects pipefd's returned in r28 & r29 */
  163. hpux_pipe_wrapper:
  164. STREG %r2,-20(%r30)
  165. ldo 64(%r30),%r30
  166. bl hpux_pipe,%r2
  167. ldo -56(%r30),%r26 /* pass local array to hpux_pipe */
  168. ldo -1024(%r0),%r1
  169. comb,>>= %r28,%r1,pipe_exit /* let syscall exit handle it */
  170. LDREG -84(%r30),%r2
  171. /* if success, load fd's from stack array */
  172. LDREG -56(%r30),%r28
  173. LDREG -52(%r30),%r29
  174. pipe_exit:
  175. bv %r0(%r2)
  176. ldo -64(%r30),%r30
  177. .export hpux_syscall_exit
  178. .import syscall_exit
  179. hpux_syscall_exit:
  180. /*
  181. *
  182. * HP-UX call return conventions:
  183. *
  184. * if error:
  185. * r22 = 1
  186. * r28 = errno value
  187. * r29 = secondary return value
  188. * else
  189. * r22 = 0
  190. * r28 = return value
  191. * r29 = secondary return value
  192. *
  193. * For now, we'll just check to see if r28 is < (unsigned long)-1024
  194. * (to handle addresses > 2 Gb) and if so set r22 to zero. If not,
  195. * we'll complement r28 and set r22 to 1. Wrappers will be
  196. * needed for syscalls that care about the secondary return value.
  197. * The wrapper may also need a way of avoiding the following code,
  198. * but we'll deal with that when it becomes necessary.
  199. */
  200. ldo -1024(%r0),%r1
  201. comb,<< %r28,%r1,no_error
  202. copy %r0,%r22
  203. subi 0,%r28,%r28
  204. ldo 1(%r0),%r22
  205. no_error:
  206. b syscall_exit
  207. nop
  208. .export hpux_unimplemented_wrapper
  209. .import hpux_unimplemented
  210. hpux_unimplemented_wrapper:
  211. b hpux_unimplemented
  212. STREG %r22,-64(%r30) /* overwrite arg8 with syscall number */