Emulator_syscalls.cpp 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500
  1. /*
  2. * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "Emulator.h"
  7. #include "MmapRegion.h"
  8. #include "SimpleRegion.h"
  9. #include <AK/Debug.h>
  10. #include <AK/Format.h>
  11. #include <fcntl.h>
  12. #include <sched.h>
  13. #include <serenity.h>
  14. #include <strings.h>
  15. #include <sys/ioctl.h>
  16. #include <sys/mman.h>
  17. #include <sys/select.h>
  18. #include <sys/socket.h>
  19. #include <sys/stat.h>
  20. #include <sys/time.h>
  21. #include <sys/uio.h>
  22. #include <syscall.h>
  23. #include <termios.h>
  24. #if defined(__GNUC__) && !defined(__clang__)
  25. # pragma GCC optimize("O3")
  26. #endif
  27. namespace UserspaceEmulator {
  28. u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
  29. {
  30. if constexpr (SPAM_DEBUG)
  31. reportln("Syscall: {} ({:x})", Syscall::to_string((Syscall::Function)function), function);
  32. switch (function) {
  33. case SC_chdir:
  34. return virt$chdir(arg1, arg2);
  35. case SC_dup2:
  36. return virt$dup2(arg1, arg2);
  37. case SC_get_stack_bounds:
  38. return virt$get_stack_bounds(arg1, arg2);
  39. case SC_access:
  40. return virt$access(arg1, arg2, arg3);
  41. case SC_waitid:
  42. return virt$waitid(arg1);
  43. case SC_getcwd:
  44. return virt$getcwd(arg1, arg2);
  45. case SC_ttyname:
  46. return virt$ttyname(arg1, arg2, arg3);
  47. case SC_getpgrp:
  48. return virt$getpgrp();
  49. case SC_getpgid:
  50. return virt$getpgid(arg1);
  51. case SC_setpgid:
  52. return virt$setpgid(arg1, arg2);
  53. case SC_execve:
  54. return virt$execve(arg1);
  55. case SC_sigaction:
  56. return virt$sigaction(arg1, arg2, arg3);
  57. case SC_sigreturn:
  58. return virt$sigreturn();
  59. case SC_stat:
  60. return virt$stat(arg1);
  61. case SC_realpath:
  62. return virt$realpath(arg1);
  63. case SC_gethostname:
  64. return virt$gethostname(arg1, arg2);
  65. case SC_ioctl:
  66. return virt$ioctl(arg1, arg2, arg3);
  67. case SC_get_dir_entries:
  68. return virt$get_dir_entries(arg1, arg2, arg3);
  69. case SC_profiling_enable:
  70. return virt$profiling_enable(arg1);
  71. case SC_profiling_disable:
  72. return virt$profiling_disable(arg1);
  73. case SC_disown:
  74. return virt$disown(arg1);
  75. case SC_purge:
  76. return virt$purge(arg1);
  77. case SC_mmap:
  78. return virt$mmap(arg1);
  79. case SC_mount:
  80. return virt$mount(arg1);
  81. case SC_munmap:
  82. return virt$munmap(arg1, arg2);
  83. case SC_mremap:
  84. return virt$mremap(arg1);
  85. case SC_gettid:
  86. return virt$gettid();
  87. case SC_getpid:
  88. return virt$getpid();
  89. case SC_getsid:
  90. return virt$getsid(arg1);
  91. case SC_pledge:
  92. return virt$pledge(arg1);
  93. case SC_unveil:
  94. return virt$unveil(arg1);
  95. case SC_getuid:
  96. return virt$getuid();
  97. case SC_geteuid:
  98. return virt$geteuid();
  99. case SC_getgid:
  100. return virt$getgid();
  101. case SC_getegid:
  102. return virt$getegid();
  103. case SC_setuid:
  104. return virt$setuid(arg1);
  105. case SC_setgid:
  106. return virt$setgid(arg2);
  107. case SC_close:
  108. return virt$close(arg1);
  109. case SC_fstat:
  110. return virt$fstat(arg1, arg2);
  111. case SC_mkdir:
  112. return virt$mkdir(arg1, arg2, arg3);
  113. case SC_rmdir:
  114. return virt$rmdir(arg1, arg2);
  115. case SC_unlink:
  116. return virt$unlink(arg1, arg2);
  117. case SC_symlink:
  118. return virt$symlink(arg1);
  119. case SC_rename:
  120. return virt$rename(arg1);
  121. case SC_set_coredump_metadata:
  122. return virt$set_coredump_metadata(arg1);
  123. case SC_write:
  124. return virt$write(arg1, arg2, arg3);
  125. case SC_read:
  126. return virt$read(arg1, arg2, arg3);
  127. case SC_mprotect:
  128. return virt$mprotect(arg1, arg2, arg3);
  129. case SC_madvise:
  130. return virt$madvise(arg1, arg2, arg3);
  131. case SC_anon_create:
  132. return virt$anon_create(arg1, arg2);
  133. case SC_sendfd:
  134. return virt$sendfd(arg1, arg2);
  135. case SC_recvfd:
  136. return virt$recvfd(arg1, arg2);
  137. case SC_open:
  138. return virt$open(arg1);
  139. case SC_pipe:
  140. return virt$pipe(arg1, arg2);
  141. case SC_fcntl:
  142. return virt$fcntl(arg1, arg2, arg3);
  143. case SC_getgroups:
  144. return virt$getgroups(arg1, arg2);
  145. case SC_setgroups:
  146. return virt$setgroups(arg1, arg2);
  147. case SC_lseek:
  148. return virt$lseek(arg1, arg2, arg3);
  149. case SC_socket:
  150. return virt$socket(arg1, arg2, arg3);
  151. case SC_getsockopt:
  152. return virt$getsockopt(arg1);
  153. case SC_get_process_name:
  154. return virt$get_process_name(arg1, arg2);
  155. case SC_set_process_name:
  156. return virt$set_process_name(arg1, arg2);
  157. case SC_dbgputstr:
  158. return virt$dbgputstr(arg1, arg2);
  159. case SC_dbgputch:
  160. return virt$dbgputch(arg1);
  161. case SC_chmod:
  162. return virt$chmod(arg1, arg2, arg3);
  163. case SC_fchmod:
  164. return virt$fchmod(arg1, arg2);
  165. case SC_fchown:
  166. return virt$fchown(arg1, arg2, arg3);
  167. case SC_accept:
  168. return virt$accept(arg1, arg2, arg3);
  169. case SC_setsockopt:
  170. return virt$setsockopt(arg1);
  171. case SC_getsockname:
  172. return virt$getsockname(arg1);
  173. case SC_getpeername:
  174. return virt$getpeername(arg1);
  175. case SC_bind:
  176. return virt$bind(arg1, arg2, arg3);
  177. case SC_connect:
  178. return virt$connect(arg1, arg2, arg3);
  179. case SC_shutdown:
  180. return virt$shutdown(arg1, arg2);
  181. case SC_listen:
  182. return virt$listen(arg1, arg2);
  183. case SC_select:
  184. return virt$select(arg1);
  185. case SC_recvmsg:
  186. return virt$recvmsg(arg1, arg2, arg3);
  187. case SC_sendmsg:
  188. return virt$sendmsg(arg1, arg2, arg3);
  189. case SC_kill:
  190. return virt$kill(arg1, arg2);
  191. case SC_killpg:
  192. return virt$killpg(arg1, arg2);
  193. case SC_set_mmap_name:
  194. return virt$set_mmap_name(arg1);
  195. case SC_sync:
  196. virt$sync();
  197. return 0;
  198. case SC_exit:
  199. virt$exit((int)arg1);
  200. return 0;
  201. case SC_gettimeofday:
  202. return virt$gettimeofday(arg1);
  203. case SC_clock_gettime:
  204. return virt$clock_gettime(arg1, arg2);
  205. case SC_clock_settime:
  206. return virt$clock_settime(arg1, arg2);
  207. case SC_getrandom:
  208. return virt$getrandom(arg1, arg2, arg3);
  209. case SC_fork:
  210. return virt$fork();
  211. case SC_emuctl:
  212. return virt$emuctl(arg1, arg2, arg3);
  213. case SC_sched_getparam:
  214. return virt$sched_getparam(arg1, arg2);
  215. case SC_sched_setparam:
  216. return virt$sched_setparam(arg1, arg2);
  217. case SC_set_thread_name:
  218. return virt$set_thread_name(arg1, arg2, arg3);
  219. case SC_setsid:
  220. return virt$setsid();
  221. case SC_create_inode_watcher:
  222. return virt$create_inode_watcher(arg1);
  223. case SC_inode_watcher_add_watch:
  224. return virt$inode_watcher_add_watch(arg1);
  225. case SC_inode_watcher_remove_watch:
  226. return virt$inode_watcher_remove_watch(arg1, arg2);
  227. case SC_clock_nanosleep:
  228. return virt$clock_nanosleep(arg1);
  229. case SC_readlink:
  230. return virt$readlink(arg1);
  231. case SC_ptsname:
  232. return virt$ptsname(arg1, arg2, arg3);
  233. case SC_allocate_tls:
  234. return virt$allocate_tls(arg1, arg2);
  235. case SC_beep:
  236. return virt$beep();
  237. case SC_ftruncate:
  238. return virt$ftruncate(arg1, arg2);
  239. case SC_umask:
  240. return virt$umask(arg1);
  241. case SC_chown:
  242. return virt$chown(arg1);
  243. case SC_msyscall:
  244. return virt$msyscall(arg1);
  245. case SC_futex:
  246. return virt$futex(arg1);
  247. default:
  248. reportln("\n=={}== \033[31;1mUnimplemented syscall: {}\033[0m, {:p}", getpid(), Syscall::to_string((Syscall::Function)function), function);
  249. dump_backtrace();
  250. TODO();
  251. }
  252. }
  253. int Emulator::virt$anon_create(size_t size, int options)
  254. {
  255. return syscall(SC_anon_create, size, options);
  256. }
  257. int Emulator::virt$sendfd(int socket, int fd)
  258. {
  259. return syscall(SC_sendfd, socket, fd);
  260. }
  261. int Emulator::virt$recvfd(int socket, int options)
  262. {
  263. return syscall(SC_recvfd, socket, options);
  264. }
  265. int Emulator::virt$profiling_enable(pid_t pid)
  266. {
  267. return syscall(SC_profiling_enable, pid);
  268. }
  269. int Emulator::virt$profiling_disable(pid_t pid)
  270. {
  271. return syscall(SC_profiling_disable, pid);
  272. }
  273. int Emulator::virt$disown(pid_t pid)
  274. {
  275. return syscall(SC_disown, pid);
  276. }
  277. int Emulator::virt$purge(int mode)
  278. {
  279. return syscall(SC_purge, mode);
  280. }
  281. int Emulator::virt$fstat(int fd, FlatPtr statbuf)
  282. {
  283. struct stat local_statbuf;
  284. int rc = syscall(SC_fstat, fd, &local_statbuf);
  285. if (rc < 0)
  286. return rc;
  287. mmu().copy_to_vm(statbuf, &local_statbuf, sizeof(local_statbuf));
  288. return rc;
  289. }
  290. int Emulator::virt$close(int fd)
  291. {
  292. return syscall(SC_close, fd);
  293. }
  294. int Emulator::virt$mkdir(FlatPtr path, size_t path_length, mode_t mode)
  295. {
  296. auto buffer = mmu().copy_buffer_from_vm(path, path_length);
  297. return syscall(SC_mkdir, buffer.data(), buffer.size(), mode);
  298. }
  299. int Emulator::virt$rmdir(FlatPtr path, size_t path_length)
  300. {
  301. auto buffer = mmu().copy_buffer_from_vm(path, path_length);
  302. return syscall(SC_rmdir, buffer.data(), buffer.size());
  303. }
  304. int Emulator::virt$unlink(FlatPtr path, size_t path_length)
  305. {
  306. auto buffer = mmu().copy_buffer_from_vm(path, path_length);
  307. return syscall(SC_unlink, buffer.data(), buffer.size());
  308. }
  309. int Emulator::virt$symlink(FlatPtr params_addr)
  310. {
  311. Syscall::SC_symlink_params params;
  312. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  313. auto target = mmu().copy_buffer_from_vm((FlatPtr)params.target.characters, params.target.length);
  314. params.target.characters = (const char*)target.data();
  315. params.target.length = target.size();
  316. auto link = mmu().copy_buffer_from_vm((FlatPtr)params.linkpath.characters, params.linkpath.length);
  317. params.linkpath.characters = (const char*)link.data();
  318. params.linkpath.length = link.size();
  319. return syscall(SC_symlink, &params);
  320. }
  321. int Emulator::virt$rename(FlatPtr params_addr)
  322. {
  323. Syscall::SC_rename_params params;
  324. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  325. auto new_path = mmu().copy_buffer_from_vm((FlatPtr)params.new_path.characters, params.new_path.length);
  326. params.new_path.characters = (const char*)new_path.data();
  327. params.new_path.length = new_path.size();
  328. auto old_path = mmu().copy_buffer_from_vm((FlatPtr)params.old_path.characters, params.old_path.length);
  329. params.old_path.characters = (const char*)old_path.data();
  330. params.old_path.length = old_path.size();
  331. return syscall(SC_rename, &params);
  332. }
  333. int Emulator::virt$set_coredump_metadata(FlatPtr params_addr)
  334. {
  335. Syscall::SC_set_coredump_metadata_params params;
  336. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  337. auto key = mmu().copy_buffer_from_vm((FlatPtr)params.key.characters, params.key.length);
  338. params.key.characters = (const char*)key.data();
  339. params.key.length = key.size();
  340. auto value = mmu().copy_buffer_from_vm((FlatPtr)params.value.characters, params.value.length);
  341. params.value.characters = (const char*)value.data();
  342. params.value.length = value.size();
  343. return syscall(SC_set_coredump_metadata, &params);
  344. }
  345. int Emulator::virt$dbgputstr(FlatPtr characters, int length)
  346. {
  347. auto buffer = mmu().copy_buffer_from_vm(characters, length);
  348. dbgputstr((const char*)buffer.data(), buffer.size());
  349. return 0;
  350. }
  351. int Emulator::virt$chmod(FlatPtr path_addr, size_t path_length, mode_t mode)
  352. {
  353. auto path = mmu().copy_buffer_from_vm(path_addr, path_length);
  354. return syscall(SC_chmod, path.data(), path.size(), mode);
  355. }
  356. int Emulator::virt$chown(FlatPtr params_addr)
  357. {
  358. Syscall::SC_chown_params params;
  359. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  360. auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
  361. params.path.characters = (const char*)path.data();
  362. params.path.length = path.size();
  363. return syscall(SC_chown, &params);
  364. }
  365. int Emulator::virt$fchmod(int fd, mode_t mode)
  366. {
  367. return syscall(SC_fchmod, fd, mode);
  368. }
  369. int Emulator::virt$fchown(int fd, uid_t uid, gid_t gid)
  370. {
  371. return syscall(SC_fchown, fd, uid, gid);
  372. }
  373. int Emulator::virt$setsockopt(FlatPtr params_addr)
  374. {
  375. Syscall::SC_setsockopt_params params;
  376. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  377. if (params.option == SO_RCVTIMEO || params.option == SO_TIMESTAMP) {
  378. auto host_value_buffer = ByteBuffer::create_zeroed(params.value_size);
  379. mmu().copy_from_vm(host_value_buffer.data(), (FlatPtr)params.value, params.value_size);
  380. int rc = setsockopt(params.sockfd, params.level, params.option, host_value_buffer.data(), host_value_buffer.size());
  381. if (rc < 0)
  382. return -errno;
  383. return rc;
  384. }
  385. if (params.option == SO_BINDTODEVICE) {
  386. auto ifname = mmu().copy_buffer_from_vm((FlatPtr)params.value, params.value_size);
  387. params.value = ifname.data();
  388. params.value_size = ifname.size();
  389. return syscall(SC_setsockopt, &params);
  390. }
  391. TODO();
  392. }
  393. int Emulator::virt$get_stack_bounds(FlatPtr base, FlatPtr size)
  394. {
  395. auto* region = mmu().find_region({ m_cpu.ss(), m_cpu.esp().value() });
  396. FlatPtr b = region->base();
  397. size_t s = region->size();
  398. mmu().copy_to_vm(base, &b, sizeof(b));
  399. mmu().copy_to_vm(size, &s, sizeof(s));
  400. return 0;
  401. }
  402. int Emulator::virt$ftruncate(int fd, FlatPtr length_addr)
  403. {
  404. off_t length;
  405. mmu().copy_from_vm(&length, length_addr, sizeof(off_t));
  406. return syscall(SC_ftruncate, fd, &length);
  407. }
  408. mode_t Emulator::virt$umask(mode_t mask)
  409. {
  410. return syscall(SC_umask, mask);
  411. }
  412. int Emulator::virt$accept(int sockfd, FlatPtr address, FlatPtr address_length)
  413. {
  414. socklen_t host_address_length = 0;
  415. mmu().copy_from_vm(&host_address_length, address_length, sizeof(host_address_length));
  416. auto host_buffer = ByteBuffer::create_zeroed(host_address_length);
  417. int rc = syscall(SC_accept, sockfd, host_buffer.data(), &host_address_length);
  418. if (rc < 0)
  419. return rc;
  420. mmu().copy_to_vm(address, host_buffer.data(), min((socklen_t)host_buffer.size(), host_address_length));
  421. mmu().copy_to_vm(address_length, &host_address_length, sizeof(host_address_length));
  422. return rc;
  423. }
  424. int Emulator::virt$bind(int sockfd, FlatPtr address, socklen_t address_length)
  425. {
  426. auto buffer = mmu().copy_buffer_from_vm(address, address_length);
  427. return syscall(SC_bind, sockfd, buffer.data(), buffer.size());
  428. }
  429. int Emulator::virt$connect(int sockfd, FlatPtr address, socklen_t address_size)
  430. {
  431. auto buffer = mmu().copy_buffer_from_vm(address, address_size);
  432. return syscall(SC_connect, sockfd, buffer.data(), buffer.size());
  433. }
  434. int Emulator::virt$shutdown(int sockfd, int how)
  435. {
  436. return syscall(SC_shutdown, sockfd, how);
  437. }
  438. int Emulator::virt$dbgputch(char ch)
  439. {
  440. dbgputch(ch);
  441. return 0;
  442. }
  443. int Emulator::virt$listen(int fd, int backlog)
  444. {
  445. return syscall(SC_listen, fd, backlog);
  446. }
  447. int Emulator::virt$kill(pid_t pid, int signal)
  448. {
  449. return syscall(SC_kill, pid, signal);
  450. }
  451. int Emulator::virt$killpg(int pgrp, int sig)
  452. {
  453. return syscall(SC_killpg, pgrp, sig);
  454. }
  455. int Emulator::virt$gettimeofday(FlatPtr timeval)
  456. {
  457. struct timeval host_timeval;
  458. int rc = syscall(SC_gettimeofday, &host_timeval);
  459. if (rc < 0)
  460. return rc;
  461. mmu().copy_to_vm(timeval, &host_timeval, sizeof(host_timeval));
  462. return rc;
  463. }
  464. int Emulator::virt$clock_gettime(int clockid, FlatPtr timespec)
  465. {
  466. struct timespec host_timespec;
  467. int rc = syscall(SC_clock_gettime, clockid, &host_timespec);
  468. if (rc < 0)
  469. return rc;
  470. mmu().copy_to_vm(timespec, &host_timespec, sizeof(host_timespec));
  471. return rc;
  472. }
  473. int Emulator::virt$clock_settime(uint32_t clock_id, FlatPtr user_ts)
  474. {
  475. struct timespec user_timespec;
  476. mmu().copy_from_vm(&user_timespec, user_ts, sizeof(user_timespec));
  477. int rc = syscall(SC_clock_settime, clock_id, &user_timespec);
  478. return rc;
  479. }
  480. int Emulator::virt$set_mmap_name(FlatPtr params_addr)
  481. {
  482. Syscall::SC_set_mmap_name_params params {};
  483. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  484. auto name = mmu().copy_buffer_from_vm((FlatPtr)params.name.characters, params.name.length);
  485. auto* region = mmu().find_region({ 0x23, (FlatPtr)params.addr });
  486. if (!region || !is<MmapRegion>(*region))
  487. return -EINVAL;
  488. static_cast<MmapRegion&>(*region).set_name(String::copy(name));
  489. return 0;
  490. }
  491. int Emulator::virt$get_process_name(FlatPtr buffer, int size)
  492. {
  493. if (size < 0)
  494. return -EINVAL;
  495. auto host_buffer = ByteBuffer::create_zeroed((size_t)size);
  496. int rc = syscall(SC_get_process_name, host_buffer.data(), host_buffer.size());
  497. mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
  498. return rc;
  499. }
  500. int Emulator::virt$set_process_name(FlatPtr user_buffer, int size)
  501. {
  502. if (size < 0)
  503. return -EINVAL;
  504. auto host_buffer = mmu().copy_buffer_from_vm(user_buffer, size);
  505. auto name = String::formatted("(UE) {}", StringView { host_buffer.data(), host_buffer.size() });
  506. return syscall(SC_set_process_name, name.characters(), name.length());
  507. }
  508. int Emulator::virt$lseek(int fd, FlatPtr offset_addr, int whence)
  509. {
  510. off_t offset;
  511. mmu().copy_from_vm(&offset, offset_addr, sizeof(off_t));
  512. auto rc = syscall(SC_lseek, fd, &offset, whence);
  513. mmu().copy_to_vm(offset_addr, &offset, sizeof(off_t));
  514. return rc;
  515. }
  516. int Emulator::virt$socket(int domain, int type, int protocol)
  517. {
  518. return syscall(SC_socket, domain, type, protocol);
  519. }
  520. int Emulator::virt$recvmsg(int sockfd, FlatPtr msg_addr, int flags)
  521. {
  522. msghdr mmu_msg;
  523. mmu().copy_from_vm(&mmu_msg, msg_addr, sizeof(mmu_msg));
  524. Vector<iovec, 1> mmu_iovs;
  525. mmu_iovs.resize(mmu_msg.msg_iovlen);
  526. mmu().copy_from_vm(mmu_iovs.data(), (FlatPtr)mmu_msg.msg_iov, mmu_msg.msg_iovlen * sizeof(iovec));
  527. Vector<ByteBuffer, 1> buffers;
  528. Vector<iovec, 1> iovs;
  529. for (const auto& iov : mmu_iovs) {
  530. buffers.append(ByteBuffer::create_uninitialized(iov.iov_len));
  531. iovs.append({ buffers.last().data(), buffers.last().size() });
  532. }
  533. ByteBuffer control_buffer;
  534. if (mmu_msg.msg_control)
  535. control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
  536. sockaddr_storage addr;
  537. msghdr msg = { &addr, sizeof(addr), iovs.data(), (int)iovs.size(), mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
  538. int rc = recvmsg(sockfd, &msg, flags);
  539. if (rc < 0)
  540. return -errno;
  541. for (size_t i = 0; i < buffers.size(); ++i)
  542. mmu().copy_to_vm((FlatPtr)mmu_iovs[i].iov_base, buffers[i].data(), mmu_iovs[i].iov_len);
  543. if (mmu_msg.msg_name)
  544. mmu().copy_to_vm((FlatPtr)mmu_msg.msg_name, &addr, min(sizeof(addr), (size_t)mmu_msg.msg_namelen));
  545. if (mmu_msg.msg_control)
  546. mmu().copy_to_vm((FlatPtr)mmu_msg.msg_control, control_buffer.data(), min(mmu_msg.msg_controllen, msg.msg_controllen));
  547. mmu_msg.msg_namelen = msg.msg_namelen;
  548. mmu_msg.msg_controllen = msg.msg_controllen;
  549. mmu_msg.msg_flags = msg.msg_flags;
  550. mmu().copy_to_vm(msg_addr, &mmu_msg, sizeof(mmu_msg));
  551. return rc;
  552. }
  553. int Emulator::virt$sendmsg(int sockfd, FlatPtr msg_addr, int flags)
  554. {
  555. msghdr mmu_msg;
  556. mmu().copy_from_vm(&mmu_msg, msg_addr, sizeof(mmu_msg));
  557. Vector<iovec, 1> iovs;
  558. iovs.resize(mmu_msg.msg_iovlen);
  559. mmu().copy_from_vm(iovs.data(), (FlatPtr)mmu_msg.msg_iov, mmu_msg.msg_iovlen * sizeof(iovec));
  560. Vector<ByteBuffer, 1> buffers;
  561. for (auto& iov : iovs) {
  562. buffers.append(mmu().copy_buffer_from_vm((FlatPtr)iov.iov_base, iov.iov_len));
  563. iov = { buffers.last().data(), buffers.last().size() };
  564. }
  565. ByteBuffer control_buffer;
  566. if (mmu_msg.msg_control)
  567. control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
  568. sockaddr_storage address;
  569. socklen_t address_length = 0;
  570. if (mmu_msg.msg_name) {
  571. address_length = min(sizeof(address), (size_t)mmu_msg.msg_namelen);
  572. mmu().copy_from_vm(&address, (FlatPtr)mmu_msg.msg_name, address_length);
  573. }
  574. msghdr msg = { mmu_msg.msg_name ? &address : nullptr, address_length, iovs.data(), (int)iovs.size(), mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
  575. return sendmsg(sockfd, &msg, flags);
  576. }
  577. int Emulator::virt$select(FlatPtr params_addr)
  578. {
  579. Syscall::SC_select_params params;
  580. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  581. fd_set readfds {};
  582. fd_set writefds {};
  583. fd_set exceptfds {};
  584. struct timespec timeout;
  585. u32 sigmask;
  586. if (params.readfds)
  587. mmu().copy_from_vm(&readfds, (FlatPtr)params.readfds, sizeof(readfds));
  588. if (params.writefds)
  589. mmu().copy_from_vm(&writefds, (FlatPtr)params.writefds, sizeof(writefds));
  590. if (params.exceptfds)
  591. mmu().copy_from_vm(&exceptfds, (FlatPtr)params.exceptfds, sizeof(exceptfds));
  592. if (params.timeout)
  593. mmu().copy_from_vm(&timeout, (FlatPtr)params.timeout, sizeof(timeout));
  594. if (params.sigmask)
  595. mmu().copy_from_vm(&sigmask, (FlatPtr)params.sigmask, sizeof(sigmask));
  596. int rc = pselect(params.nfds, &readfds, &writefds, &exceptfds, params.timeout ? &timeout : nullptr, params.sigmask ? &sigmask : nullptr);
  597. if (rc < 0)
  598. return -errno;
  599. if (params.readfds)
  600. mmu().copy_to_vm((FlatPtr)params.readfds, &readfds, sizeof(readfds));
  601. if (params.writefds)
  602. mmu().copy_to_vm((FlatPtr)params.writefds, &writefds, sizeof(writefds));
  603. if (params.exceptfds)
  604. mmu().copy_to_vm((FlatPtr)params.exceptfds, &exceptfds, sizeof(exceptfds));
  605. if (params.timeout)
  606. mmu().copy_to_vm((FlatPtr)params.timeout, &timeout, sizeof(timeout));
  607. return rc;
  608. }
  609. int Emulator::virt$getsockopt(FlatPtr params_addr)
  610. {
  611. Syscall::SC_getsockopt_params params;
  612. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  613. if (params.option == SO_PEERCRED) {
  614. struct ucred creds = {};
  615. socklen_t creds_size = sizeof(creds);
  616. int rc = getsockopt(params.sockfd, params.level, SO_PEERCRED, &creds, &creds_size);
  617. if (rc < 0)
  618. return -errno;
  619. // FIXME: Check params.value_size
  620. mmu().copy_to_vm((FlatPtr)params.value, &creds, sizeof(creds));
  621. return rc;
  622. }
  623. TODO();
  624. }
  625. int Emulator::virt$getsockname(FlatPtr params_addr)
  626. {
  627. Syscall::SC_getsockname_params params;
  628. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  629. struct sockaddr addr = {};
  630. socklen_t addrlen = {};
  631. auto rc = getsockname(params.sockfd, &addr, &addrlen);
  632. mmu().copy_to_vm((FlatPtr)params.addr, &addr, sizeof(addr));
  633. mmu().copy_to_vm((FlatPtr)params.addrlen, &addrlen, sizeof(addrlen));
  634. return rc;
  635. }
  636. int Emulator::virt$getpeername(FlatPtr params_addr)
  637. {
  638. Syscall::SC_getpeername_params params;
  639. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  640. struct sockaddr addr = {};
  641. socklen_t addrlen = {};
  642. auto rc = getpeername(params.sockfd, &addr, &addrlen);
  643. mmu().copy_to_vm((FlatPtr)params.addr, &addr, sizeof(addr));
  644. mmu().copy_to_vm((FlatPtr)params.addrlen, &addrlen, sizeof(addrlen));
  645. return rc;
  646. }
  647. int Emulator::virt$getgroups(ssize_t count, FlatPtr groups)
  648. {
  649. if (!count)
  650. return syscall(SC_getgroups, 0, nullptr);
  651. auto buffer = ByteBuffer::create_uninitialized(count * sizeof(gid_t));
  652. int rc = syscall(SC_getgroups, count, buffer.data());
  653. if (rc < 0)
  654. return rc;
  655. mmu().copy_to_vm(groups, buffer.data(), buffer.size());
  656. return 0;
  657. }
  658. int Emulator::virt$setgroups(ssize_t count, FlatPtr groups)
  659. {
  660. if (!count)
  661. return syscall(SC_setgroups, 0, nullptr);
  662. auto buffer = mmu().copy_buffer_from_vm(groups, count * sizeof(gid_t));
  663. return syscall(SC_setgroups, count, buffer.data());
  664. }
  665. u32 Emulator::virt$fcntl(int fd, int cmd, u32 arg)
  666. {
  667. switch (cmd) {
  668. case F_DUPFD:
  669. case F_GETFD:
  670. case F_SETFD:
  671. case F_GETFL:
  672. case F_SETFL:
  673. case F_ISTTY:
  674. break;
  675. default:
  676. dbgln("Invalid fcntl cmd: {}", cmd);
  677. }
  678. return syscall(SC_fcntl, fd, cmd, arg);
  679. }
  680. u32 Emulator::virt$open(u32 params_addr)
  681. {
  682. Syscall::SC_open_params params;
  683. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  684. auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
  685. Syscall::SC_open_params host_params {};
  686. host_params.dirfd = params.dirfd;
  687. host_params.mode = params.mode;
  688. host_params.options = params.options;
  689. host_params.path.characters = (const char*)path.data();
  690. host_params.path.length = path.size();
  691. return syscall(SC_open, &host_params);
  692. }
  693. int Emulator::virt$pipe(FlatPtr vm_pipefd, int flags)
  694. {
  695. int pipefd[2];
  696. int rc = syscall(SC_pipe, pipefd, flags);
  697. if (rc < 0)
  698. return rc;
  699. mmu().copy_to_vm(vm_pipefd, pipefd, sizeof(pipefd));
  700. return rc;
  701. }
  702. static void round_to_page_size(FlatPtr& address, size_t& size)
  703. {
  704. auto new_end = round_up_to_power_of_two(address + size, PAGE_SIZE);
  705. address &= ~(PAGE_SIZE - 1);
  706. size = new_end - address;
  707. }
  708. u32 Emulator::virt$munmap(FlatPtr address, size_t size)
  709. {
  710. round_to_page_size(address, size);
  711. Vector<Region*, 4> marked_for_deletion;
  712. bool has_non_mmap_region = false;
  713. mmu().for_regions_in({ 0x23, address }, size, [&](Region* region) {
  714. if (region) {
  715. if (!is<MmapRegion>(*region)) {
  716. has_non_mmap_region = true;
  717. return IterationDecision::Break;
  718. }
  719. marked_for_deletion.append(region);
  720. }
  721. return IterationDecision::Continue;
  722. });
  723. if (has_non_mmap_region)
  724. return -EINVAL;
  725. for (Region* region : marked_for_deletion) {
  726. m_range_allocator.deallocate(region->range());
  727. mmu().remove_region(*region);
  728. }
  729. return 0;
  730. }
  731. u32 Emulator::virt$mmap(u32 params_addr)
  732. {
  733. Syscall::SC_mmap_params params;
  734. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  735. u32 requested_size = round_up_to_power_of_two(params.size, PAGE_SIZE);
  736. FlatPtr final_address;
  737. Optional<Range> result;
  738. if (params.flags & MAP_RANDOMIZED) {
  739. result = m_range_allocator.allocate_randomized(requested_size, params.alignment);
  740. } else if (params.flags & MAP_FIXED) {
  741. if (params.addr)
  742. result = m_range_allocator.allocate_specific(VirtualAddress { params.addr }, requested_size);
  743. else {
  744. // mmap(nullptr, …, MAP_FIXED) is technically okay, but tends to be a bug.
  745. // Therefore, refuse to be helpful.
  746. reportln("\n=={}== \033[31;1mTried to mmap at nullptr with MAP_FIXED.\033[0m, 0x{:x} bytes.", getpid(), params.size);
  747. dump_backtrace();
  748. }
  749. } else {
  750. result = m_range_allocator.allocate_anywhere(requested_size, params.alignment);
  751. }
  752. if (!result.has_value())
  753. return -ENOMEM;
  754. final_address = result.value().base().get();
  755. auto final_size = result.value().size();
  756. String name_str;
  757. if (params.name.characters) {
  758. auto name = ByteBuffer::create_uninitialized(params.name.length);
  759. mmu().copy_from_vm(name.data(), (FlatPtr)params.name.characters, params.name.length);
  760. name_str = { name.data(), name.size() };
  761. }
  762. if (params.flags & MAP_ANONYMOUS) {
  763. mmu().add_region(MmapRegion::create_anonymous(final_address, final_size, params.prot, move(name_str)));
  764. } else {
  765. auto region = MmapRegion::create_file_backed(final_address, final_size, params.prot, params.flags, params.fd, params.offset, move(name_str));
  766. if (region->name() == "libc.so: .text" && !m_libc_start) {
  767. m_libc_start = final_address;
  768. m_libc_end = final_address + final_size;
  769. bool rc = find_malloc_symbols(*region);
  770. VERIFY(rc);
  771. } else if (region->name() == "libsystem.so: .text" && !m_libsystem_start) {
  772. m_libsystem_start = final_address;
  773. m_libsystem_end = final_address + final_size;
  774. }
  775. mmu().add_region(move(region));
  776. }
  777. return final_address;
  778. }
  779. FlatPtr Emulator::virt$mremap(FlatPtr params_addr)
  780. {
  781. Syscall::SC_mremap_params params;
  782. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  783. // FIXME: Support regions that have been split in the past (e.g. due to mprotect or munmap).
  784. if (auto* region = mmu().find_region({ m_cpu.ds(), params.old_address })) {
  785. if (!is<MmapRegion>(*region))
  786. return -EINVAL;
  787. VERIFY(region->size() == params.old_size);
  788. auto& mmap_region = *(MmapRegion*)region;
  789. auto* ptr = mremap(mmap_region.data(), mmap_region.size(), mmap_region.size(), params.flags);
  790. if (ptr == MAP_FAILED)
  791. return -errno;
  792. return (FlatPtr)ptr;
  793. }
  794. return -EINVAL;
  795. }
  796. u32 Emulator::virt$mount(u32 params_addr)
  797. {
  798. Syscall::SC_mount_params params;
  799. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  800. auto target = mmu().copy_buffer_from_vm((FlatPtr)params.target.characters, params.target.length);
  801. auto fs_path = mmu().copy_buffer_from_vm((FlatPtr)params.fs_type.characters, params.fs_type.length);
  802. params.fs_type.characters = (char*)fs_path.data();
  803. params.fs_type.length = fs_path.size();
  804. params.target.characters = (char*)target.data();
  805. params.target.length = target.size();
  806. return syscall(SC_mount, &params);
  807. }
  808. u32 Emulator::virt$gettid()
  809. {
  810. return gettid();
  811. }
  812. u32 Emulator::virt$getpid()
  813. {
  814. return getpid();
  815. }
  816. u32 Emulator::virt$pledge(u32)
  817. {
  818. return 0;
  819. }
  820. u32 Emulator::virt$unveil(u32)
  821. {
  822. return 0;
  823. }
  824. u32 Emulator::virt$mprotect(FlatPtr base, size_t size, int prot)
  825. {
  826. round_to_page_size(base, size);
  827. bool has_non_mmapped_region = false;
  828. mmu().for_regions_in({ 0x23, base }, size, [&](Region* region) {
  829. if (region) {
  830. if (!is<MmapRegion>(*region)) {
  831. has_non_mmapped_region = true;
  832. return IterationDecision::Break;
  833. }
  834. auto& mmap_region = *(MmapRegion*)region;
  835. mmap_region.set_prot(prot);
  836. }
  837. return IterationDecision::Continue;
  838. });
  839. if (has_non_mmapped_region)
  840. return -EINVAL;
  841. return 0;
  842. }
  843. u32 Emulator::virt$madvise(FlatPtr, size_t, int)
  844. {
  845. return 0;
  846. }
  847. uid_t Emulator::virt$getuid()
  848. {
  849. return getuid();
  850. }
  851. uid_t Emulator::virt$geteuid()
  852. {
  853. return geteuid();
  854. }
  855. gid_t Emulator::virt$getgid()
  856. {
  857. return getgid();
  858. }
  859. gid_t Emulator::virt$getegid()
  860. {
  861. return getegid();
  862. }
  863. int Emulator::virt$setuid(uid_t uid)
  864. {
  865. return syscall(SC_setuid, uid);
  866. }
  867. int Emulator::virt$setgid(gid_t gid)
  868. {
  869. return syscall(SC_setgid, gid);
  870. }
  871. u32 Emulator::virt$write(int fd, FlatPtr data, ssize_t size)
  872. {
  873. if (size < 0)
  874. return -EINVAL;
  875. auto buffer = mmu().copy_buffer_from_vm(data, size);
  876. return syscall(SC_write, fd, buffer.data(), buffer.size());
  877. }
  878. u32 Emulator::virt$read(int fd, FlatPtr buffer, ssize_t size)
  879. {
  880. if (size < 0)
  881. return -EINVAL;
  882. auto local_buffer = ByteBuffer::create_uninitialized(size);
  883. int nread = syscall(SC_read, fd, local_buffer.data(), local_buffer.size());
  884. if (nread < 0) {
  885. if (nread == -EPERM) {
  886. dump_backtrace();
  887. TODO();
  888. }
  889. return nread;
  890. }
  891. mmu().copy_to_vm(buffer, local_buffer.data(), local_buffer.size());
  892. return nread;
  893. }
  894. void Emulator::virt$sync()
  895. {
  896. syscall(SC_sync);
  897. }
  898. void Emulator::virt$exit(int status)
  899. {
  900. reportln("\n=={}== \033[33;1mSyscall: exit({})\033[0m, shutting down!", getpid(), status);
  901. m_exit_status = status;
  902. m_shutdown = true;
  903. }
  904. ssize_t Emulator::virt$getrandom(FlatPtr buffer, size_t buffer_size, unsigned int flags)
  905. {
  906. auto host_buffer = ByteBuffer::create_uninitialized(buffer_size);
  907. int rc = syscall(SC_getrandom, host_buffer.data(), host_buffer.size(), flags);
  908. if (rc < 0)
  909. return rc;
  910. mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
  911. return rc;
  912. }
  913. int Emulator::virt$get_dir_entries(int fd, FlatPtr buffer, ssize_t size)
  914. {
  915. auto host_buffer = ByteBuffer::create_uninitialized(size);
  916. int rc = syscall(SC_get_dir_entries, fd, host_buffer.data(), host_buffer.size());
  917. if (rc < 0)
  918. return rc;
  919. mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
  920. return rc;
  921. }
  922. int Emulator::virt$ioctl([[maybe_unused]] int fd, unsigned request, [[maybe_unused]] FlatPtr arg)
  923. {
  924. if (request == TIOCGWINSZ) {
  925. struct winsize ws;
  926. int rc = syscall(SC_ioctl, fd, TIOCGWINSZ, &ws);
  927. if (rc < 0)
  928. return rc;
  929. mmu().copy_to_vm(arg, &ws, sizeof(winsize));
  930. return 0;
  931. }
  932. if (request == TIOCSPGRP) {
  933. return syscall(SC_ioctl, fd, request, arg);
  934. }
  935. if (request == TCGETS) {
  936. struct termios termios;
  937. int rc = syscall(SC_ioctl, fd, request, &termios);
  938. if (rc < 0)
  939. return rc;
  940. mmu().copy_to_vm(arg, &termios, sizeof(termios));
  941. return rc;
  942. }
  943. if (request == TCSETS) {
  944. struct termios termios;
  945. mmu().copy_from_vm(&termios, arg, sizeof(termios));
  946. return syscall(SC_ioctl, fd, request, &termios);
  947. }
  948. if (request == TIOCNOTTY || request == TIOCSCTTY) {
  949. return syscall(SC_ioctl, fd, request, 0);
  950. }
  951. if (request == FB_IOCTL_GET_SIZE_IN_BYTES) {
  952. size_t size = 0;
  953. auto rc = syscall(SC_ioctl, fd, request, &size);
  954. mmu().copy_to_vm(arg, &size, sizeof(size));
  955. return rc;
  956. }
  957. if (request == FB_IOCTL_SET_RESOLUTION) {
  958. FBResolution user_resolution;
  959. mmu().copy_from_vm(&user_resolution, arg, sizeof(user_resolution));
  960. auto rc = syscall(SC_ioctl, fd, request, &user_resolution);
  961. mmu().copy_to_vm(arg, &user_resolution, sizeof(user_resolution));
  962. return rc;
  963. }
  964. if (request == FB_IOCTL_SET_BUFFER) {
  965. return syscall(SC_ioctl, fd, request, arg);
  966. }
  967. reportln("Unsupported ioctl: {}", request);
  968. dump_backtrace();
  969. TODO();
  970. }
  971. int Emulator::virt$emuctl(FlatPtr arg1, FlatPtr arg2, FlatPtr arg3)
  972. {
  973. auto* tracer = malloc_tracer();
  974. if (!tracer)
  975. return 0;
  976. switch (arg1) {
  977. case 1:
  978. tracer->target_did_malloc({}, arg3, arg2);
  979. return 0;
  980. case 2:
  981. tracer->target_did_free({}, arg2);
  982. return 0;
  983. case 3:
  984. tracer->target_did_realloc({}, arg3, arg2);
  985. return 0;
  986. default:
  987. return -EINVAL;
  988. }
  989. }
  990. int Emulator::virt$fork()
  991. {
  992. int rc = fork();
  993. if (rc < 0)
  994. return -errno;
  995. return rc;
  996. }
  997. int Emulator::virt$execve(FlatPtr params_addr)
  998. {
  999. Syscall::SC_execve_params params;
  1000. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  1001. auto path = String::copy(mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length));
  1002. Vector<String> arguments;
  1003. Vector<String> environment;
  1004. auto copy_string_list = [this](auto& output_vector, auto& string_list) {
  1005. for (size_t i = 0; i < string_list.length; ++i) {
  1006. Syscall::StringArgument string;
  1007. mmu().copy_from_vm(&string, (FlatPtr)&string_list.strings[i], sizeof(string));
  1008. output_vector.append(String::copy(mmu().copy_buffer_from_vm((FlatPtr)string.characters, string.length)));
  1009. }
  1010. };
  1011. copy_string_list(arguments, params.arguments);
  1012. copy_string_list(environment, params.environment);
  1013. reportln("\n=={}== \033[33;1mSyscall:\033[0m execve", getpid());
  1014. reportln("=={}== @ {}", getpid(), path);
  1015. for (auto& argument : arguments)
  1016. reportln("=={}== - {}", getpid(), argument);
  1017. Vector<char*> argv;
  1018. Vector<char*> envp;
  1019. argv.append(const_cast<char*>("/bin/UserspaceEmulator"));
  1020. argv.append(const_cast<char*>(path.characters()));
  1021. if (g_report_to_debug)
  1022. argv.append(const_cast<char*>("--report-to-debug"));
  1023. argv.append(const_cast<char*>("--"));
  1024. auto create_string_vector = [](auto& output_vector, auto& input_vector) {
  1025. for (auto& string : input_vector)
  1026. output_vector.append(const_cast<char*>(string.characters()));
  1027. output_vector.append(nullptr);
  1028. };
  1029. create_string_vector(argv, arguments);
  1030. create_string_vector(envp, environment);
  1031. // Yoink duplicated program name.
  1032. argv.remove(3 + (g_report_to_debug ? 1 : 0));
  1033. return execve(argv[0], (char* const*)argv.data(), (char* const*)envp.data());
  1034. }
  1035. int Emulator::virt$stat(FlatPtr params_addr)
  1036. {
  1037. Syscall::SC_stat_params params;
  1038. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  1039. auto path = String::copy(mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length));
  1040. struct stat host_statbuf;
  1041. int rc;
  1042. if (params.follow_symlinks)
  1043. rc = stat(path.characters(), &host_statbuf);
  1044. else
  1045. rc = lstat(path.characters(), &host_statbuf);
  1046. if (rc < 0)
  1047. return -errno;
  1048. mmu().copy_to_vm((FlatPtr)params.statbuf, &host_statbuf, sizeof(host_statbuf));
  1049. return rc;
  1050. }
  1051. int Emulator::virt$realpath(FlatPtr params_addr)
  1052. {
  1053. Syscall::SC_realpath_params params;
  1054. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  1055. auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
  1056. auto host_buffer = ByteBuffer::create_zeroed(params.buffer.size);
  1057. Syscall::SC_realpath_params host_params;
  1058. host_params.path = { (const char*)path.data(), path.size() };
  1059. host_params.buffer = { (char*)host_buffer.data(), host_buffer.size() };
  1060. int rc = syscall(SC_realpath, &host_params);
  1061. if (rc < 0)
  1062. return rc;
  1063. mmu().copy_to_vm((FlatPtr)params.buffer.data, host_buffer.data(), host_buffer.size());
  1064. return rc;
  1065. }
  1066. int Emulator::virt$gethostname(FlatPtr buffer, ssize_t buffer_size)
  1067. {
  1068. if (buffer_size < 0)
  1069. return -EINVAL;
  1070. auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
  1071. int rc = syscall(SC_gethostname, host_buffer.data(), host_buffer.size());
  1072. if (rc < 0)
  1073. return rc;
  1074. mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
  1075. return rc;
  1076. }
  1077. int Emulator::virt$sigaction(int signum, FlatPtr act, FlatPtr oldact)
  1078. {
  1079. if (signum == SIGKILL) {
  1080. reportln("Attempted to sigaction() with SIGKILL");
  1081. return -EINVAL;
  1082. }
  1083. if (signum <= 0 || signum >= NSIG)
  1084. return -EINVAL;
  1085. struct sigaction host_act;
  1086. mmu().copy_from_vm(&host_act, act, sizeof(host_act));
  1087. auto& handler = m_signal_handler[signum];
  1088. handler.handler = (FlatPtr)host_act.sa_handler;
  1089. handler.mask = host_act.sa_mask;
  1090. handler.flags = host_act.sa_flags;
  1091. if (oldact) {
  1092. struct sigaction host_oldact;
  1093. auto& old_handler = m_signal_handler[signum];
  1094. host_oldact.sa_handler = (void (*)(int))(old_handler.handler);
  1095. host_oldact.sa_mask = old_handler.mask;
  1096. host_oldact.sa_flags = old_handler.flags;
  1097. mmu().copy_to_vm(oldact, &host_oldact, sizeof(host_oldact));
  1098. }
  1099. return 0;
  1100. }
  1101. int Emulator::virt$sigreturn()
  1102. {
  1103. u32 stack_ptr = m_cpu.esp().value();
  1104. auto local_pop = [&]() -> ValueWithShadow<u32> {
  1105. auto value = m_cpu.read_memory32({ m_cpu.ss(), stack_ptr });
  1106. stack_ptr += sizeof(u32);
  1107. return value;
  1108. };
  1109. auto smuggled_eax = local_pop();
  1110. stack_ptr += 4 * sizeof(u32);
  1111. m_signal_mask = local_pop().value();
  1112. m_cpu.set_edi(local_pop());
  1113. m_cpu.set_esi(local_pop());
  1114. m_cpu.set_ebp(local_pop());
  1115. m_cpu.set_esp(local_pop());
  1116. m_cpu.set_ebx(local_pop());
  1117. m_cpu.set_edx(local_pop());
  1118. m_cpu.set_ecx(local_pop());
  1119. m_cpu.set_eax(local_pop());
  1120. m_cpu.set_eip(local_pop().value());
  1121. m_cpu.set_eflags(local_pop());
  1122. // FIXME: We're losing shadow bits here.
  1123. return smuggled_eax.value();
  1124. }
  1125. int Emulator::virt$getpgrp()
  1126. {
  1127. return syscall(SC_getpgrp);
  1128. }
  1129. int Emulator::virt$getpgid(pid_t pid)
  1130. {
  1131. return syscall(SC_getpgid, pid);
  1132. }
  1133. int Emulator::virt$setpgid(pid_t pid, pid_t pgid)
  1134. {
  1135. return syscall(SC_setpgid, pid, pgid);
  1136. }
  1137. int Emulator::virt$ttyname(int fd, FlatPtr buffer, size_t buffer_size)
  1138. {
  1139. auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
  1140. int rc = syscall(SC_ttyname, fd, host_buffer.data(), host_buffer.size());
  1141. if (rc < 0)
  1142. return rc;
  1143. mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
  1144. return rc;
  1145. }
  1146. int Emulator::virt$getcwd(FlatPtr buffer, size_t buffer_size)
  1147. {
  1148. auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
  1149. int rc = syscall(SC_getcwd, host_buffer.data(), host_buffer.size());
  1150. if (rc < 0)
  1151. return rc;
  1152. mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
  1153. return rc;
  1154. }
  1155. int Emulator::virt$getsid(pid_t pid)
  1156. {
  1157. return syscall(SC_getsid, pid);
  1158. }
  1159. int Emulator::virt$access(FlatPtr path, size_t path_length, int type)
  1160. {
  1161. auto host_path = mmu().copy_buffer_from_vm(path, path_length);
  1162. return syscall(SC_access, host_path.data(), host_path.size(), type);
  1163. }
  1164. int Emulator::virt$waitid(FlatPtr params_addr)
  1165. {
  1166. Syscall::SC_waitid_params params;
  1167. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  1168. Syscall::SC_waitid_params host_params = params;
  1169. siginfo info {};
  1170. host_params.infop = &info;
  1171. int rc = syscall(SC_waitid, &host_params);
  1172. if (rc < 0)
  1173. return rc;
  1174. if (info.si_addr) {
  1175. // FIXME: Translate this somehow once we actually start setting it in the kernel.
  1176. dbgln("si_addr is set to {:p}, I did not expect this!", info.si_addr);
  1177. TODO();
  1178. }
  1179. if (params.infop)
  1180. mmu().copy_to_vm((FlatPtr)params.infop, &info, sizeof(info));
  1181. return rc;
  1182. }
  1183. int Emulator::virt$chdir(FlatPtr path, size_t path_length)
  1184. {
  1185. auto host_path = mmu().copy_buffer_from_vm(path, path_length);
  1186. return syscall(SC_chdir, host_path.data(), host_path.size());
  1187. }
  1188. int Emulator::virt$dup2(int old_fd, int new_fd)
  1189. {
  1190. return syscall(SC_dup2, old_fd, new_fd);
  1191. }
  1192. int Emulator::virt$sched_getparam(pid_t pid, FlatPtr user_addr)
  1193. {
  1194. sched_param user_param;
  1195. mmu().copy_from_vm(&user_param, user_addr, sizeof(user_param));
  1196. auto rc = syscall(SC_sched_getparam, pid, &user_param);
  1197. mmu().copy_to_vm(user_addr, &user_param, sizeof(user_param));
  1198. return rc;
  1199. }
  1200. int Emulator::virt$sched_setparam(int pid, FlatPtr user_addr)
  1201. {
  1202. sched_param user_param;
  1203. mmu().copy_from_vm(&user_param, user_addr, sizeof(user_param));
  1204. return syscall(SC_sched_setparam, pid, &user_param);
  1205. }
  1206. int Emulator::virt$set_thread_name(pid_t pid, FlatPtr name_addr, size_t name_length)
  1207. {
  1208. auto user_name = mmu().copy_buffer_from_vm(name_addr, name_length);
  1209. auto name = String::formatted("(UE) {}", StringView { user_name.data(), user_name.size() });
  1210. return syscall(SC_set_thread_name, pid, name.characters(), name.length());
  1211. }
  1212. pid_t Emulator::virt$setsid()
  1213. {
  1214. return syscall(SC_setsid);
  1215. }
  1216. int Emulator::virt$create_inode_watcher(unsigned flags)
  1217. {
  1218. return syscall(SC_create_inode_watcher, flags);
  1219. }
  1220. int Emulator::virt$inode_watcher_add_watch(FlatPtr params_addr)
  1221. {
  1222. Syscall::SC_inode_watcher_add_watch_params params;
  1223. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  1224. return syscall(SC_inode_watcher_add_watch, &params);
  1225. }
  1226. int Emulator::virt$inode_watcher_remove_watch(int fd, int wd)
  1227. {
  1228. return syscall(SC_inode_watcher_add_watch, fd, wd);
  1229. }
  1230. int Emulator::virt$clock_nanosleep(FlatPtr params_addr)
  1231. {
  1232. Syscall::SC_clock_nanosleep_params params;
  1233. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  1234. timespec requested_sleep;
  1235. mmu().copy_from_vm(&requested_sleep, (FlatPtr)params.requested_sleep, sizeof(timespec));
  1236. params.requested_sleep = &requested_sleep;
  1237. auto remaining_vm_addr = params.remaining_sleep;
  1238. auto remaining = ByteBuffer::create_zeroed(sizeof(timespec));
  1239. params.remaining_sleep = (timespec*)remaining.data();
  1240. int rc = syscall(SC_clock_nanosleep, &params);
  1241. if (remaining_vm_addr)
  1242. mmu().copy_to_vm((FlatPtr)remaining_vm_addr, remaining.data(), sizeof(timespec));
  1243. return rc;
  1244. }
  1245. int Emulator::virt$readlink(FlatPtr params_addr)
  1246. {
  1247. Syscall::SC_readlink_params params;
  1248. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  1249. auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
  1250. auto host_buffer = ByteBuffer::create_zeroed(params.buffer.size);
  1251. Syscall::SC_readlink_params host_params;
  1252. host_params.path = { (const char*)path.data(), path.size() };
  1253. host_params.buffer = { (char*)host_buffer.data(), host_buffer.size() };
  1254. int rc = syscall(SC_readlink, &host_params);
  1255. if (rc < 0)
  1256. return rc;
  1257. mmu().copy_to_vm((FlatPtr)params.buffer.data, host_buffer.data(), host_buffer.size());
  1258. return rc;
  1259. }
  1260. u32 Emulator::virt$allocate_tls(FlatPtr initial_data, size_t size)
  1261. {
  1262. // TODO: This matches what Thread::make_thread_specific_region does. The kernel
  1263. // ends up allocating one more page. Figure out if this is intentional.
  1264. auto region_size = align_up_to(size, PAGE_SIZE) + PAGE_SIZE;
  1265. auto tcb_region = make<SimpleRegion>(0x20000000, region_size);
  1266. size_t offset = 0;
  1267. while (size - offset > 0) {
  1268. u8 buffer[512];
  1269. size_t read_bytes = min(sizeof(buffer), size - offset);
  1270. mmu().copy_from_vm(buffer, initial_data + offset, read_bytes);
  1271. memcpy(tcb_region->data() + offset, buffer, read_bytes);
  1272. offset += read_bytes;
  1273. }
  1274. memset(tcb_region->shadow_data(), 0x01, size);
  1275. auto tls_region = make<SimpleRegion>(0, 4);
  1276. tls_region->write32(0, shadow_wrap_as_initialized(tcb_region->base() + (u32)size));
  1277. memset(tls_region->shadow_data(), 0x01, 4);
  1278. u32 tls_base = tcb_region->base();
  1279. mmu().add_region(move(tcb_region));
  1280. mmu().set_tls_region(move(tls_region));
  1281. return tls_base;
  1282. }
  1283. int Emulator::virt$ptsname(int fd, FlatPtr buffer, size_t buffer_size)
  1284. {
  1285. auto pts = mmu().copy_buffer_from_vm(buffer, buffer_size);
  1286. return syscall(SC_ptsname, fd, pts.data(), pts.size());
  1287. }
  1288. int Emulator::virt$beep()
  1289. {
  1290. return syscall(SC_beep);
  1291. }
  1292. int Emulator::virt$msyscall(FlatPtr)
  1293. {
  1294. // FIXME: Implement this.
  1295. return 0;
  1296. }
  1297. int Emulator::virt$futex(FlatPtr params_addr)
  1298. {
  1299. Syscall::SC_futex_params params;
  1300. mmu().copy_from_vm(&params, params_addr, sizeof(params));
  1301. // FIXME: Implement this.
  1302. return 0;
  1303. }
  1304. }