Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 #include <sos/thread.h> 018 #include <sos/thread.h>
019 #include <sos/kmalloc.h> 019 #include <sos/kmalloc.h>
020 #include <sos/klibc.h> 020 #include <sos/klibc.h>
021 #include <drivers/bochs.h> 021 #include <drivers/bochs.h>
022 #include <hwcore/paging.h> <<
023 #include <sos/physmem.h> <<
024 #include <sos/umem_vmm.h> <<
025 #include <drivers/zero.h> <<
026 #include <drivers/mem.h> <<
027 #include <sos/binfmt_elf32.h> <<
028 022
029 #include <hwcore/cpu_context.h> 023 #include <hwcore/cpu_context.h>
030 #include <sos/uaccess.h> 024 #include <sos/uaccess.h>
031 #include "syscall.h" 025 #include "syscall.h"
032 026
033 027
034 028
035 029
036 030
037 sos_ret_t sos_do_syscall(int syscall_id, 031 sos_ret_t sos_do_syscall(int syscall_id,
038 const struct sos_cpu_ 032 const struct sos_cpu_state *user_ctxt)
039 { 033 {
040 sos_ret_t retval; 034 sos_ret_t retval;
041 035
042 switch(syscall_id) 036 switch(syscall_id)
043 { 037 {
044 case SOS_SYSCALL_ID_EXIT: 038 case SOS_SYSCALL_ID_EXIT:
045 { 039 {
046 unsigned int status; 040 unsigned int status;
047 <<
048 retval = sos_syscall_get1arg(user_ctxt 041 retval = sos_syscall_get1arg(user_ctxt, & status);
049 if (SOS_OK != retval) 042 if (SOS_OK != retval)
050 break; 043 break;
051 sos_thread_exit(); 044 sos_thread_exit();
052 retval = -SOS_EFATAL; 045 retval = -SOS_EFATAL;
053 } 046 }
054 break; 047 break;
055 <<
056 case SOS_SYSCALL_ID_FORK: <<
057 { <<
058 struct sos_thread *cur_thr, *new_thr; <<
059 struct sos_process *new_proc; <<
060 <<
061 cur_thr = sos_thread_get_current(); <<
062 <<
063 <<
064 new_proc = sos_process_create(NULL, TR <<
065 if (! new_proc) <<
066 { <<
067 retval = -SOS_ENOMEM; <<
068 break; <<
069 } <<
070 <<
071 <<
072 <<
073 <<
074 new_thr = <<
075 sos_duplicate_user_thread(NULL, new_ <<
076 cur_thr, <<
077 user_ctxt, <<
078 0); <<
079 if (! new_thr) <<
080 { <<
081 sos_process_unref(new_proc); <<
082 retval = -SOS_ENOMEM; <<
083 break; <<
084 } <<
085 <<
086 sos_process_unref(new_proc); <<
087 <<
088 <<
089 <<
090 <<
091 retval = (sos_ui32_t)new_proc; <<
092 } <<
093 break; <<
094 <<
095 case SOS_SYSCALL_ID_EXEC: <<
096 { <<
097 struct sos_thread *cur_thr, *new_thr; <<
098 struct sos_process * proc; <<
099 struct sos_umem_vmm_as *new_as; <<
100 sos_uaddr_t user_str, ustack, start_ua <<
101 sos_size_t len; <<
102 char * str; <<
103 <<
104 cur_thr = sos_thread_get_current(); <<
105 proc = cur_thr->process; <<
106 <<
107 <<
108 if (sos_process_get_nb_threads(proc) ! <<
109 { <<
110 retval = -SOS_EBUSY; <<
111 break; <<
112 } <<
113 <<
114 <<
115 retval = sos_syscall_get2args(user_ctx <<
116 if (SOS_OK != retval) <<
117 break; <<
118 <<
119 <<
120 retval = sos_strndup_from_user(& str, <<
121 if (SOS_OK != retval) <<
122 { <<
123 break; <<
124 } <<
125 <<
126 <<
127 new_as = sos_umem_vmm_create_empty_as( <<
128 if (! new_as) <<
129 { <<
130 sos_kfree((sos_vaddr_t)str); <<
131 retval = -SOS_ENOMEM; <<
132 break; <<
133 } <<
134 <<
135 <<
136 start_uaddr = sos_binfmt_elf32_map(new <<
137 if (start_uaddr == (sos_uaddr_t)NULL) <<
138 { <<
139 sos_umem_vmm_delete_as(new_as); <<
140 sos_kfree((sos_vaddr_t)str); <<
141 retval = -SOS_ENOENT; <<
142 break; <<
143 } <<
144 <<
145 <<
146 #define SOS_DEFAULT_USER_STACK_SIZE (8 << 20) <<
147 ustack = (SOS_PAGING_TOP_USER_ADDRESS <<
148 + 1; <<
149 retval = sos_dev_zero_map(new_as, &ust <<
150 SOS_VM_MAP_P <<
151 <<
152 if (SOS_OK != retval) <<
153 { <<
154 sos_umem_vmm_delete_as(new_as); <<
155 sos_kfree((sos_vaddr_t)str); <<
156 break; <<
157 } <<
158 <<
159 <<
160 new_thr = sos_create_user_thread(NULL, <<
161 proc, <<
162 start <<
163 0, 0, <<
164 ustac <<
165 - 4 <<
166 SOS_S <<
167 if (! new_thr) <<
168 { <<
169 sos_umem_vmm_delete_as(new_as); <<
170 sos_kfree((sos_vaddr_t)str); <<
171 retval = -SOS_ENOMEM; <<
172 break; <<
173 } <<
174 <<
175 sos_process_set_name(proc, str); <<
176 <<
177 <<
178 retval = sos_process_set_address_space <<
179 <<
180 if (SOS_OK != retval) <<
181 { <<
182 sos_umem_vmm_delete_as(new_as); <<
183 sos_kfree((sos_vaddr_t)str); <<
184 break; <<
185 } <<
186 <<
187 <<
188 sos_kfree((sos_vaddr_t)str); <<
189 sos_thread_exit(); <<
190 retval = -SOS_EFATAL; <<
191 } <<
192 break; <<
193 <<
194 case SOS_SYSCALL_ID_FAKEMMAP: <<
195 { <<
196 sos_uaddr_t ptr_hint_uaddr; <<
197 sos_uaddr_t hint_uaddr; <<
198 sos_size_t length; <<
199 sos_ui32_t prot; <<
200 sos_ui32_t flags; <<
201 sos_uaddr_t name_user; <<
202 sos_ui32_t offs64_hi; <<
203 sos_ui32_t offs64_lo; <<
204 sos_luoffset_t offset_in_resource; <<
205 char name[256]; <<
206 struct sos_umem_vmm_as * my_as; <<
207 <<
208 retval = sos_syscall_get7args(user_ctx <<
209 (unsigne <<
210 (unsigne <<
211 (unsigne <<
212 (unsigne <<
213 (unsigne <<
214 (unsigne <<
215 (unsigne <<
216 if (SOS_OK != retval) <<
217 break; <<
218 <<
219 <<
220 offset_in_resource = offs64_hi; <<
221 offset_in_resource <<= 32; <<
222 offset_in_resource |= offs64_lo; <<
223 <<
224 retval = sos_memcpy_from_user((sos_vad <<
225 ptr_hint <<
226 sizeof(h <<
227 if (sizeof(hint_uaddr) != retval) <<
228 { <<
229 retval = -SOS_EFAULT; <<
230 break; <<
231 } <<
232 <<
233 retval = sos_strzcpy_from_user(name, n <<
234 if (SOS_OK != retval) <<
235 break; <<
236 <<
237 my_as <<
238 = sos_process_get_address_space(sos_ <<
239 if ( (0 == strncmp(name, "/dev/zero", <<
240 || (0 == strncmp(name, "/dev/null <<
241 retval = sos_dev_zero_map(my_as, & h <<
242 else if (0 == strncmp(name, "/dev/mem" <<
243 retval = sos_dev_physmem_map(my_as, <<
244 offset_ <<
245 else if (0 == strncmp(name, "/dev/kmem <<
246 retval = sos_dev_kmem_map(my_as, & h <<
247 offset_in_ <<
248 else <<
249 retval = -SOS_ENOENT; <<
250 <<
251 if (SOS_OK == retval) <<
252 { <<
253 if (sizeof(hint_uaddr) <<
254 != sos_memcpy_to_user(ptr_hint <<
255 (sos_vad <<
256 sizeof(h <<
257 { <<
258 sos_umem_vmm_unmap(my_as, hint <<
259 retval = -SOS_EFAULT; <<
260 } <<
261 } <<
262 <<
263 } <<
264 break; <<
265 <<
266 case SOS_SYSCALL_ID_MUNMAP: <<
267 { <<
268 sos_uaddr_t start_uaddr; <<
269 sos_size_t size; <<
270 struct sos_umem_vmm_as * my_as; <<
271 <<
272 my_as <<
273 = sos_process_get_address_space(sos_ <<
274 <<
275 retval = sos_syscall_get2args(user_ctx <<
276 (unsigne <<
277 (unsigne <<
278 if (SOS_OK != retval) <<
279 break; <<
280 <<
281 retval = sos_umem_vmm_unmap(my_as, sta <<
282 } <<
283 break; <<
284 <<
285 case SOS_SYSCALL_ID_MPROTECT: <<
286 { <<
287 sos_uaddr_t start_uaddr; <<
288 sos_size_t size; <<
289 sos_ui32_t new_access_rights; <<
290 struct sos_umem_vmm_as * my_as; <<
291 <<
292 my_as <<
293 = sos_process_get_address_space(sos_ <<
294 <<
295 retval = sos_syscall_get3args(user_ctx <<
296 (unsigne <<
297 (unsigne <<
298 (unsigne <<
299 if (SOS_OK != retval) <<
300 break; <<
301 <<
302 retval = sos_thread_prepare_user_space <<
303 if (SOS_OK != retval) <<
304 break; <<
305 <<
306 retval = sos_umem_vmm_chprot(my_as, st <<
307 new_acces <<
308 <<
309 sos_thread_end_user_space_access(); <<
310 } <<
311 break; <<
312 <<
313 case SOS_SYSCALL_ID_MRESIZE: <<
314 { <<
315 sos_uaddr_t old_uaddr; <<
316 sos_size_t old_size; <<
317 sos_uaddr_t *uptr_new_uaddr; <<
318 sos_uaddr_t new_uaddr; <<
319 sos_size_t new_size; <<
320 sos_ui32_t flags; <<
321 struct sos_umem_vmm_as * my_as; <<
322 <<
323 my_as <<
324 = sos_process_get_address_space(sos_ <<
325 <<
326 retval = sos_syscall_get5args(user_ctx <<
327 (unsigne <<
328 (unsigne <<
329 (unsigne <<
330 (unsigne <<
331 (unsigne <<
332 if (SOS_OK != retval) <<
333 break; <<
334 <<
335 if (sizeof(new_uaddr) != sos_memcpy_fr <<
336 <<
337 <<
338 <<
339 { <<
340 retval = -SOS_EFAULT; <<
341 break; <<
342 } <<
343 <<
344 retval = sos_thread_prepare_user_space <<
345 if (SOS_OK != retval) <<
346 break; <<
347 <<
348 retval = sos_umem_vmm_resize(my_as, ol <<
349 & new_uad <<
350 sos_thread_end_user_space_access(); <<
351 if (SOS_OK != retval) <<
352 break; <<
353 <<
354 if (sizeof(new_uaddr) <<
355 == sos_memcpy_to_user((sos_uaddr_t <<
356 (sos_vaddr_t <<
357 sizeof(new_u <<
358 { <<
359 retval = -SOS_EFAULT; <<
360 break; <<
361 } <<
362 } <<
363 break; <<
364 <<
365 case SOS_SYSCALL_ID_NEW_THREAD: <<
366 { <<
367 sos_uaddr_t start_func; <<
368 sos_ui32_t start_arg1, start_arg2; <<
369 sos_size_t stack_size; <<
370 sos_uaddr_t stack_uaddr; <<
371 <<
372 struct sos_thread * new_thr; <<
373 struct sos_umem_vmm_as * my_as; <<
374 <<
375 my_as <<
376 = sos_process_get_address_space(sos_ <<
377 <<
378 retval = sos_syscall_get4args(user_ctx <<
379 (unsigne <<
380 (unsigne <<
381 (unsigne <<
382 (unsigne <<
383 if (SOS_OK != retval) <<
384 break; <<
385 <<
386 if (stack_size <= 0) <<
387 { <<
388 retval = -SOS_EINVAL; <<
389 break; <<
390 } <<
391 <<
392 <<
393 stack_uaddr = 0; <<
394 stack_size = SOS_PAGE_ALIGN_SUP(stack_ <<
395 retval = sos_dev_zero_map(my_as, & sta <<
396 SOS_VM_MAP_P <<
397 <<
398 if (SOS_OK != retval) <<
399 break; <<
400 <<
401 <<
402 new_thr = sos_create_user_thread(NULL, <<
403 sos_t <<
404 start <<
405 start <<
406 start <<
407 stack <<
408 SOS_S <<
409 <<
410 if (! new_thr) <<
411 { <<
412 sos_umem_vmm_unmap(my_as, stack_ua <<
413 retval = -SOS_ENOMEM; <<
414 break; <<
415 } <<
416 <<
417 } <<
418 break; <<
419 <<
420 case SOS_SYSCALL_ID_NANOSLEEP: <<
421 { <<
422 struct sos_time delay; <<
423 <<
424 retval = sos_syscall_get2args(user_ctx <<
425 (unsigne <<
426 (unsigne <<
427 if (SOS_OK != retval) <<
428 break; <<
429 <<
430 retval = sos_thread_sleep(& delay); <<
431 } <<
432 break; <<
433 <<
434 case SOS_SYSCALL_ID_BRK: <<
435 { <<
436 sos_uaddr_t new_top_heap; <<
437 struct sos_umem_vmm_as * my_as; <<
438 <<
439 my_as <<
440 = sos_process_get_address_space(sos_ <<
441 <<
442 retval = sos_syscall_get1arg(user_ctxt <<
443 (unsigned <<
444 if (SOS_OK != retval) <<
445 break; <<
446 <<
447 retval = sos_thread_prepare_user_space <<
448 if (SOS_OK != retval) <<
449 break; <<
450 <<
451 retval = sos_umem_vmm_brk(my_as, new_t <<
452 sos_thread_end_user_space_access(); <<
453 } <<
454 break; <<
455 <<
456 <<
457 <<
458 <<
459 <<
460 case SOS_SYSCALL_ID_MOUNT: <<
461 { <<
462 sos_uaddr_t user_src; <<
463 sos_size_t srclen; <<
464 const char * kernel_src = NULL; <<
465 sos_uaddr_t user_dst; <<
466 sos_size_t dstlen; <<
467 const char * kernel_dst; <<
468 sos_ui32_t mountflags; <<
469 sos_uaddr_t user_fstype; <<
470 char * kernel_fstype; <<
471 sos_uaddr_t user_args; <<
472 char * kernel_args = NULL; <<
473 struct sos_process * proc; <<
474 <<
475 proc = sos_thread_get_current()->proce <<
476 retval = sos_syscall_get7args(user_ctx <<
477 (unsigne <<
478 (unsigne <<
479 (unsigne <<
480 (unsigne <<
481 (unsigne <<
482 (unsigne <<
483 (unsigne <<
484 if (SOS_OK != retval) <<
485 break; <<
486 <<
487 if (user_src != (sos_uaddr_t)NULL) <<
488 { <<
489 retval = sos_memdup_from_user((sos <<
490 if (SOS_OK != retval) <<
491 break; <<
492 } <<
493 <<
494 retval = sos_memdup_from_user((sos_vad <<
495 if (SOS_OK != retval) <<
496 { <<
497 if (kernel_src) <<
498 sos_kfree((sos_vaddr_t)kernel_sr <<
499 break; <<
500 } <<
501 <<
502 retval = sos_strndup_from_user(& kerne <<
503 if (SOS_OK != retval) <<
504 { <<
505 if (kernel_src) <<
506 sos_kfree((sos_vaddr_t)kernel_sr <<
507 sos_kfree((sos_vaddr_t)kernel_dst) <<
508 break; <<
509 } <<
510 <<
511 if (user_args != (sos_uaddr_t)NULL) <<
512 { <<
513 retval = sos_strndup_from_user(& k <<
514 if (SOS_OK != retval) <<
515 { <<
516 if (kernel_src) <<
517 sos_kfree((sos_vaddr_t)kerne <<
518 sos_kfree((sos_vaddr_t)kernel_ <<
519 sos_kfree((sos_vaddr_t)kernel_ <<
520 break; <<
521 } <<
522 } <<
523 <<
524 retval = sos_fs_mount(proc, kernel_src <<
525 kernel_dst, dstl <<
526 kernel_fstype, <<
527 mountflags, <<
528 kernel_args, <<
529 NULL); <<
530 if (kernel_src) <<
531 sos_kfree((sos_vaddr_t)kernel_src); <<
532 sos_kfree((sos_vaddr_t)kernel_dst); <<
533 sos_kfree((sos_vaddr_t)kernel_fstype); <<
534 if (kernel_args) <<
535 sos_kfree((sos_vaddr_t)kernel_args); <<
536 } <<
537 break; <<
538 <<
539 case SOS_SYSCALL_ID_UMOUNT: <<
540 { <<
541 sos_uaddr_t user_str; <<
542 sos_size_t len; <<
543 char * path; <<
544 struct sos_process * proc; <<
545 <<
546 proc = sos_thread_get_current()->proce <<
547 retval = sos_syscall_get2args(user_ctx <<
548 (unsigne <<
549 (unsigne <<
550 if (SOS_OK != retval) <<
551 break; <<
552 <<
553 retval = sos_memdup_from_user((sos_vad <<
554 if (SOS_OK != retval) <<
555 break; <<
556 <<
557 retval = sos_fs_umount(proc, <<
558 path, len); <<
559 sos_kfree((sos_vaddr_t)path); <<
560 } <<
561 break; <<
562 <<
563 case SOS_SYSCALL_ID_SYNC: <<
564 { <<
565 sos_fs_sync_all_fs(); <<
566 retval = SOS_OK; <<
567 } <<
568 break; <<
569 <<
570 case SOS_SYSCALL_ID_VFSTAT64: <<
571 { <<
572 sos_uaddr_t user_str; <<
573 sos_size_t len; <<
574 sos_uaddr_t user_vfstat_struct; <<
575 struct sos_fs_statfs kernel_vfstat_str <<
576 char * path; <<
577 struct sos_process * proc; <<
578 <<
579 proc = sos_thread_get_current()->proce <<
580 retval = sos_syscall_get3args(user_ctx <<
581 (unsigne <<
582 (unsigne <<
583 (unsigne <<
584 if (SOS_OK != retval) <<
585 break; <<
586 <<
587 retval = sos_memdup_from_user((sos_vad <<
588 if (SOS_OK != retval) <<
589 break; <<
590 <<
591 retval = sos_fs_vfstat(proc, path, len <<
592 sos_kfree((sos_vaddr_t)path); <<
593 if (SOS_OK != retval) <<
594 break; <<
595 <<
596 if (sizeof(kernel_vfstat_struct) <<
597 != sos_memcpy_to_user(user_vfstat_ <<
598 (sos_vaddr_t <<
599 sizeof(kerne <<
600 retval = -SOS_EFAULT; <<
601 } <<
602 break; <<
603 <<
604 case SOS_SYSCALL_ID_OPEN: <<
605 { <<
606 sos_uaddr_t user_str; <<
607 sos_size_t len; <<
608 sos_ui32_t open_flags; <<
609 sos_ui32_t access_rights; <<
610 char * path; <<
611 struct sos_fs_opened_file * of; <<
612 struct sos_process * proc; <<
613 <<
614 proc = sos_thread_get_current()->proce <<
615 retval = sos_syscall_get4args(user_ctx <<
616 (unsigne <<
617 (unsigne <<
618 (unsigne <<
619 (unsigne <<
620 if (SOS_OK != retval) <<
621 break; <<
622 <<
623 retval = sos_memdup_from_user((sos_vad <<
624 if (SOS_OK != retval) <<
625 break; <<
626 <<
627 retval = sos_fs_open(proc, <<
628 path, len, <<
629 open_flags, <<
630 access_rights, <<
631 & of); <<
632 sos_kfree((sos_vaddr_t)path); <<
633 if (SOS_OK != retval) <<
634 break; <<
635 <<
636 retval = sos_process_register_opened_f <<
637 if (retval < 0) <<
638 { <<
639 sos_fs_close(of); <<
640 break; <<
641 } <<
642 } <<
643 break; <<
644 <<
645 case SOS_SYSCALL_ID_CLOSE: <<
646 { <<
647 struct sos_fs_opened_file * of; <<
648 struct sos_process * proc; <<
649 int fd; <<
650 <<
651 proc = sos_thread_get_current()->proce <<
652 retval = sos_syscall_get1arg(user_ctxt <<
653 (unsigned <<
654 if (SOS_OK != retval) <<
655 break; <<
656 <<
657 of = sos_process_get_opened_file(proc, <<
658 if (NULL == of) <<
659 { <<
660 retval = -SOS_EBADF; <<
661 break; <<
662 } <<
663 <<
664 retval = sos_process_unregister_opened <<
665 if (SOS_OK != retval) <<
666 break; <<
667 <<
668 retval = sos_fs_close(of); <<
669 } <<
670 break; <<
671 <<
672 case SOS_SYSCALL_ID_READ: <<
673 { <<
674 struct sos_fs_opened_file * of; <<
675 struct sos_process * proc; <<
676 sos_uaddr_t uaddr_buf; <<
677 sos_uaddr_t uaddr_buflen; <<
678 sos_size_t kernel_buflen; <<
679 int fd; <<
680 <<
681 proc = sos_thread_get_current()->proce <<
682 retval = sos_syscall_get3args(user_ctx <<
683 (unsigne <<
684 (unsigne <<
685 (unsigne <<
686 if (SOS_OK != retval) <<
687 break; <<
688 <<
689 <<
690 retval = sos_memcpy_from_user((sos_vad <<
691 uaddr_bu <<
692 sizeof(k <<
693 if (sizeof(kernel_buflen) != retval) <<
694 { <<
695 retval = -SOS_EFAULT; <<
696 break; <<
697 } <<
698 <<
699 of = sos_process_get_opened_file(proc, <<
700 if (NULL == of) <<
701 { <<
702 retval = -SOS_EBADF; <<
703 break; <<
704 } <<
705 <<
706 <<
707 retval = sos_fs_read(of, uaddr_buf, & <<
708 <<
709 <<
710 sos_memcpy_to_user(uaddr_buflen, <<
711 (sos_vaddr_t)& kern <<
712 sizeof(kernel_bufle <<
713 } <<
714 break; <<
715 <<
716 case SOS_SYSCALL_ID_READDIR: <<
717 { <<
718 struct sos_fs_opened_file * of; <<
719 struct sos_process * proc; <<
720 sos_uaddr_t uaddr_direntry; <<
721 struct sos_fs_dirent direntry; <<
722 int fd; <<
723 <<
724 proc = sos_thread_get_current()->proce <<
725 retval = sos_syscall_get2args(user_ctx <<
726 (unsigne <<
727 (unsigne <<
728 if (SOS_OK != retval) <<
729 break; <<
730 <<
731 of = sos_process_get_opened_file(proc, <<
732 if (NULL == of) <<
733 { <<
734 retval = -SOS_EBADF; <<
735 break; <<
736 } <<
737 <<
738 <<
739 retval = sos_fs_readdir(of, & direntry <<
740 if (SOS_OK != retval) <<
741 break; <<
742 <<
743 <<
744 if (sizeof(direntry) != sos_memcpy_to_ <<
745 <<
746 <<
747 retval = -SOS_EFAULT; <<
748 } <<
749 break; <<
750 <<
751 case SOS_SYSCALL_ID_WRITE: <<
752 { <<
753 struct sos_fs_opened_file * of; <<
754 struct sos_process * proc; <<
755 sos_uaddr_t uaddr_buf; <<
756 sos_uaddr_t uaddr_buflen; <<
757 sos_size_t kernel_buflen; <<
758 int fd; <<
759 <<
760 proc = sos_thread_get_current()->proce <<
761 retval = sos_syscall_get3args(user_ctx <<
762 (unsigne <<
763 (unsigne <<
764 (unsigne <<
765 if (SOS_OK != retval) <<
766 break; <<
767 <<
768 <<
769 retval = sos_memcpy_from_user((sos_vad <<
770 uaddr_bu <<
771 sizeof(k <<
772 if (sizeof(kernel_buflen) != retval) <<
773 { <<
774 retval = -SOS_EFAULT; <<
775 break; <<
776 } <<
777 <<
778 of = sos_process_get_opened_file(proc, <<
779 if (NULL == of) <<
780 { <<
781 retval = -SOS_EBADF; <<
782 break; <<
783 } <<
784 <<
785 <<
786 retval = sos_fs_write(of, uaddr_buf, & <<
787 <<
788 <<
789 sos_memcpy_to_user(uaddr_buflen, <<
790 (sos_vaddr_t)& kern <<
791 sizeof(kernel_bufle <<
792 } <<
793 break; <<
794 <<
795 case SOS_SYSCALL_ID_SEEK64: <<
796 { <<
797 struct sos_fs_opened_file * of; <<
798 struct sos_process * proc; <<
799 sos_uaddr_t uaddr_offset; <<
800 sos_seek_whence_t whence; <<
801 sos_lsoffset_t kernel_offset, result_p <<
802 int fd; <<
803 <<
804 proc = sos_thread_get_current()->proce <<
805 retval = sos_syscall_get3args(user_ctx <<
806 (unsigne <<
807 (unsigne <<
808 (unsigne <<
809 if (SOS_OK != retval) <<
810 break; <<
811 <<
812 <<
813 retval = sos_memcpy_from_user((sos_vad <<
814 uaddr_of <<
815 sizeof(k <<
816 if (sizeof(kernel_offset) != retval) <<
817 { <<
818 retval = -SOS_EFAULT; <<
819 break; <<
820 } <<
821 <<
822 of = sos_process_get_opened_file(proc, <<
823 if (NULL == of) <<
824 { <<
825 retval = -SOS_EBADF; <<
826 break; <<
827 } <<
828 <<
829 <<
830 retval = sos_fs_seek(of, kernel_offset <<
831 <<
832 <<
833 sos_memcpy_to_user(uaddr_offset, <<
834 (sos_vaddr_t)& resu <<
835 sizeof(kernel_offse <<
836 } <<
837 break; <<
838 <<
839 case SOS_SYSCALL_ID_FTRUNCATE64: <<
840 { <<
841 struct sos_fs_opened_file * of; <<
842 struct sos_process * proc; <<
843 sos_lsoffset_t length; <<
844 int fd; <<
845 <<
846 proc = sos_thread_get_current()->proce <<
847 retval = sos_syscall_get2args(user_ctx <<
848 (unsigne <<
849 (unsigne <<
850 if (SOS_OK != retval) <<
851 break; <<
852 <<
853 of = sos_process_get_opened_file(proc, <<
854 if (NULL == of) <<
855 { <<
856 retval = -SOS_EBADF; <<
857 break; <<
858 } <<
859 <<
860 <<
861 retval = sos_fs_ftruncate(of, length); <<
862 } <<
863 break; <<
864 <<
865 case SOS_SYSCALL_ID_FSMMAP: <<
866 { <<
867 sos_uaddr_t ptr_hint_uaddr; <<
868 sos_uaddr_t hint_uaddr; <<
869 sos_size_t length; <<
870 sos_ui32_t prot; <<
871 sos_ui32_t flags; <<
872 int fd; <<
873 sos_ui32_t offs64_hi; <<
874 sos_ui32_t offs64_lo; <<
875 sos_luoffset_t offset_in_resource; <<
876 struct sos_fs_opened_file * of; <<
877 struct sos_process * proc; <<
878 <<
879 proc = sos_thread_get_current()->proce <<
880 retval = sos_syscall_get7args(user_ctx <<
881 (unsigne <<
882 (unsigne <<
883 (unsigne <<
884 (unsigne <<
885 (unsigne <<
886 (unsigne <<
887 (unsigne <<
888 if (SOS_OK != retval) <<
889 break; <<
890 <<
891 of = sos_process_get_opened_file(proc, <<
892 if (NULL == of) <<
893 { <<
894 retval = -SOS_EBADF; <<
895 break; <<
896 } <<
897 <<
898 <<
899 offset_in_resource = offs64_hi; <<
900 offset_in_resource <<= 32; <<
901 offset_in_resource |= offs64_lo; <<
902 <<
903 retval = sos_memcpy_from_user((sos_vad <<
904 ptr_hint <<
905 sizeof(h <<
906 if (sizeof(hint_uaddr) != retval) <<
907 { <<
908 retval = -SOS_EFAULT; <<
909 break; <<
910 } <<
911 <<
912 retval = sos_fs_mmap(of, & hint_uaddr, <<
913 offset_in_resourc <<
914 if (SOS_OK == retval) <<
915 { <<
916 if (sizeof(hint_uaddr) <<
917 != sos_memcpy_to_user(ptr_hint <<
918 (sos_vad <<
919 sizeof(h <<
920 { <<
921 sos_umem_vmm_unmap(sos_process <<
922 hint_uaddr, <<
923 retval = -SOS_EFAULT; <<
924 } <<
925 } <<
926 <<
927 } <<
928 break; <<
929 <<
930 case SOS_SYSCALL_ID_FSYNC: <<
931 { <<
932 struct sos_fs_opened_file * of; <<
933 struct sos_process * proc; <<
934 int fd; <<
935 <<
936 proc = sos_thread_get_current()->proce <<
937 retval = sos_syscall_get1arg(user_ctxt <<
938 (unsigned <<
939 if (SOS_OK != retval) <<
940 break; <<
941 <<
942 of = sos_process_get_opened_file(proc, <<
943 if (NULL == of) <<
944 { <<
945 retval = -SOS_EBADF; <<
946 break; <<
947 } <<
948 <<
949 <<
950 retval = sos_fs_fsync(of); <<
951 } <<
952 break; <<
953 <<
954 case SOS_SYSCALL_ID_FCNTL: <<
955 { <<
956 struct sos_fs_opened_file * of; <<
957 struct sos_process * proc; <<
958 sos_ui32_t cmd, arg; <<
959 int fd; <<
960 <<
961 proc = sos_thread_get_current()->proce <<
962 retval = sos_syscall_get3args(user_ctx <<
963 (unsigne <<
964 (unsigne <<
965 (unsigne <<
966 if (SOS_OK != retval) <<
967 break; <<
968 <<
969 of = sos_process_get_opened_file(proc, <<
970 if (NULL == of) <<
971 { <<
972 retval = -SOS_EBADF; <<
973 break; <<
974 } <<
975 <<
976 <<
977 retval = sos_fs_fcntl(of, cmd, arg); <<
978 } <<
979 break; <<
980 <<
981 case SOS_SYSCALL_ID_CREAT: <<
982 { <<
983 sos_uaddr_t user_str; <<
984 sos_size_t len; <<
985 sos_ui32_t access_rights; <<
986 char * path; <<
987 struct sos_process * proc; <<
988 <<
989 proc = sos_thread_get_current()->proce <<
990 retval = sos_syscall_get3args(user_ctx <<
991 (unsigne <<
992 (unsigne <<
993 (unsigne <<
994 if (SOS_OK != retval) <<
995 break; <<
996 <<
997 retval = sos_memdup_from_user((sos_vad <<
998 if (SOS_OK != retval) <<
999 break; <<
1000 <<
1001 retval = sos_fs_creat(proc, <<
1002 path, len, <<
1003 access_rights); <<
1004 sos_kfree((sos_vaddr_t)path); <<
1005 } <<
1006 break; <<
1007 <<
1008 case SOS_SYSCALL_ID_LINK: <<
1009 case SOS_SYSCALL_ID_RENAME: <<
1010 { <<
1011 sos_uaddr_t user_oldpath, user_newpat <<
1012 sos_size_t oldpathlen, newpathlen; <<
1013 char * kernel_oldpath, * kernel_newpa <<
1014 struct sos_process * proc; <<
1015 <<
1016 proc = sos_thread_get_current()->proc <<
1017 retval = sos_syscall_get4args(user_ct <<
1018 (unsign <<
1019 (unsign <<
1020 (unsign <<
1021 (unsign <<
1022 if (SOS_OK != retval) <<
1023 break; <<
1024 <<
1025 retval = sos_memdup_from_user((sos_va <<
1026 user_ol <<
1027 oldpath <<
1028 if (SOS_OK != retval) <<
1029 break; <<
1030 <<
1031 retval = sos_memdup_from_user((sos_va <<
1032 user_ne <<
1033 newpath <<
1034 if (SOS_OK != retval) <<
1035 { <<
1036 sos_kfree((sos_vaddr_t) kernel_ol <<
1037 break; <<
1038 } <<
1039 <<
1040 if (syscall_id == SOS_SYSCALL_ID_LINK <<
1041 retval = sos_fs_link(proc, <<
1042 kernel_oldpath <<
1043 kernel_newpath <<
1044 else <<
1045 retval = sos_fs_rename(proc, <<
1046 kernel_oldpa <<
1047 kernel_newpa <<
1048 sos_kfree((sos_vaddr_t)kernel_oldpath <<
1049 sos_kfree((sos_vaddr_t)kernel_newpath <<
1050 } <<
1051 break; <<
1052 <<
1053 case SOS_SYSCALL_ID_UNLINK: <<
1054 { <<
1055 sos_uaddr_t user_str; <<
1056 sos_size_t len; <<
1057 char * path; <<
1058 struct sos_process * proc; <<
1059 <<
1060 proc = sos_thread_get_current()->proc <<
1061 retval = sos_syscall_get2args(user_ct <<
1062 (unsign <<
1063 (unsign <<
1064 if (SOS_OK != retval) <<
1065 break; <<
1066 <<
1067 retval = sos_memdup_from_user((sos_va <<
1068 if (SOS_OK != retval) <<
1069 break; <<
1070 <<
1071 retval = sos_fs_unlink(proc, <<
1072 path, len); <<
1073 sos_kfree((sos_vaddr_t)path); <<
1074 } <<
1075 break; <<
1076 <<
1077 case SOS_SYSCALL_ID_SYMLINK: <<
1078 { <<
1079 sos_uaddr_t user_path, user_targetpat <<
1080 sos_size_t pathlen, targetpathlen; <<
1081 char * kernel_path; <<
1082 struct sos_process * proc; <<
1083 <<
1084 proc = sos_thread_get_current()->proc <<
1085 retval = sos_syscall_get4args(user_ct <<
1086 (unsign <<
1087 (unsign <<
1088 (unsign <<
1089 (unsign <<
1090 if (SOS_OK != retval) <<
1091 break; <<
1092 <<
1093 retval = sos_memdup_from_user((sos_va <<
1094 user_pa <<
1095 pathlen <<
1096 if (SOS_OK != retval) <<
1097 break; <<
1098 <<
1099 retval = sos_fs_symlink(proc, <<
1100 kernel_path, <<
1101 user_targetpa <<
1102 sos_kfree((sos_vaddr_t)kernel_path); <<
1103 } <<
1104 break; <<
1105 <<
1106 case SOS_SYSCALL_ID_MKDIR: <<
1107 { <<
1108 sos_uaddr_t user_str; <<
1109 sos_size_t len; <<
1110 sos_ui32_t access_rights; <<
1111 char * path; <<
1112 struct sos_process * proc; <<
1113 <<
1114 proc = sos_thread_get_current()->proc <<
1115 retval = sos_syscall_get3args(user_ct <<
1116 (unsign <<
1117 (unsign <<
1118 (unsign <<
1119 if (SOS_OK != retval) <<
1120 break; <<
1121 <<
1122 retval = sos_memdup_from_user((sos_va <<
1123 if (SOS_OK != retval) <<
1124 break; <<
1125 <<
1126 retval = sos_fs_mkdir(proc, <<
1127 path, len, acce <<
1128 sos_kfree((sos_vaddr_t)path); <<
1129 } <<
1130 break; <<
1131 <<
1132 case SOS_SYSCALL_ID_RMDIR: <<
1133 { <<
1134 sos_uaddr_t user_str; <<
1135 sos_size_t len; <<
1136 char * path; <<
1137 struct sos_process * proc; <<
1138 <<
1139 proc = sos_thread_get_current()->proc <<
1140 retval = sos_syscall_get2args(user_ct <<
1141 (unsign <<
1142 (unsign <<
1143 if (SOS_OK != retval) <<
1144 break; <<
1145 <<
1146 retval = sos_memdup_from_user((sos_va <<
1147 if (SOS_OK != retval) <<
1148 break; <<
1149 <<
1150 retval = sos_fs_rmdir(proc, path, len <<
1151 sos_kfree((sos_vaddr_t)path); <<
1152 } <<
1153 break; <<
1154 <<
1155 case SOS_SYSCALL_ID_CHMOD: <<
1156 { <<
1157 sos_uaddr_t user_str; <<
1158 sos_size_t len; <<
1159 sos_ui32_t access_rights; <<
1160 char * path; <<
1161 struct sos_process * proc; <<
1162 <<
1163 proc = sos_thread_get_current()->proc <<
1164 retval = sos_syscall_get3args(user_ct <<
1165 (unsign <<
1166 (unsign <<
1167 (unsign <<
1168 if (SOS_OK != retval) <<
1169 break; <<
1170 <<
1171 retval = sos_memdup_from_user((sos_va <<
1172 if (SOS_OK != retval) <<
1173 break; <<
1174 <<
1175 retval = sos_fs_chmod(proc, path, len <<
1176 sos_kfree((sos_vaddr_t)path); <<
1177 } <<
1178 break; <<
1179 <<
1180 case SOS_SYSCALL_ID_STAT64: <<
1181 { <<
1182 sos_uaddr_t user_str; <<
1183 sos_size_t len; <<
1184 sos_uaddr_t user_stat_struct; <<
1185 struct sos_fs_stat kernel_stat_struct <<
1186 int nofollow; <<
1187 char * path; <<
1188 struct sos_process * proc; <<
1189 <<
1190 proc = sos_thread_get_current()->proc <<
1191 retval = sos_syscall_get4args(user_ct <<
1192 (unsign <<
1193 (unsign <<
1194 (unsign <<
1195 (unsign <<
1196 if (SOS_OK != retval) <<
1197 break; <<
1198 <<
1199 retval = sos_memdup_from_user((sos_va <<
1200 if (SOS_OK != retval) <<
1201 break; <<
1202 <<
1203 retval = sos_fs_stat(proc, path, len, <<
1204 sos_kfree((sos_vaddr_t)path); <<
1205 if (SOS_OK != retval) <<
1206 break; <<
1207 <<
1208 if (sizeof(kernel_stat_struct) <<
1209 != sos_memcpy_to_user(user_stat_s <<
1210 (sos_vaddr_ <<
1211 sizeof(kern <<
1212 retval = -SOS_EFAULT; <<
1213 } <<
1214 break; <<
1215 <<
1216 case SOS_SYSCALL_ID_CHROOT: <<
1217 case SOS_SYSCALL_ID_CHDIR: <<
1218 { <<
1219 sos_uaddr_t user_str; <<
1220 sos_size_t len; <<
1221 char * path; <<
1222 struct sos_fs_opened_file * of, * old <<
1223 struct sos_process * proc; <<
1224 <<
1225 proc = sos_thread_get_current()->proc <<
1226 retval = sos_syscall_get2args(user_ct <<
1227 (unsign <<
1228 (unsign <<
1229 if (SOS_OK != retval) <<
1230 break; <<
1231 <<
1232 retval = sos_memdup_from_user((sos_va <<
1233 if (SOS_OK != retval) <<
1234 break; <<
1235 <<
1236 retval = sos_fs_open(proc, <<
1237 path, len, <<
1238 SOS_FS_OPEN_DIRE <<
1239 SOS_FS_OPEN_READ <<
1240 & of); <<
1241 sos_kfree((sos_vaddr_t)path); <<
1242 if (SOS_OK != retval) <<
1243 break; <<
1244 <<
1245 if (syscall_id == SOS_SYSCALL_ID_CHRO <<
1246 retval = sos_process_chroot(proc, o <<
1247 else <<
1248 retval = sos_process_chdir(proc, of <<
1249 <<
1250 if (retval < 0) <<
1251 { <<
1252 sos_fs_close(of); <<
1253 break; <<
1254 } <<
1255 <<
1256 sos_fs_close(old_of); <<
1257 } <<
1258 break; <<
1259 <<
1260 case SOS_SYSCALL_ID_FCHDIR: <<
1261 { <<
1262 struct sos_fs_opened_file * of, * new <<
1263 struct sos_process * proc; <<
1264 int fd; <<
1265 <<
1266 proc = sos_thread_get_current()->proc <<
1267 retval = sos_syscall_get1arg(user_ctx <<
1268 (unsigne <<
1269 if (SOS_OK != retval) <<
1270 break; <<
1271 <<
1272 of = sos_process_get_opened_file(proc <<
1273 if (NULL == of) <<
1274 { <<
1275 retval = -SOS_EBADF; <<
1276 break; <<
1277 } <<
1278 <<
1279 <<
1280 retval = sos_fs_duplicate_opened_file <<
1281 if (SOS_OK != retval) <<
1282 break; <<
1283 <<
1284 <<
1285 retval = sos_process_chdir(proc, new_ <<
1286 if (retval < 0) <<
1287 { <<
1288 sos_fs_close(new_of); <<
1289 break; <<
1290 } <<
1291 <<
1292 sos_fs_close(old_of); <<
1293 } <<
1294 break; <<
1295 <<
1296 case SOS_SYSCALL_ID_BOCHS_WRITE: 048 case SOS_SYSCALL_ID_BOCHS_WRITE:
1297 { 049 {
1298 sos_uaddr_t user_str; 050 sos_uaddr_t user_str;
1299 sos_size_t len; 051 sos_size_t len;
1300 char * str; 052 char * str;
1301 retval = sos_syscall_get2args(user_ct 053 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
1302 if (SOS_OK != retval) 054 if (SOS_OK != retval)
1303 break; 055 break;
1304 056
1305 retval = sos_strndup_from_user(& str, !! 057 str = (char*)sos_kmalloc(len + 1, 0);
1306 if (SOS_OK == retval) !! 058 if (str)
1307 { 059 {
1308 sos_bochs_printf("THR 0x%x: ", !! 060 retval = sos_strzcpy_from_user(str, user_str, len+1);
1309 (unsigned)sos_th !! 061 str[len] = '\0';
1310 retval = sos_bochs_putstring(str) !! 062 if (SOS_OK == retval)
1311 retval = len; !! 063 {
>> 064 sos_bochs_printf("THR 0x%x: ",
>> 065 (unsigned)sos_thread_get_current());
>> 066 retval = sos_bochs_putstring(str);
>> 067 retval = len;
>> 068 }
1312 sos_kfree((sos_vaddr_t)str); 069 sos_kfree((sos_vaddr_t)str);
1313 } 070 }
>> 071 else
>> 072 retval = -SOS_ENOMEM;
1314 } 073 }
1315 break; 074 break;
1316 075
1317 076
1318 077
1319 078
1320 079
1321 080
1322 081
1323 082
1324 083
1325 084
1326 085
1327 case 4012: 086 case 4012:
1328 { 087 {
1329 sos_uaddr_t user_str; 088 sos_uaddr_t user_str;
1330 unsigned int len; 089 unsigned int len;
1331 unsigned char * str; 090 unsigned char * str;
1332 091
1333 retval = sos_syscall_get2args(user_ct 092 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
1334 if (SOS_OK != retval) 093 if (SOS_OK != retval)
1335 break; 094 break;
1336 095
1337 str = (char*)sos_kmalloc(len, 0); !! 096 str = (char*)sos_kmalloc(len + 1, 0);
1338 if (str) 097 if (str)
1339 { 098 {
1340 int i; 099 int i;
1341 sos_bochs_printf("Hexdump(0x%x, % 100 sos_bochs_printf("Hexdump(0x%x, %d):\n", user_str, len);
1342 retval = sos_memcpy_from_user((so 101 retval = sos_memcpy_from_user((sos_vaddr_t) str, user_str, len);
1343 sos_bochs_printf(" (Successfully 102 sos_bochs_printf(" (Successfully copied %d out of %d)\n",
1344 retval, len); 103 retval, len);
1345 104
1346 for (i = 0 ; i < retval ; i++) 105 for (i = 0 ; i < retval ; i++)
1347 { 106 {
1348 if ((i % 32) == 0) 107 if ((i % 32) == 0)
1349 sos_bochs_printf("%x:", i); 108 sos_bochs_printf("%x:", i);
1350 sos_bochs_printf(" %x", str[i 109 sos_bochs_printf(" %x", str[i]);
1351 if (((i+1) % 32) == 0) 110 if (((i+1) % 32) == 0)
1352 sos_bochs_printf("\n"); 111 sos_bochs_printf("\n");
1353 } 112 }
1354 if (i % 32) 113 if (i % 32)
1355 sos_bochs_printf("\n"); 114 sos_bochs_printf("\n");
1356 115
1357 sos_kfree((sos_vaddr_t)str); 116 sos_kfree((sos_vaddr_t)str);
1358 } 117 }
1359 else 118 else
1360 retval = -SOS_ENOMEM; 119 retval = -SOS_ENOMEM;
1361 } <<
1362 break; <<
1363 <<
1364 <<
1365 <<
1366 <<
1367 <<
1368 <<
1369 case 4004: <<
1370 { <<
1371 sos_uaddr_t ustr; <<
1372 char * kstr; <<
1373 struct sos_umem_vmm_as * my_as; <<
1374 <<
1375 retval = sos_syscall_get1arg(user_ctx <<
1376 if (SOS_OK != retval) <<
1377 break; <<
1378 <<
1379 retval = sos_strndup_from_user(& kstr <<
1380 if (SOS_OK != retval) <<
1381 break; <<
1382 <<
1383 extern void sos_dump_as(const struct <<
1384 my_as <<
1385 = sos_process_get_address_space(sos <<
1386 sos_dump_as(my_as, kstr); <<
1387 sos_kfree((sos_vaddr_t)kstr); <<
1388 } 120 }
1389 break; 121 break;
1390 122
1391 123
1392 124
1393 125
1394 126
1395 127
1396 case 4008: 128 case 4008:
1397 { 129 {
1398 extern void sos_process_dumplist(void 130 extern void sos_process_dumplist(void);
1399 sos_process_dumplist(); 131 sos_process_dumplist();
1400 retval = SOS_OK; 132 retval = SOS_OK;
1401 } 133 }
1402 break; 134 break;
1403 135
1404 default: 136 default:
1405 sos_bochs_printf("Syscall: UNKNOWN[%d]\ 137 sos_bochs_printf("Syscall: UNKNOWN[%d]\n", syscall_id);
1406 retval = -SOS_ENOSUP; 138 retval = -SOS_ENOSUP;
1407 } 139 }
1408 140
1409 return retval; 141 return retval;
1410 } 142 }