syscall.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * BSD syscalls
  3. *
  4. * Copyright (c) 2003 - 2008 Fabrice Bellard
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <stdint.h>
  23. #include <stdarg.h>
  24. #include <string.h>
  25. #include <errno.h>
  26. #include <unistd.h>
  27. #include <fcntl.h>
  28. #include <time.h>
  29. #include <limits.h>
  30. #include <sys/types.h>
  31. #include <sys/mman.h>
  32. #include <sys/syscall.h>
  33. #include <signal.h>
  34. #include <utime.h>
  35. #include "qemu.h"
  36. #include "qemu-common.h"
  37. //#define DEBUG
  38. static abi_ulong target_brk;
  39. static abi_ulong target_original_brk;
  40. #define get_errno(x) (x)
  41. #define target_to_host_bitmask(x, tbl) (x)
  42. void target_set_brk(abi_ulong new_brk)
  43. {
  44. target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
  45. }
  46. /* do_syscall() should always have a single exit point at the end so
  47. that actions, such as logging of syscall results, can be performed.
  48. All errnos that do_syscall() returns must be -TARGET_<errcode>. */
  49. abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
  50. abi_long arg2, abi_long arg3, abi_long arg4,
  51. abi_long arg5, abi_long arg6)
  52. {
  53. abi_long ret;
  54. void *p;
  55. #ifdef DEBUG
  56. gemu_log("freebsd syscall %d\n", num);
  57. #endif
  58. if(do_strace)
  59. print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
  60. switch(num) {
  61. case TARGET_FREEBSD_NR_exit:
  62. #ifdef HAVE_GPROF
  63. _mcleanup();
  64. #endif
  65. gdb_exit(cpu_env, arg1);
  66. /* XXX: should free thread stack and CPU env */
  67. _exit(arg1);
  68. ret = 0; /* avoid warning */
  69. break;
  70. case TARGET_FREEBSD_NR_read:
  71. if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
  72. goto efault;
  73. ret = get_errno(read(arg1, p, arg3));
  74. unlock_user(p, arg2, ret);
  75. break;
  76. case TARGET_FREEBSD_NR_write:
  77. if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
  78. goto efault;
  79. ret = get_errno(write(arg1, p, arg3));
  80. unlock_user(p, arg2, 0);
  81. break;
  82. case TARGET_FREEBSD_NR_open:
  83. if (!(p = lock_user_string(arg1)))
  84. goto efault;
  85. ret = get_errno(open(path(p),
  86. target_to_host_bitmask(arg2, fcntl_flags_tbl),
  87. arg3));
  88. unlock_user(p, arg1, 0);
  89. break;
  90. case TARGET_FREEBSD_NR_mmap:
  91. ret = get_errno(target_mmap(arg1, arg2, arg3,
  92. target_to_host_bitmask(arg4, mmap_flags_tbl),
  93. arg5,
  94. arg6));
  95. break;
  96. case TARGET_FREEBSD_NR_mprotect:
  97. ret = get_errno(target_mprotect(arg1, arg2, arg3));
  98. break;
  99. case TARGET_FREEBSD_NR_syscall:
  100. case TARGET_FREEBSD_NR___syscall:
  101. ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
  102. break;
  103. default:
  104. ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
  105. break;
  106. }
  107. fail:
  108. #ifdef DEBUG
  109. gemu_log(" = %ld\n", ret);
  110. #endif
  111. if (do_strace)
  112. print_freebsd_syscall_ret(num, ret);
  113. return ret;
  114. efault:
  115. ret = -TARGET_EFAULT;
  116. goto fail;
  117. }
  118. abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
  119. abi_long arg2, abi_long arg3, abi_long arg4,
  120. abi_long arg5, abi_long arg6)
  121. {
  122. abi_long ret;
  123. void *p;
  124. #ifdef DEBUG
  125. gemu_log("netbsd syscall %d\n", num);
  126. #endif
  127. if(do_strace)
  128. print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
  129. switch(num) {
  130. case TARGET_NETBSD_NR_exit:
  131. #ifdef HAVE_GPROF
  132. _mcleanup();
  133. #endif
  134. gdb_exit(cpu_env, arg1);
  135. /* XXX: should free thread stack and CPU env */
  136. _exit(arg1);
  137. ret = 0; /* avoid warning */
  138. break;
  139. case TARGET_NETBSD_NR_read:
  140. if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
  141. goto efault;
  142. ret = get_errno(read(arg1, p, arg3));
  143. unlock_user(p, arg2, ret);
  144. break;
  145. case TARGET_NETBSD_NR_write:
  146. if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
  147. goto efault;
  148. ret = get_errno(write(arg1, p, arg3));
  149. unlock_user(p, arg2, 0);
  150. break;
  151. case TARGET_NETBSD_NR_open:
  152. if (!(p = lock_user_string(arg1)))
  153. goto efault;
  154. ret = get_errno(open(path(p),
  155. target_to_host_bitmask(arg2, fcntl_flags_tbl),
  156. arg3));
  157. unlock_user(p, arg1, 0);
  158. break;
  159. case TARGET_NETBSD_NR_mmap:
  160. ret = get_errno(target_mmap(arg1, arg2, arg3,
  161. target_to_host_bitmask(arg4, mmap_flags_tbl),
  162. arg5,
  163. arg6));
  164. break;
  165. case TARGET_NETBSD_NR_mprotect:
  166. ret = get_errno(target_mprotect(arg1, arg2, arg3));
  167. break;
  168. case TARGET_NETBSD_NR_syscall:
  169. case TARGET_NETBSD_NR___syscall:
  170. ret = do_netbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
  171. break;
  172. default:
  173. ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
  174. break;
  175. }
  176. fail:
  177. #ifdef DEBUG
  178. gemu_log(" = %ld\n", ret);
  179. #endif
  180. if (do_strace)
  181. print_netbsd_syscall_ret(num, ret);
  182. return ret;
  183. efault:
  184. ret = -TARGET_EFAULT;
  185. goto fail;
  186. }
  187. abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
  188. abi_long arg2, abi_long arg3, abi_long arg4,
  189. abi_long arg5, abi_long arg6)
  190. {
  191. abi_long ret;
  192. void *p;
  193. #ifdef DEBUG
  194. gemu_log("openbsd syscall %d\n", num);
  195. #endif
  196. if(do_strace)
  197. print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
  198. switch(num) {
  199. case TARGET_OPENBSD_NR_exit:
  200. #ifdef HAVE_GPROF
  201. _mcleanup();
  202. #endif
  203. gdb_exit(cpu_env, arg1);
  204. /* XXX: should free thread stack and CPU env */
  205. _exit(arg1);
  206. ret = 0; /* avoid warning */
  207. break;
  208. case TARGET_OPENBSD_NR_read:
  209. if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
  210. goto efault;
  211. ret = get_errno(read(arg1, p, arg3));
  212. unlock_user(p, arg2, ret);
  213. break;
  214. case TARGET_OPENBSD_NR_write:
  215. if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
  216. goto efault;
  217. ret = get_errno(write(arg1, p, arg3));
  218. unlock_user(p, arg2, 0);
  219. break;
  220. case TARGET_OPENBSD_NR_open:
  221. if (!(p = lock_user_string(arg1)))
  222. goto efault;
  223. ret = get_errno(open(path(p),
  224. target_to_host_bitmask(arg2, fcntl_flags_tbl),
  225. arg3));
  226. unlock_user(p, arg1, 0);
  227. break;
  228. case TARGET_OPENBSD_NR_mmap:
  229. ret = get_errno(target_mmap(arg1, arg2, arg3,
  230. target_to_host_bitmask(arg4, mmap_flags_tbl),
  231. arg5,
  232. arg6));
  233. break;
  234. case TARGET_OPENBSD_NR_mprotect:
  235. ret = get_errno(target_mprotect(arg1, arg2, arg3));
  236. break;
  237. case TARGET_OPENBSD_NR_syscall:
  238. case TARGET_OPENBSD_NR___syscall:
  239. ret = do_openbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
  240. break;
  241. default:
  242. ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
  243. break;
  244. }
  245. fail:
  246. #ifdef DEBUG
  247. gemu_log(" = %ld\n", ret);
  248. #endif
  249. if (do_strace)
  250. print_openbsd_syscall_ret(num, ret);
  251. return ret;
  252. efault:
  253. ret = -TARGET_EFAULT;
  254. goto fail;
  255. }
  256. void syscall_init(void)
  257. {
  258. }