bsd-proc.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * process related system call shims and definitions
  3. *
  4. * Copyright (c) 2013-2014 Stacey D. Son
  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, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef BSD_PROC_H_
  20. #define BSD_PROC_H_
  21. #include <sys/resource.h>
  22. #include "qemu-bsd.h"
  23. #include "gdbstub/syscalls.h"
  24. #include "qemu/plugin.h"
  25. extern int _getlogin(char*, int);
  26. int bsd_get_ncpu(void);
  27. /* exit(2) */
  28. static inline abi_long do_bsd_exit(void *cpu_env, abi_long arg1)
  29. {
  30. gdb_exit(arg1);
  31. qemu_plugin_user_exit();
  32. _exit(arg1);
  33. return 0;
  34. }
  35. /* getgroups(2) */
  36. static inline abi_long do_bsd_getgroups(abi_long gidsetsize, abi_long arg2)
  37. {
  38. abi_long ret;
  39. uint32_t *target_grouplist;
  40. g_autofree gid_t *grouplist;
  41. int i;
  42. grouplist = g_try_new(gid_t, gidsetsize);
  43. ret = get_errno(getgroups(gidsetsize, grouplist));
  44. if (gidsetsize != 0) {
  45. if (!is_error(ret)) {
  46. target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
  47. if (!target_grouplist) {
  48. return -TARGET_EFAULT;
  49. }
  50. for (i = 0; i < ret; i++) {
  51. target_grouplist[i] = tswap32(grouplist[i]);
  52. }
  53. unlock_user(target_grouplist, arg2, gidsetsize * 2);
  54. }
  55. }
  56. return ret;
  57. }
  58. /* setgroups(2) */
  59. static inline abi_long do_bsd_setgroups(abi_long gidsetsize, abi_long arg2)
  60. {
  61. uint32_t *target_grouplist;
  62. g_autofree gid_t *grouplist;
  63. int i;
  64. grouplist = g_try_new(gid_t, gidsetsize);
  65. target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
  66. if (!target_grouplist) {
  67. return -TARGET_EFAULT;
  68. }
  69. for (i = 0; i < gidsetsize; i++) {
  70. grouplist[i] = tswap32(target_grouplist[i]);
  71. }
  72. unlock_user(target_grouplist, arg2, 0);
  73. return get_errno(setgroups(gidsetsize, grouplist));
  74. }
  75. /* umask(2) */
  76. static inline abi_long do_bsd_umask(abi_long arg1)
  77. {
  78. return get_errno(umask(arg1));
  79. }
  80. /* setlogin(2) */
  81. static inline abi_long do_bsd_setlogin(abi_long arg1)
  82. {
  83. abi_long ret;
  84. void *p;
  85. p = lock_user_string(arg1);
  86. if (p == NULL) {
  87. return -TARGET_EFAULT;
  88. }
  89. ret = get_errno(setlogin(p));
  90. unlock_user(p, arg1, 0);
  91. return ret;
  92. }
  93. /* getlogin(2) */
  94. static inline abi_long do_bsd_getlogin(abi_long arg1, abi_long arg2)
  95. {
  96. abi_long ret;
  97. void *p;
  98. p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
  99. if (p == NULL) {
  100. return -TARGET_EFAULT;
  101. }
  102. ret = get_errno(_getlogin(p, arg2));
  103. unlock_user(p, arg1, arg2);
  104. return ret;
  105. }
  106. /* getrusage(2) */
  107. static inline abi_long do_bsd_getrusage(abi_long who, abi_ulong target_addr)
  108. {
  109. abi_long ret;
  110. struct rusage rusage;
  111. ret = get_errno(getrusage(who, &rusage));
  112. if (!is_error(ret)) {
  113. host_to_target_rusage(target_addr, &rusage);
  114. }
  115. return ret;
  116. }
  117. /* getrlimit(2) */
  118. static inline abi_long do_bsd_getrlimit(abi_long arg1, abi_ulong arg2)
  119. {
  120. abi_long ret;
  121. int resource = target_to_host_resource(arg1);
  122. struct target_rlimit *target_rlim;
  123. struct rlimit rlim;
  124. switch (resource) {
  125. case RLIMIT_STACK:
  126. rlim.rlim_cur = target_dflssiz;
  127. rlim.rlim_max = target_maxssiz;
  128. ret = 0;
  129. break;
  130. case RLIMIT_DATA:
  131. rlim.rlim_cur = target_dfldsiz;
  132. rlim.rlim_max = target_maxdsiz;
  133. ret = 0;
  134. break;
  135. default:
  136. ret = get_errno(getrlimit(resource, &rlim));
  137. break;
  138. }
  139. if (!is_error(ret)) {
  140. if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) {
  141. return -TARGET_EFAULT;
  142. }
  143. target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
  144. target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
  145. unlock_user_struct(target_rlim, arg2, 1);
  146. }
  147. return ret;
  148. }
  149. /* setrlimit(2) */
  150. static inline abi_long do_bsd_setrlimit(abi_long arg1, abi_ulong arg2)
  151. {
  152. abi_long ret;
  153. int resource = target_to_host_resource(arg1);
  154. struct target_rlimit *target_rlim;
  155. struct rlimit rlim;
  156. if (RLIMIT_STACK == resource) {
  157. /* XXX We should, maybe, allow the stack size to shrink */
  158. ret = -TARGET_EPERM;
  159. } else {
  160. if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) {
  161. return -TARGET_EFAULT;
  162. }
  163. rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
  164. rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
  165. unlock_user_struct(target_rlim, arg2, 0);
  166. ret = get_errno(setrlimit(resource, &rlim));
  167. }
  168. return ret;
  169. }
  170. /* getpid(2) */
  171. static inline abi_long do_bsd_getpid(void)
  172. {
  173. return get_errno(getpid());
  174. }
  175. /* getppid(2) */
  176. static inline abi_long do_bsd_getppid(void)
  177. {
  178. return get_errno(getppid());
  179. }
  180. /* getuid(2) */
  181. static inline abi_long do_bsd_getuid(void)
  182. {
  183. return get_errno(getuid());
  184. }
  185. /* geteuid(2) */
  186. static inline abi_long do_bsd_geteuid(void)
  187. {
  188. return get_errno(geteuid());
  189. }
  190. /* getgid(2) */
  191. static inline abi_long do_bsd_getgid(void)
  192. {
  193. return get_errno(getgid());
  194. }
  195. /* getegid(2) */
  196. static inline abi_long do_bsd_getegid(void)
  197. {
  198. return get_errno(getegid());
  199. }
  200. /* setuid(2) */
  201. static inline abi_long do_bsd_setuid(abi_long arg1)
  202. {
  203. return get_errno(setuid(arg1));
  204. }
  205. /* seteuid(2) */
  206. static inline abi_long do_bsd_seteuid(abi_long arg1)
  207. {
  208. return get_errno(seteuid(arg1));
  209. }
  210. /* setgid(2) */
  211. static inline abi_long do_bsd_setgid(abi_long arg1)
  212. {
  213. return get_errno(setgid(arg1));
  214. }
  215. /* setegid(2) */
  216. static inline abi_long do_bsd_setegid(abi_long arg1)
  217. {
  218. return get_errno(setegid(arg1));
  219. }
  220. /* getpgid(2) */
  221. static inline abi_long do_bsd_getpgid(pid_t pid)
  222. {
  223. return get_errno(getpgid(pid));
  224. }
  225. /* setpgid(2) */
  226. static inline abi_long do_bsd_setpgid(int pid, int pgrp)
  227. {
  228. return get_errno(setpgid(pid, pgrp));
  229. }
  230. /* getpgrp(2) */
  231. static inline abi_long do_bsd_getpgrp(void)
  232. {
  233. return get_errno(getpgrp());
  234. }
  235. /* setreuid(2) */
  236. static inline abi_long do_bsd_setreuid(abi_long arg1, abi_long arg2)
  237. {
  238. return get_errno(setreuid(arg1, arg2));
  239. }
  240. /* setregid(2) */
  241. static inline abi_long do_bsd_setregid(abi_long arg1, abi_long arg2)
  242. {
  243. return get_errno(setregid(arg1, arg2));
  244. }
  245. /* setresgid(2) */
  246. static inline abi_long do_bsd_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
  247. {
  248. return get_errno(setresgid(rgid, egid, sgid));
  249. }
  250. /* setresuid(2) */
  251. static inline abi_long do_bsd_setresuid(uid_t ruid, uid_t euid, uid_t suid)
  252. {
  253. return get_errno(setresuid(ruid, euid, suid));
  254. }
  255. /* getresuid(2) */
  256. static inline abi_long do_bsd_getresuid(abi_ulong arg1, abi_ulong arg2,
  257. abi_ulong arg3)
  258. {
  259. abi_long ret;
  260. uid_t ruid, euid, suid;
  261. ret = get_errno(getresuid(&ruid, &euid, &suid));
  262. if (is_error(ret)) {
  263. return ret;
  264. }
  265. if (put_user_s32(ruid, arg1)) {
  266. return -TARGET_EFAULT;
  267. }
  268. if (put_user_s32(euid, arg2)) {
  269. return -TARGET_EFAULT;
  270. }
  271. if (put_user_s32(suid, arg3)) {
  272. return -TARGET_EFAULT;
  273. }
  274. return ret;
  275. }
  276. /* getresgid(2) */
  277. static inline abi_long do_bsd_getresgid(abi_ulong arg1, abi_ulong arg2,
  278. abi_ulong arg3)
  279. {
  280. abi_long ret;
  281. uid_t ruid, euid, suid;
  282. ret = get_errno(getresgid(&ruid, &euid, &suid));
  283. if (is_error(ret)) {
  284. return ret;
  285. }
  286. if (put_user_s32(ruid, arg1)) {
  287. return -TARGET_EFAULT;
  288. }
  289. if (put_user_s32(euid, arg2)) {
  290. return -TARGET_EFAULT;
  291. }
  292. if (put_user_s32(suid, arg3)) {
  293. return -TARGET_EFAULT;
  294. }
  295. return ret;
  296. }
  297. /* getsid(2) */
  298. static inline abi_long do_bsd_getsid(abi_long arg1)
  299. {
  300. return get_errno(getsid(arg1));
  301. }
  302. /* setsid(2) */
  303. static inline abi_long do_bsd_setsid(void)
  304. {
  305. return get_errno(setsid());
  306. }
  307. /* issetugid(2) */
  308. static inline abi_long do_bsd_issetugid(void)
  309. {
  310. return get_errno(issetugid());
  311. }
  312. /* profil(2) */
  313. static inline abi_long do_bsd_profil(abi_long arg1, abi_long arg2,
  314. abi_long arg3, abi_long arg4)
  315. {
  316. return -TARGET_ENOSYS;
  317. }
  318. /* ktrace(2) */
  319. static inline abi_long do_bsd_ktrace(abi_long arg1, abi_long arg2,
  320. abi_long arg3, abi_long arg4)
  321. {
  322. return -TARGET_ENOSYS;
  323. }
  324. /* utrace(2) */
  325. static inline abi_long do_bsd_utrace(abi_long arg1, abi_long arg2)
  326. {
  327. return -TARGET_ENOSYS;
  328. }
  329. /* ptrace(2) */
  330. static inline abi_long do_bsd_ptrace(abi_long arg1, abi_long arg2,
  331. abi_long arg3, abi_long arg4)
  332. {
  333. return -TARGET_ENOSYS;
  334. }
  335. /* getpriority(2) */
  336. static inline abi_long do_bsd_getpriority(abi_long which, abi_long who)
  337. {
  338. abi_long ret;
  339. /*
  340. * Note that negative values are valid for getpriority, so we must
  341. * differentiate based on errno settings.
  342. */
  343. errno = 0;
  344. ret = getpriority(which, who);
  345. if (ret == -1 && errno != 0) {
  346. return -host_to_target_errno(errno);
  347. }
  348. return ret;
  349. }
  350. /* setpriority(2) */
  351. static inline abi_long do_bsd_setpriority(abi_long which, abi_long who,
  352. abi_long prio)
  353. {
  354. return get_errno(setpriority(which, who, prio));
  355. }
  356. #endif /* !BSD_PROC_H_ */