Revision 53a5960a linux-user/syscall.c
b/linux-user/syscall.c | ||
---|---|---|
252 | 252 |
return (unsigned long)ret >= (unsigned long)(-4096); |
253 | 253 |
} |
254 | 254 |
|
255 |
static char *target_brk;
|
|
256 |
static char *target_original_brk;
|
|
255 |
static target_ulong target_brk;
|
|
256 |
static target_ulong target_original_brk;
|
|
257 | 257 |
|
258 |
void target_set_brk(char *new_brk)
|
|
258 |
void target_set_brk(target_ulong new_brk)
|
|
259 | 259 |
{ |
260 |
target_brk = new_brk; |
|
261 |
target_original_brk = new_brk; |
|
260 |
target_original_brk = target_brk = new_brk; |
|
262 | 261 |
} |
263 | 262 |
|
264 |
long do_brk(char *new_brk)
|
|
263 |
long do_brk(target_ulong new_brk)
|
|
265 | 264 |
{ |
266 |
char *brk_page;
|
|
265 |
target_ulong brk_page;
|
|
267 | 266 |
long mapped_addr; |
268 | 267 |
int new_alloc_size; |
269 | 268 |
|
270 | 269 |
if (!new_brk) |
271 |
return (long)target_brk;
|
|
270 |
return target_brk; |
|
272 | 271 |
if (new_brk < target_original_brk) |
273 | 272 |
return -ENOMEM; |
274 | 273 |
|
275 |
brk_page = (char *)HOST_PAGE_ALIGN((unsigned long)target_brk);
|
|
274 |
brk_page = HOST_PAGE_ALIGN(target_brk);
|
|
276 | 275 |
|
277 | 276 |
/* If the new brk is less than this, set it and we're done... */ |
278 | 277 |
if (new_brk < brk_page) { |
279 | 278 |
target_brk = new_brk; |
280 |
return (long)target_brk;
|
|
279 |
return target_brk; |
|
281 | 280 |
} |
282 | 281 |
|
283 | 282 |
/* We need to allocate more memory after the brk... */ |
284 | 283 |
new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); |
285 |
mapped_addr = get_errno(target_mmap((unsigned long)brk_page, new_alloc_size,
|
|
284 |
mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, |
|
286 | 285 |
PROT_READ|PROT_WRITE, |
287 | 286 |
MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); |
288 | 287 |
if (is_error(mapped_addr)) { |
289 | 288 |
return mapped_addr; |
290 | 289 |
} else { |
291 | 290 |
target_brk = new_brk; |
292 |
return (long)target_brk;
|
|
291 |
return target_brk; |
|
293 | 292 |
} |
294 | 293 |
} |
295 | 294 |
|
... | ... | |
354 | 353 |
#endif |
355 | 354 |
} |
356 | 355 |
|
357 |
static inline void host_to_target_rusage(struct target_rusage *target_rusage,
|
|
356 |
static inline void host_to_target_rusage(target_ulong target_addr,
|
|
358 | 357 |
const struct rusage *rusage) |
359 | 358 |
{ |
359 |
struct target_rusage *target_rusage; |
|
360 |
|
|
361 |
lock_user_struct(target_rusage, target_addr, 0); |
|
360 | 362 |
target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec); |
361 | 363 |
target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec); |
362 | 364 |
target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec); |
... | ... | |
375 | 377 |
target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals); |
376 | 378 |
target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw); |
377 | 379 |
target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw); |
380 |
unlock_user_struct(target_rusage, target_addr, 1); |
|
378 | 381 |
} |
379 | 382 |
|
380 |
static inline void target_to_host_timeval(struct timeval *tv,
|
|
381 |
const struct target_timeval *target_tv)
|
|
383 |
static inline void target_to_host_timeval(struct timeval *tv, |
|
384 |
target_ulong target_addr)
|
|
382 | 385 |
{ |
386 |
struct target_timeval *target_tv; |
|
387 |
|
|
388 |
lock_user_struct(target_tv, target_addr, 1); |
|
383 | 389 |
tv->tv_sec = tswapl(target_tv->tv_sec); |
384 | 390 |
tv->tv_usec = tswapl(target_tv->tv_usec); |
391 |
unlock_user_struct(target_tv, target_addr, 0); |
|
385 | 392 |
} |
386 | 393 |
|
387 |
static inline void host_to_target_timeval(struct target_timeval *target_tv,
|
|
394 |
static inline void host_to_target_timeval(target_ulong target_addr,
|
|
388 | 395 |
const struct timeval *tv) |
389 | 396 |
{ |
397 |
struct target_timeval *target_tv; |
|
398 |
|
|
399 |
lock_user_struct(target_tv, target_addr, 0); |
|
390 | 400 |
target_tv->tv_sec = tswapl(tv->tv_sec); |
391 | 401 |
target_tv->tv_usec = tswapl(tv->tv_usec); |
402 |
unlock_user_struct(target_tv, target_addr, 1); |
|
392 | 403 |
} |
393 | 404 |
|
394 | 405 |
|
395 | 406 |
static long do_select(long n, |
396 |
target_long *target_rfds, target_long *target_wfds,
|
|
397 |
target_long *target_efds, struct target_timeval *target_tv)
|
|
407 |
target_ulong rfd_p, target_ulong wfd_p,
|
|
408 |
target_ulong efd_p, target_ulong target_tv)
|
|
398 | 409 |
{ |
399 | 410 |
fd_set rfds, wfds, efds; |
400 | 411 |
fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; |
412 |
target_long *target_rfds, *target_wfds, *target_efds; |
|
401 | 413 |
struct timeval tv, *tv_ptr; |
402 | 414 |
long ret; |
415 |
int ok; |
|
403 | 416 |
|
404 |
rfds_ptr = target_to_host_fds(&rfds, target_rfds, n); |
|
405 |
wfds_ptr = target_to_host_fds(&wfds, target_wfds, n); |
|
406 |
efds_ptr = target_to_host_fds(&efds, target_efds, n); |
|
417 |
if (rfd_p) { |
|
418 |
target_rfds = lock_user(rfd_p, sizeof(target_long) * n, 1); |
|
419 |
rfds_ptr = target_to_host_fds(&rfds, target_rfds, n); |
|
420 |
} else { |
|
421 |
target_rfds = NULL; |
|
422 |
rfds_ptr = NULL; |
|
423 |
} |
|
424 |
if (wfd_p) { |
|
425 |
target_wfds = lock_user(wfd_p, sizeof(target_long) * n, 1); |
|
426 |
wfds_ptr = target_to_host_fds(&wfds, target_wfds, n); |
|
427 |
} else { |
|
428 |
target_wfds = NULL; |
|
429 |
wfds_ptr = NULL; |
|
430 |
} |
|
431 |
if (efd_p) { |
|
432 |
target_efds = lock_user(efd_p, sizeof(target_long) * n, 1); |
|
433 |
efds_ptr = target_to_host_fds(&efds, target_efds, n); |
|
434 |
} else { |
|
435 |
target_efds = NULL; |
|
436 |
efds_ptr = NULL; |
|
437 |
} |
|
407 | 438 |
|
408 | 439 |
if (target_tv) { |
409 | 440 |
target_to_host_timeval(&tv, target_tv); |
... | ... | |
412 | 443 |
tv_ptr = NULL; |
413 | 444 |
} |
414 | 445 |
ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr)); |
415 |
if (!is_error(ret)) { |
|
446 |
ok = !is_error(ret); |
|
447 |
|
|
448 |
if (ok) { |
|
416 | 449 |
host_to_target_fds(target_rfds, rfds_ptr, n); |
417 | 450 |
host_to_target_fds(target_wfds, wfds_ptr, n); |
418 | 451 |
host_to_target_fds(target_efds, efds_ptr, n); |
... | ... | |
421 | 454 |
host_to_target_timeval(target_tv, &tv); |
422 | 455 |
} |
423 | 456 |
} |
457 |
if (target_rfds) |
|
458 |
unlock_user(target_rfds, rfd_p, ok ? sizeof(target_long) * n : 0); |
|
459 |
if (target_wfds) |
|
460 |
unlock_user(target_wfds, wfd_p, ok ? sizeof(target_long) * n : 0); |
|
461 |
if (target_efds) |
|
462 |
unlock_user(target_efds, efd_p, ok ? sizeof(target_long) * n : 0); |
|
463 |
|
|
424 | 464 |
return ret; |
425 | 465 |
} |
426 | 466 |
|
427 | 467 |
static inline void target_to_host_sockaddr(struct sockaddr *addr, |
428 |
struct target_sockaddr *target_addr,
|
|
468 |
target_ulong target_addr,
|
|
429 | 469 |
socklen_t len) |
430 | 470 |
{ |
431 |
memcpy(addr, target_addr, len); |
|
432 |
addr->sa_family = tswap16(target_addr->sa_family); |
|
471 |
struct target_sockaddr *target_saddr; |
|
472 |
|
|
473 |
target_saddr = lock_user(target_addr, len, 1); |
|
474 |
memcpy(addr, target_saddr, len); |
|
475 |
addr->sa_family = tswap16(target_saddr->sa_family); |
|
476 |
unlock_user(target_saddr, target_addr, 0); |
|
433 | 477 |
} |
434 | 478 |
|
435 |
static inline void host_to_target_sockaddr(struct target_sockaddr *target_addr,
|
|
479 |
static inline void host_to_target_sockaddr(target_ulong target_addr,
|
|
436 | 480 |
struct sockaddr *addr, |
437 | 481 |
socklen_t len) |
438 | 482 |
{ |
439 |
memcpy(target_addr, addr, len); |
|
440 |
target_addr->sa_family = tswap16(addr->sa_family); |
|
483 |
struct target_sockaddr *target_saddr; |
|
484 |
|
|
485 |
target_saddr = lock_user(target_addr, len, 0); |
|
486 |
memcpy(target_saddr, addr, len); |
|
487 |
target_saddr->sa_family = tswap16(addr->sa_family); |
|
488 |
unlock_user(target_saddr, target_addr, len); |
|
441 | 489 |
} |
442 | 490 |
|
491 |
/* ??? Should this also swap msgh->name? */ |
|
443 | 492 |
static inline void target_to_host_cmsg(struct msghdr *msgh, |
444 | 493 |
struct target_msghdr *target_msgh) |
445 | 494 |
{ |
... | ... | |
484 | 533 |
msgh->msg_controllen = space; |
485 | 534 |
} |
486 | 535 |
|
536 |
/* ??? Should this also swap msgh->name? */ |
|
487 | 537 |
static inline void host_to_target_cmsg(struct target_msghdr *target_msgh, |
488 | 538 |
struct msghdr *msgh) |
489 | 539 |
{ |
... | ... | |
528 | 578 |
} |
529 | 579 |
|
530 | 580 |
static long do_setsockopt(int sockfd, int level, int optname, |
531 |
void *optval, socklen_t optlen)
|
|
581 |
target_ulong optval, socklen_t optlen)
|
|
532 | 582 |
{ |
533 | 583 |
int val, ret; |
534 | 584 |
|
... | ... | |
538 | 588 |
if (optlen < sizeof(uint32_t)) |
539 | 589 |
return -EINVAL; |
540 | 590 |
|
541 |
if (get_user(val, (uint32_t *)optval)) |
|
542 |
return -EFAULT; |
|
591 |
val = tget32(optval); |
|
543 | 592 |
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); |
544 | 593 |
break; |
545 | 594 |
case SOL_IP: |
... | ... | |
561 | 610 |
case IP_MULTICAST_LOOP: |
562 | 611 |
val = 0; |
563 | 612 |
if (optlen >= sizeof(uint32_t)) { |
564 |
if (get_user(val, (uint32_t *)optval)) |
|
565 |
return -EFAULT; |
|
613 |
val = tget32(optval); |
|
566 | 614 |
} else if (optlen >= 1) { |
567 |
if (get_user(val, (uint8_t *)optval)) |
|
568 |
return -EFAULT; |
|
615 |
val = tget8(optval); |
|
569 | 616 |
} |
570 | 617 |
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); |
571 | 618 |
break; |
... | ... | |
598 | 645 |
case SO_SNDTIMEO: |
599 | 646 |
if (optlen < sizeof(uint32_t)) |
600 | 647 |
return -EINVAL; |
601 |
if (get_user(val, (uint32_t *)optval)) |
|
602 |
return -EFAULT;
|
|
648 |
|
|
649 |
val = tget32(optval);
|
|
603 | 650 |
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); |
604 | 651 |
break; |
605 | 652 |
default: |
... | ... | |
615 | 662 |
} |
616 | 663 |
|
617 | 664 |
static long do_getsockopt(int sockfd, int level, int optname, |
618 |
void *optval, socklen_t *optlen)
|
|
665 |
target_ulong optval, target_ulong optlen)
|
|
619 | 666 |
{ |
620 | 667 |
int len, lv, val, ret; |
621 | 668 |
|
... | ... | |
636 | 683 |
case SOL_TCP: |
637 | 684 |
/* TCP options all take an 'int' value. */ |
638 | 685 |
int_case: |
639 |
if (get_user(len, optlen)) |
|
640 |
return -EFAULT; |
|
686 |
len = tget32(optlen); |
|
641 | 687 |
if (len < 0) |
642 | 688 |
return -EINVAL; |
643 | 689 |
lv = sizeof(int); |
... | ... | |
647 | 693 |
val = tswap32(val); |
648 | 694 |
if (len > lv) |
649 | 695 |
len = lv; |
650 |
if (copy_to_user(optval, &val, len)) |
|
651 |
return -EFAULT; |
|
652 |
if (put_user(len, optlen)) |
|
653 |
return -EFAULT; |
|
696 |
if (len == 4) |
|
697 |
tput32(optval, val); |
|
698 |
else |
|
699 |
tput8(optval, val); |
|
700 |
tput32(optlen, len); |
|
654 | 701 |
break; |
655 | 702 |
case SOL_IP: |
656 | 703 |
switch(optname) { |
... | ... | |
669 | 716 |
#endif |
670 | 717 |
case IP_MULTICAST_TTL: |
671 | 718 |
case IP_MULTICAST_LOOP: |
672 |
if (get_user(len, optlen)) |
|
673 |
return -EFAULT; |
|
719 |
len = tget32(optlen); |
|
674 | 720 |
if (len < 0) |
675 | 721 |
return -EINVAL; |
676 | 722 |
lv = sizeof(int); |
... | ... | |
678 | 724 |
if (ret < 0) |
679 | 725 |
return ret; |
680 | 726 |
if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) { |
681 |
unsigned char ucval = val; |
|
682 | 727 |
len = 1; |
683 |
if (put_user(len, optlen)) |
|
684 |
return -EFAULT; |
|
685 |
if (copy_to_user(optval,&ucval,1)) |
|
686 |
return -EFAULT; |
|
728 |
tput32(optlen, len); |
|
729 |
tput8(optval, val); |
|
687 | 730 |
} else { |
688 |
val = tswap32(val); |
|
689 | 731 |
if (len > sizeof(int)) |
690 | 732 |
len = sizeof(int); |
691 |
if (put_user(len, optlen)) |
|
692 |
return -EFAULT; |
|
693 |
if (copy_to_user(optval, &val, len)) |
|
694 |
return -EFAULT; |
|
733 |
tput32(optlen, len); |
|
734 |
tput32(optval, val); |
|
695 | 735 |
} |
696 | 736 |
break; |
697 | 737 |
default: |
... | ... | |
708 | 748 |
return ret; |
709 | 749 |
} |
710 | 750 |
|
711 |
static long do_socketcall(int num, int32_t *vptr) |
|
751 |
static void lock_iovec(struct iovec *vec, target_ulong target_addr, |
|
752 |
int count, int copy) |
|
753 |
{ |
|
754 |
struct target_iovec *target_vec; |
|
755 |
target_ulong base; |
|
756 |
int i; |
|
757 |
|
|
758 |
target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); |
|
759 |
for(i = 0;i < count; i++) { |
|
760 |
base = tswapl(target_vec[i].iov_base); |
|
761 |
vec[i].iov_len = tswapl(target_vec[i].iov_len); |
|
762 |
vec[i].iov_base = lock_user(base, vec[i].iov_len, copy); |
|
763 |
} |
|
764 |
unlock_user (target_vec, target_addr, 0); |
|
765 |
} |
|
766 |
|
|
767 |
static void unlock_iovec(struct iovec *vec, target_ulong target_addr, |
|
768 |
int count, int copy) |
|
769 |
{ |
|
770 |
struct target_iovec *target_vec; |
|
771 |
target_ulong base; |
|
772 |
int i; |
|
773 |
|
|
774 |
target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); |
|
775 |
for(i = 0;i < count; i++) { |
|
776 |
base = tswapl(target_vec[i].iov_base); |
|
777 |
unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); |
|
778 |
} |
|
779 |
unlock_user (target_vec, target_addr, 0); |
|
780 |
} |
|
781 |
|
|
782 |
static long do_socketcall(int num, target_ulong vptr) |
|
712 | 783 |
{ |
713 | 784 |
long ret; |
785 |
const int n = sizeof(target_ulong); |
|
714 | 786 |
|
715 | 787 |
switch(num) { |
716 | 788 |
case SOCKOP_socket: |
717 | 789 |
{ |
718 |
int domain = tswap32(vptr[0]);
|
|
719 |
int type = tswap32(vptr[1]);
|
|
720 |
int protocol = tswap32(vptr[2]);
|
|
790 |
int domain = tgetl(vptr);
|
|
791 |
int type = tgetl(vptr + n);
|
|
792 |
int protocol = tgetl(vptr + 2 * n);
|
|
721 | 793 |
|
722 | 794 |
ret = get_errno(socket(domain, type, protocol)); |
723 | 795 |
} |
724 | 796 |
break; |
725 | 797 |
case SOCKOP_bind: |
726 | 798 |
{ |
727 |
int sockfd = tswap32(vptr[0]);
|
|
728 |
void *target_addr = (void *)tswap32(vptr[1]);
|
|
729 |
socklen_t addrlen = tswap32(vptr[2]);
|
|
799 |
int sockfd = tgetl(vptr);
|
|
800 |
target_ulong target_addr = tgetl(vptr + n);
|
|
801 |
socklen_t addrlen = tgetl(vptr + 2 * n);
|
|
730 | 802 |
void *addr = alloca(addrlen); |
731 | 803 |
|
732 | 804 |
target_to_host_sockaddr(addr, target_addr, addrlen); |
... | ... | |
735 | 807 |
break; |
736 | 808 |
case SOCKOP_connect: |
737 | 809 |
{ |
738 |
int sockfd = tswap32(vptr[0]);
|
|
739 |
void *target_addr = (void *)tswap32(vptr[1]);
|
|
740 |
socklen_t addrlen = tswap32(vptr[2]);
|
|
810 |
int sockfd = tgetl(vptr);
|
|
811 |
target_ulong target_addr = tgetl(vptr + n);
|
|
812 |
socklen_t addrlen = tgetl(vptr + 2 * n);
|
|
741 | 813 |
void *addr = alloca(addrlen); |
742 | 814 |
|
743 | 815 |
target_to_host_sockaddr(addr, target_addr, addrlen); |
... | ... | |
746 | 818 |
break; |
747 | 819 |
case SOCKOP_listen: |
748 | 820 |
{ |
749 |
int sockfd = tswap32(vptr[0]);
|
|
750 |
int backlog = tswap32(vptr[1]);
|
|
821 |
int sockfd = tgetl(vptr);
|
|
822 |
int backlog = tgetl(vptr + n);
|
|
751 | 823 |
|
752 | 824 |
ret = get_errno(listen(sockfd, backlog)); |
753 | 825 |
} |
754 | 826 |
break; |
755 | 827 |
case SOCKOP_accept: |
756 | 828 |
{ |
757 |
int sockfd = tswap32(vptr[0]);
|
|
758 |
void *target_addr = (void *)tswap32(vptr[1]);
|
|
759 |
uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
|
|
760 |
socklen_t addrlen = tswap32(*target_addrlen);
|
|
829 |
int sockfd = tgetl(vptr);
|
|
830 |
target_ulong target_addr = tgetl(vptr + n);
|
|
831 |
target_ulong target_addrlen = tgetl(vptr + 2 * n);
|
|
832 |
socklen_t addrlen = tget32(target_addrlen);
|
|
761 | 833 |
void *addr = alloca(addrlen); |
762 | 834 |
|
763 | 835 |
ret = get_errno(accept(sockfd, addr, &addrlen)); |
764 | 836 |
if (!is_error(ret)) { |
765 | 837 |
host_to_target_sockaddr(target_addr, addr, addrlen); |
766 |
*target_addrlen = tswap32(addrlen);
|
|
838 |
tput32(target_addrlen, addrlen);
|
|
767 | 839 |
} |
768 | 840 |
} |
769 | 841 |
break; |
770 | 842 |
case SOCKOP_getsockname: |
771 | 843 |
{ |
772 |
int sockfd = tswap32(vptr[0]);
|
|
773 |
void *target_addr = (void *)tswap32(vptr[1]);
|
|
774 |
uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
|
|
775 |
socklen_t addrlen = tswap32(*target_addrlen);
|
|
844 |
int sockfd = tgetl(vptr);
|
|
845 |
target_ulong target_addr = tgetl(vptr + n);
|
|
846 |
target_ulong target_addrlen = tgetl(vptr + 2 * n);
|
|
847 |
socklen_t addrlen = tget32(target_addrlen);
|
|
776 | 848 |
void *addr = alloca(addrlen); |
777 | 849 |
|
778 | 850 |
ret = get_errno(getsockname(sockfd, addr, &addrlen)); |
779 | 851 |
if (!is_error(ret)) { |
780 | 852 |
host_to_target_sockaddr(target_addr, addr, addrlen); |
781 |
*target_addrlen = tswap32(addrlen);
|
|
853 |
tput32(target_addrlen, addrlen);
|
|
782 | 854 |
} |
783 | 855 |
} |
784 | 856 |
break; |
785 | 857 |
case SOCKOP_getpeername: |
786 | 858 |
{ |
787 |
int sockfd = tswap32(vptr[0]);
|
|
788 |
void *target_addr = (void *)tswap32(vptr[1]);
|
|
789 |
uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
|
|
790 |
socklen_t addrlen = tswap32(*target_addrlen);
|
|
859 |
int sockfd = tgetl(vptr);
|
|
860 |
target_ulong target_addr = tgetl(vptr + n);
|
|
861 |
target_ulong target_addrlen = tgetl(vptr + 2 * n);
|
|
862 |
socklen_t addrlen = tget32(target_addrlen);
|
|
791 | 863 |
void *addr = alloca(addrlen); |
792 | 864 |
|
793 | 865 |
ret = get_errno(getpeername(sockfd, addr, &addrlen)); |
794 | 866 |
if (!is_error(ret)) { |
795 | 867 |
host_to_target_sockaddr(target_addr, addr, addrlen); |
796 |
*target_addrlen = tswap32(addrlen);
|
|
868 |
tput32(target_addrlen, addrlen);
|
|
797 | 869 |
} |
798 | 870 |
} |
799 | 871 |
break; |
800 | 872 |
case SOCKOP_socketpair: |
801 | 873 |
{ |
802 |
int domain = tswap32(vptr[0]);
|
|
803 |
int type = tswap32(vptr[1]);
|
|
804 |
int protocol = tswap32(vptr[2]);
|
|
805 |
int32_t *target_tab = (void *)tswap32(vptr[3]);
|
|
874 |
int domain = tgetl(vptr);
|
|
875 |
int type = tgetl(vptr + n);
|
|
876 |
int protocol = tgetl(vptr + 2 * n);
|
|
877 |
target_ulong target_tab = tgetl(vptr + 3 * n);
|
|
806 | 878 |
int tab[2]; |
807 | 879 |
|
808 | 880 |
ret = get_errno(socketpair(domain, type, protocol, tab)); |
809 | 881 |
if (!is_error(ret)) { |
810 |
target_tab[0] = tswap32(tab[0]);
|
|
811 |
target_tab[1] = tswap32(tab[1]);
|
|
882 |
tput32(target_tab, tab[0]);
|
|
883 |
tput32(target_tab + 4, tab[1]);
|
|
812 | 884 |
} |
813 | 885 |
} |
814 | 886 |
break; |
815 | 887 |
case SOCKOP_send: |
816 | 888 |
{ |
817 |
int sockfd = tswap32(vptr[0]); |
|
818 |
void *msg = (void *)tswap32(vptr[1]); |
|
819 |
size_t len = tswap32(vptr[2]); |
|
820 |
int flags = tswap32(vptr[3]); |
|
889 |
int sockfd = tgetl(vptr); |
|
890 |
target_ulong msg = tgetl(vptr + n); |
|
891 |
size_t len = tgetl(vptr + 2 * n); |
|
892 |
int flags = tgetl(vptr + 3 * n); |
|
893 |
void *host_msg; |
|
821 | 894 |
|
822 |
ret = get_errno(send(sockfd, msg, len, flags)); |
|
895 |
host_msg = lock_user(msg, len, 1); |
|
896 |
ret = get_errno(send(sockfd, host_msg, len, flags)); |
|
897 |
unlock_user(host_msg, msg, 0); |
|
823 | 898 |
} |
824 | 899 |
break; |
825 | 900 |
case SOCKOP_recv: |
826 | 901 |
{ |
827 |
int sockfd = tswap32(vptr[0]); |
|
828 |
void *msg = (void *)tswap32(vptr[1]); |
|
829 |
size_t len = tswap32(vptr[2]); |
|
830 |
int flags = tswap32(vptr[3]); |
|
902 |
int sockfd = tgetl(vptr); |
|
903 |
target_ulong msg = tgetl(vptr + n); |
|
904 |
size_t len = tgetl(vptr + 2 * n); |
|
905 |
int flags = tgetl(vptr + 3 * n); |
|
906 |
void *host_msg; |
|
831 | 907 |
|
832 |
ret = get_errno(recv(sockfd, msg, len, flags)); |
|
908 |
host_msg = lock_user(msg, len, 0); |
|
909 |
ret = get_errno(recv(sockfd, host_msg, len, flags)); |
|
910 |
unlock_user(host_msg, msg, ret); |
|
833 | 911 |
} |
834 | 912 |
break; |
835 | 913 |
case SOCKOP_sendto: |
836 | 914 |
{ |
837 |
int sockfd = tswap32(vptr[0]);
|
|
838 |
void *msg = (void *)tswap32(vptr[1]);
|
|
839 |
size_t len = tswap32(vptr[2]);
|
|
840 |
int flags = tswap32(vptr[3]);
|
|
841 |
void *target_addr = (void *)tswap32(vptr[4]);
|
|
842 |
socklen_t addrlen = tswap32(vptr[5]);
|
|
915 |
int sockfd = tgetl(vptr);
|
|
916 |
target_ulong msg = tgetl(vptr + n);
|
|
917 |
size_t len = tgetl(vptr + 2 * n);
|
|
918 |
int flags = tgetl(vptr + 3 * n);
|
|
919 |
target_ulong target_addr = tgetl(vptr + 4 * n);
|
|
920 |
socklen_t addrlen = tgetl(vptr + 5 * n);
|
|
843 | 921 |
void *addr = alloca(addrlen); |
922 |
void *host_msg; |
|
844 | 923 |
|
924 |
host_msg = lock_user(msg, len, 1); |
|
845 | 925 |
target_to_host_sockaddr(addr, target_addr, addrlen); |
846 |
ret = get_errno(sendto(sockfd, msg, len, flags, addr, addrlen)); |
|
926 |
ret = get_errno(sendto(sockfd, host_msg, len, flags, addr, addrlen)); |
|
927 |
unlock_user(host_msg, msg, 0); |
|
847 | 928 |
} |
848 | 929 |
break; |
849 | 930 |
case SOCKOP_recvfrom: |
850 | 931 |
{ |
851 |
int sockfd = tswap32(vptr[0]);
|
|
852 |
void *msg = (void *)tswap32(vptr[1]);
|
|
853 |
size_t len = tswap32(vptr[2]);
|
|
854 |
int flags = tswap32(vptr[3]);
|
|
855 |
void *target_addr = (void *)tswap32(vptr[4]);
|
|
856 |
uint32_t *target_addrlen = (void *)tswap32(vptr[5]);
|
|
857 |
socklen_t addrlen = tswap32(*target_addrlen);
|
|
932 |
int sockfd = tgetl(vptr);
|
|
933 |
target_ulong msg = tgetl(vptr + n);
|
|
934 |
size_t len = tgetl(vptr + 2 * n);
|
|
935 |
int flags = tgetl(vptr + 3 * n);
|
|
936 |
target_ulong target_addr = tgetl(vptr + 4 * n);
|
|
937 |
target_ulong target_addrlen = tgetl(vptr + 5 * n);
|
|
938 |
socklen_t addrlen = tget32(target_addrlen);
|
|
858 | 939 |
void *addr = alloca(addrlen); |
940 |
void *host_msg; |
|
859 | 941 |
|
860 |
ret = get_errno(recvfrom(sockfd, msg, len, flags, addr, &addrlen)); |
|
942 |
host_msg = lock_user(msg, len, 0); |
|
943 |
ret = get_errno(recvfrom(sockfd, host_msg, len, flags, addr, &addrlen)); |
|
861 | 944 |
if (!is_error(ret)) { |
862 | 945 |
host_to_target_sockaddr(target_addr, addr, addrlen); |
863 |
*target_addrlen = tswap32(addrlen); |
|
946 |
tput32(target_addrlen, addrlen); |
|
947 |
unlock_user(host_msg, msg, len); |
|
948 |
} else { |
|
949 |
unlock_user(host_msg, msg, 0); |
|
864 | 950 |
} |
865 | 951 |
} |
866 | 952 |
break; |
867 | 953 |
case SOCKOP_shutdown: |
868 | 954 |
{ |
869 |
int sockfd = tswap32(vptr[0]);
|
|
870 |
int how = tswap32(vptr[1]);
|
|
955 |
int sockfd = tgetl(vptr);
|
|
956 |
int how = tgetl(vptr + n);
|
|
871 | 957 |
|
872 | 958 |
ret = get_errno(shutdown(sockfd, how)); |
873 | 959 |
} |
... | ... | |
876 | 962 |
case SOCKOP_recvmsg: |
877 | 963 |
{ |
878 | 964 |
int fd; |
965 |
target_ulong target_msg; |
|
879 | 966 |
struct target_msghdr *msgp; |
880 | 967 |
struct msghdr msg; |
881 |
int flags, count, i;
|
|
968 |
int flags, count; |
|
882 | 969 |
struct iovec *vec; |
883 |
struct target_iovec *target_vec; |
|
884 |
|
|
885 |
msgp = (void *)tswap32(vptr[1]); |
|
886 |
msg.msg_name = (void *)tswapl(msgp->msg_name); |
|
887 |
msg.msg_namelen = tswapl(msgp->msg_namelen); |
|
970 |
target_ulong target_vec; |
|
971 |
int send = (num == SOCKOP_sendmsg); |
|
972 |
|
|
973 |
target_msg = tgetl(vptr + n); |
|
974 |
lock_user_struct(msgp, target_msg, 1); |
|
975 |
if (msgp->msg_name) { |
|
976 |
msg.msg_namelen = tswap32(msgp->msg_namelen); |
|
977 |
msg.msg_name = alloca(msg.msg_namelen); |
|
978 |
target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name), |
|
979 |
msg.msg_namelen); |
|
980 |
} else { |
|
981 |
msg.msg_name = NULL; |
|
982 |
msg.msg_namelen = 0; |
|
983 |
} |
|
888 | 984 |
msg.msg_controllen = 2 * tswapl(msgp->msg_controllen); |
889 | 985 |
msg.msg_control = alloca(msg.msg_controllen); |
890 | 986 |
msg.msg_flags = tswap32(msgp->msg_flags); |
891 | 987 |
|
892 | 988 |
count = tswapl(msgp->msg_iovlen); |
893 | 989 |
vec = alloca(count * sizeof(struct iovec)); |
894 |
target_vec = (void *)tswapl(msgp->msg_iov); |
|
895 |
for(i = 0;i < count; i++) { |
|
896 |
vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base); |
|
897 |
vec[i].iov_len = tswapl(target_vec[i].iov_len); |
|
898 |
} |
|
990 |
target_vec = tswapl(msgp->msg_iov); |
|
991 |
lock_iovec(vec, target_vec, count, send); |
|
899 | 992 |
msg.msg_iovlen = count; |
900 | 993 |
msg.msg_iov = vec; |
901 | 994 |
|
902 |
fd = tswap32(vptr[0]);
|
|
903 |
flags = tswap32(vptr[2]);
|
|
904 |
if (num == SOCKOP_sendmsg) {
|
|
995 |
fd = tgetl(vptr);
|
|
996 |
flags = tgetl(vptr + 2 * n);
|
|
997 |
if (send) {
|
|
905 | 998 |
target_to_host_cmsg(&msg, msgp); |
906 | 999 |
ret = get_errno(sendmsg(fd, &msg, flags)); |
907 | 1000 |
} else { |
... | ... | |
909 | 1002 |
if (!is_error(ret)) |
910 | 1003 |
host_to_target_cmsg(msgp, &msg); |
911 | 1004 |
} |
1005 |
unlock_iovec(vec, target_vec, count, !send); |
|
912 | 1006 |
} |
913 | 1007 |
break; |
914 | 1008 |
case SOCKOP_setsockopt: |
915 | 1009 |
{ |
916 |
int sockfd = tswap32(vptr[0]);
|
|
917 |
int level = tswap32(vptr[1]);
|
|
918 |
int optname = tswap32(vptr[2]);
|
|
919 |
void *optval = (void *)tswap32(vptr[3]);
|
|
920 |
socklen_t optlen = tswap32(vptr[4]);
|
|
1010 |
int sockfd = tgetl(vptr);
|
|
1011 |
int level = tgetl(vptr + n);
|
|
1012 |
int optname = tgetl(vptr + 2 * n);
|
|
1013 |
target_ulong optval = tgetl(vptr + 3 * n);
|
|
1014 |
socklen_t optlen = tgetl(vptr + 4 * n);
|
|
921 | 1015 |
|
922 | 1016 |
ret = do_setsockopt(sockfd, level, optname, optval, optlen); |
923 | 1017 |
} |
924 | 1018 |
break; |
925 | 1019 |
case SOCKOP_getsockopt: |
926 | 1020 |
{ |
927 |
int sockfd = tswap32(vptr[0]);
|
|
928 |
int level = tswap32(vptr[1]);
|
|
929 |
int optname = tswap32(vptr[2]);
|
|
930 |
void *optval = (void *)tswap32(vptr[3]);
|
|
931 |
uint32_t *poptlen = (void *)tswap32(vptr[4]);
|
|
1021 |
int sockfd = tgetl(vptr);
|
|
1022 |
int level = tgetl(vptr + n);
|
|
1023 |
int optname = tgetl(vptr + 2 * n);
|
|
1024 |
target_ulong optval = tgetl(vptr + 3 * n);
|
|
1025 |
target_ulong poptlen = tgetl(vptr + 4 * n);
|
|
932 | 1026 |
|
933 | 1027 |
ret = do_getsockopt(sockfd, level, optname, optval, poptlen); |
934 | 1028 |
} |
... | ... | |
949 | 1043 |
uint32_t size; |
950 | 1044 |
} shm_regions[N_SHM_REGIONS]; |
951 | 1045 |
|
1046 |
/* ??? This only works with linear mappings. */ |
|
952 | 1047 |
static long do_ipc(long call, long first, long second, long third, |
953 | 1048 |
long ptr, long fifth) |
954 | 1049 |
{ |
... | ... | |
1065 | 1160 |
{ 0, 0, }, |
1066 | 1161 |
}; |
1067 | 1162 |
|
1163 |
/* ??? Implement proper locking for ioctls. */ |
|
1068 | 1164 |
static long do_ioctl(long fd, long cmd, long arg) |
1069 | 1165 |
{ |
1070 | 1166 |
const IOCTLEntry *ie; |
1071 | 1167 |
const argtype *arg_type; |
1072 | 1168 |
long ret; |
1073 | 1169 |
uint8_t buf_temp[MAX_STRUCT_SIZE]; |
1170 |
int target_size; |
|
1171 |
void *argptr; |
|
1074 | 1172 |
|
1075 | 1173 |
ie = ioctl_entries; |
1076 | 1174 |
for(;;) { |
... | ... | |
1098 | 1196 |
break; |
1099 | 1197 |
case TYPE_PTR: |
1100 | 1198 |
arg_type++; |
1199 |
target_size = thunk_type_size(arg_type, 0); |
|
1101 | 1200 |
switch(ie->access) { |
1102 | 1201 |
case IOC_R: |
1103 | 1202 |
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); |
1104 | 1203 |
if (!is_error(ret)) { |
1105 |
thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET); |
|
1204 |
argptr = lock_user(arg, target_size, 0); |
|
1205 |
thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); |
|
1206 |
unlock_user(argptr, arg, target_size); |
|
1106 | 1207 |
} |
1107 | 1208 |
break; |
1108 | 1209 |
case IOC_W: |
1109 |
thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST); |
|
1210 |
argptr = lock_user(arg, target_size, 1); |
|
1211 |
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); |
|
1212 |
unlock_user(argptr, arg, 0); |
|
1110 | 1213 |
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); |
1111 | 1214 |
break; |
1112 | 1215 |
default: |
1113 | 1216 |
case IOC_RW: |
1114 |
thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST); |
|
1217 |
argptr = lock_user(arg, target_size, 1); |
|
1218 |
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); |
|
1219 |
unlock_user(argptr, arg, 0); |
|
1115 | 1220 |
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); |
1116 | 1221 |
if (!is_error(ret)) { |
1117 |
thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET); |
|
1222 |
argptr = lock_user(arg, target_size, 0); |
|
1223 |
thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); |
|
1224 |
unlock_user(argptr, arg, target_size); |
|
1118 | 1225 |
} |
1119 | 1226 |
break; |
1120 | 1227 |
} |
... | ... | |
1338 | 1445 |
/* NOTE: there is really one LDT for all the threads */ |
1339 | 1446 |
uint8_t *ldt_table; |
1340 | 1447 |
|
1341 |
static int read_ldt(void *ptr, unsigned long bytecount)
|
|
1448 |
static int read_ldt(target_ulong ptr, unsigned long bytecount)
|
|
1342 | 1449 |
{ |
1343 | 1450 |
int size; |
1451 |
void *p; |
|
1344 | 1452 |
|
1345 | 1453 |
if (!ldt_table) |
1346 | 1454 |
return 0; |
1347 | 1455 |
size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE; |
1348 | 1456 |
if (size > bytecount) |
1349 | 1457 |
size = bytecount; |
1350 |
memcpy(ptr, ldt_table, size); |
|
1458 |
p = lock_user(ptr, size, 0); |
|
1459 |
/* ??? Shoudl this by byteswapped? */ |
|
1460 |
memcpy(p, ldt_table, size); |
|
1461 |
unlock_user(p, ptr, size); |
|
1351 | 1462 |
return size; |
1352 | 1463 |
} |
1353 | 1464 |
|
1354 | 1465 |
/* XXX: add locking support */ |
1355 | 1466 |
static int write_ldt(CPUX86State *env, |
1356 |
void *ptr, unsigned long bytecount, int oldmode)
|
|
1467 |
target_ulong ptr, unsigned long bytecount, int oldmode)
|
|
1357 | 1468 |
{ |
1358 | 1469 |
struct target_modify_ldt_ldt_s ldt_info; |
1470 |
struct target_modify_ldt_ldt_s *target_ldt_info; |
|
1359 | 1471 |
int seg_32bit, contents, read_exec_only, limit_in_pages; |
1360 | 1472 |
int seg_not_present, useable; |
1361 | 1473 |
uint32_t *lp, entry_1, entry_2; |
1362 | 1474 |
|
1363 | 1475 |
if (bytecount != sizeof(ldt_info)) |
1364 | 1476 |
return -EINVAL; |
1365 |
memcpy(&ldt_info, ptr, sizeof(ldt_info)); |
|
1366 |
tswap32s(&ldt_info.entry_number); |
|
1367 |
tswapls((long *)&ldt_info.base_addr); |
|
1368 |
tswap32s(&ldt_info.limit); |
|
1369 |
tswap32s(&ldt_info.flags); |
|
1477 |
lock_user_struct(target_ldt_info, ptr, 1); |
|
1478 |
ldt_info.entry_number = tswap32(target_ldt_info->entry_number); |
|
1479 |
ldt_info.base_addr = tswapl(target_ldt_info->base_addr); |
|
1480 |
ldt_info.limit = tswap32(target_ldt_info->limit); |
|
1481 |
ldt_info.flags = tswap32(target_ldt_info->flags); |
|
1482 |
unlock_user_struct(target_ldt_info, ptr, 0); |
|
1370 | 1483 |
|
1371 | 1484 |
if (ldt_info.entry_number >= TARGET_LDT_ENTRIES) |
1372 | 1485 |
return -EINVAL; |
... | ... | |
1389 | 1502 |
if (!ldt_table) |
1390 | 1503 |
return -ENOMEM; |
1391 | 1504 |
memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); |
1392 |
env->ldt.base = (long)ldt_table;
|
|
1505 |
env->ldt.base = h2g(ldt_table);
|
|
1393 | 1506 |
env->ldt.limit = 0xffff; |
1394 | 1507 |
} |
1395 | 1508 |
|
... | ... | |
1432 | 1545 |
} |
1433 | 1546 |
|
1434 | 1547 |
/* specific and weird i386 syscalls */ |
1435 |
int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
|
|
1548 |
int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount)
|
|
1436 | 1549 |
{ |
1437 | 1550 |
int ret = -ENOSYS; |
1438 | 1551 |
|
... | ... | |
1523 | 1636 |
return ret; |
1524 | 1637 |
} |
1525 | 1638 |
|
1526 |
static long do_fcntl(int fd, int cmd, unsigned long arg)
|
|
1639 |
static long do_fcntl(int fd, int cmd, target_ulong arg)
|
|
1527 | 1640 |
{ |
1528 | 1641 |
struct flock fl; |
1529 |
struct target_flock *target_fl = (void *)arg;
|
|
1642 |
struct target_flock *target_fl; |
|
1530 | 1643 |
long ret; |
1531 |
|
|
1644 |
|
|
1532 | 1645 |
switch(cmd) { |
1533 | 1646 |
case TARGET_F_GETLK: |
1534 | 1647 |
ret = fcntl(fd, cmd, &fl); |
1535 | 1648 |
if (ret == 0) { |
1649 |
lock_user_struct(target_fl, arg, 0); |
|
1536 | 1650 |
target_fl->l_type = tswap16(fl.l_type); |
1537 | 1651 |
target_fl->l_whence = tswap16(fl.l_whence); |
1538 | 1652 |
target_fl->l_start = tswapl(fl.l_start); |
1539 | 1653 |
target_fl->l_len = tswapl(fl.l_len); |
1540 | 1654 |
target_fl->l_pid = tswapl(fl.l_pid); |
1655 |
unlock_user_struct(target_fl, arg, 1); |
|
1541 | 1656 |
} |
1542 | 1657 |
break; |
1543 | 1658 |
|
1544 | 1659 |
case TARGET_F_SETLK: |
1545 | 1660 |
case TARGET_F_SETLKW: |
1661 |
lock_user_struct(target_fl, arg, 1); |
|
1546 | 1662 |
fl.l_type = tswap16(target_fl->l_type); |
1547 | 1663 |
fl.l_whence = tswap16(target_fl->l_whence); |
1548 | 1664 |
fl.l_start = tswapl(target_fl->l_start); |
1549 | 1665 |
fl.l_len = tswapl(target_fl->l_len); |
1550 | 1666 |
fl.l_pid = tswapl(target_fl->l_pid); |
1667 |
unlock_user_struct(target_fl, arg, 0); |
|
1551 | 1668 |
ret = fcntl(fd, cmd, &fl); |
1552 | 1669 |
break; |
1553 | 1670 |
|
... | ... | |
1690 | 1807 |
} |
1691 | 1808 |
#endif |
1692 | 1809 |
|
1810 |
static inline void target_to_host_timespec(struct timespec *host_ts, |
|
1811 |
target_ulong target_addr) |
|
1812 |
{ |
|
1813 |
struct target_timespec *target_ts; |
|
1814 |
|
|
1815 |
lock_user_struct(target_ts, target_addr, 1); |
|
1816 |
host_ts->tv_sec = tswapl(target_ts->tv_sec); |
|
1817 |
host_ts->tv_nsec = tswapl(target_ts->tv_nsec); |
|
1818 |
unlock_user_struct(target_ts, target_addr, 0); |
|
1819 |
} |
|
1820 |
|
|
1821 |
static inline void host_to_target_timespec(target_ulong target_addr, |
|
1822 |
struct timespec *host_ts) |
|
1823 |
{ |
|
1824 |
struct target_timespec *target_ts; |
|
1825 |
|
|
1826 |
lock_user_struct(target_ts, target_addr, 0); |
|
1827 |
target_ts->tv_sec = tswapl(host_ts->tv_sec); |
|
1828 |
target_ts->tv_nsec = tswapl(host_ts->tv_nsec); |
|
1829 |
unlock_user_struct(target_ts, target_addr, 1); |
|
1830 |
} |
|
1831 |
|
|
1693 | 1832 |
long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
1694 | 1833 |
long arg4, long arg5, long arg6) |
1695 | 1834 |
{ |
1696 | 1835 |
long ret; |
1697 | 1836 |
struct stat st; |
1698 | 1837 |
struct statfs stfs; |
1838 |
void *p; |
|
1699 | 1839 |
|
1700 | 1840 |
#ifdef DEBUG |
1701 | 1841 |
gemu_log("syscall %d", num); |
... | ... | |
1711 | 1851 |
ret = 0; /* avoid warning */ |
1712 | 1852 |
break; |
1713 | 1853 |
case TARGET_NR_read: |
1714 |
page_unprotect_range((void *)arg2, arg3); |
|
1715 |
ret = get_errno(read(arg1, (void *)arg2, arg3)); |
|
1854 |
page_unprotect_range(arg2, arg3); |
|
1855 |
p = lock_user(arg2, arg3, 0); |
|
1856 |
ret = get_errno(read(arg1, p, arg3)); |
|
1857 |
unlock_user(p, arg2, ret); |
|
1716 | 1858 |
break; |
1717 | 1859 |
case TARGET_NR_write: |
1718 |
ret = get_errno(write(arg1, (void *)arg2, arg3)); |
|
1860 |
p = lock_user(arg2, arg3, 1); |
|
1861 |
ret = get_errno(write(arg1, p, arg3)); |
|
1862 |
unlock_user(p, arg2, 0); |
|
1719 | 1863 |
break; |
1720 | 1864 |
case TARGET_NR_open: |
1721 |
ret = get_errno(open(path((const char *)arg1), |
|
1865 |
p = lock_user_string(arg1); |
|
1866 |
ret = get_errno(open(path(p), |
|
1722 | 1867 |
target_to_host_bitmask(arg2, fcntl_flags_tbl), |
1723 | 1868 |
arg3)); |
1869 |
unlock_user(p, arg1, 0); |
|
1724 | 1870 |
break; |
1725 | 1871 |
case TARGET_NR_close: |
1726 | 1872 |
ret = get_errno(close(arg1)); |
1727 | 1873 |
break; |
1728 | 1874 |
case TARGET_NR_brk: |
1729 |
ret = do_brk((char *)arg1);
|
|
1875 |
ret = do_brk(arg1); |
|
1730 | 1876 |
break; |
1731 | 1877 |
case TARGET_NR_fork: |
1732 | 1878 |
ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); |
1733 | 1879 |
break; |
1734 | 1880 |
case TARGET_NR_waitpid: |
1735 | 1881 |
{ |
1736 |
int *status = (int *)arg2;
|
|
1737 |
ret = get_errno(waitpid(arg1, status, arg3)); |
|
1738 |
if (!is_error(ret) && status)
|
|
1739 |
tswapls((long *)&status);
|
|
1882 |
int status;
|
|
1883 |
ret = get_errno(waitpid(arg1, &status, arg3));
|
|
1884 |
if (!is_error(ret) && arg2)
|
|
1885 |
tput32(arg2, status);
|
|
1740 | 1886 |
} |
1741 | 1887 |
break; |
1742 | 1888 |
case TARGET_NR_creat: |
1743 |
ret = get_errno(creat((const char *)arg1, arg2)); |
|
1889 |
p = lock_user_string(arg1); |
|
1890 |
ret = get_errno(creat(p, arg2)); |
|
1891 |
unlock_user(p, arg1, 0); |
|
1744 | 1892 |
break; |
1745 | 1893 |
case TARGET_NR_link: |
1746 |
ret = get_errno(link((const char *)arg1, (const char *)arg2)); |
|
1894 |
{ |
|
1895 |
void * p2; |
|
1896 |
p = lock_user_string(arg1); |
|
1897 |
p2 = lock_user_string(arg2); |
|
1898 |
ret = get_errno(link(p, p2)); |
|
1899 |
unlock_user(p2, arg2, 0); |
|
1900 |
unlock_user(p, arg1, 0); |
|
1901 |
} |
|
1747 | 1902 |
break; |
1748 | 1903 |
case TARGET_NR_unlink: |
1749 |
ret = get_errno(unlink((const char *)arg1)); |
|
1904 |
p = lock_user_string(arg1); |
|
1905 |
ret = get_errno(unlink(p)); |
|
1906 |
unlock_user(p, arg1, 0); |
|
1750 | 1907 |
break; |
1751 | 1908 |
case TARGET_NR_execve: |
1752 | 1909 |
{ |
1753 | 1910 |
char **argp, **envp; |
1754 | 1911 |
int argc, envc; |
1755 |
uint32_t *p; |
|
1912 |
target_ulong gp; |
|
1913 |
target_ulong guest_argp; |
|
1914 |
target_ulong guest_envp; |
|
1915 |
target_ulong addr; |
|
1756 | 1916 |
char **q; |
1757 | 1917 |
|
1758 | 1918 |
argc = 0; |
1759 |
for (p = (void *)arg2; *p; p++) |
|
1919 |
guest_argp = arg2; |
|
1920 |
for (gp = guest_argp; tgetl(gp); gp++) |
|
1760 | 1921 |
argc++; |
1761 | 1922 |
envc = 0; |
1762 |
for (p = (void *)arg3; *p; p++) |
|
1923 |
guest_envp = arg3; |
|
1924 |
for (gp = guest_envp; tgetl(gp); gp++) |
|
1763 | 1925 |
envc++; |
1764 | 1926 |
|
1765 | 1927 |
argp = alloca((argc + 1) * sizeof(void *)); |
1766 | 1928 |
envp = alloca((envc + 1) * sizeof(void *)); |
1767 | 1929 |
|
1768 |
for (p = (void *)arg2, q = argp; *p; p++, q++) |
|
1769 |
*q = (void *)tswap32(*p); |
|
1930 |
for (gp = guest_argp, q = argp; ; |
|
1931 |
gp += sizeof(target_ulong), q++) { |
|
1932 |
addr = tgetl(gp); |
|
1933 |
if (!addr) |
|
1934 |
break; |
|
1935 |
*q = lock_user_string(addr); |
|
1936 |
} |
|
1770 | 1937 |
*q = NULL; |
1771 | 1938 |
|
1772 |
for (p = (void *)arg3, q = envp; *p; p++, q++) |
|
1773 |
*q = (void *)tswap32(*p); |
|
1939 |
for (gp = guest_envp, q = envp; ; |
|
1940 |
gp += sizeof(target_ulong), q++) { |
|
1941 |
addr = tgetl(gp); |
|
1942 |
if (!addr) |
|
1943 |
break; |
|
1944 |
*q = lock_user_string(addr); |
|
1945 |
} |
|
1774 | 1946 |
*q = NULL; |
1775 | 1947 |
|
1776 |
ret = get_errno(execve((const char *)arg1, argp, envp)); |
|
1948 |
p = lock_user_string(arg1); |
|
1949 |
ret = get_errno(execve(p, argp, envp)); |
|
1950 |
unlock_user(p, arg1, 0); |
|
1951 |
|
|
1952 |
for (gp = guest_argp, q = argp; *q; |
|
1953 |
gp += sizeof(target_ulong), q++) { |
|
1954 |
addr = tgetl(gp); |
|
1955 |
unlock_user(*q, addr, 0); |
|
1956 |
} |
|
1957 |
for (gp = guest_envp, q = envp; *q; |
|
1958 |
gp += sizeof(target_ulong), q++) { |
|
1959 |
addr = tgetl(gp); |
|
1960 |
unlock_user(*q, addr, 0); |
|
1961 |
} |
|
1777 | 1962 |
} |
1778 | 1963 |
break; |
1779 | 1964 |
case TARGET_NR_chdir: |
1780 |
ret = get_errno(chdir((const char *)arg1)); |
|
1965 |
p = lock_user_string(arg1); |
|
1966 |
ret = get_errno(chdir(p)); |
|
1967 |
unlock_user(p, arg1, 0); |
|
1781 | 1968 |
break; |
1782 | 1969 |
#ifdef TARGET_NR_time |
1783 | 1970 |
case TARGET_NR_time: |
1784 | 1971 |
{ |
1785 |
int *time_ptr = (int *)arg1;
|
|
1786 |
ret = get_errno(time((time_t *)time_ptr));
|
|
1787 |
if (!is_error(ret) && time_ptr)
|
|
1788 |
tswap32s(time_ptr);
|
|
1972 |
time_t host_time;
|
|
1973 |
ret = get_errno(time(&host_time));
|
|
1974 |
if (!is_error(ret) && arg1)
|
|
1975 |
tputl(arg1, host_time);
|
|
1789 | 1976 |
} |
1790 | 1977 |
break; |
1791 | 1978 |
#endif |
1792 | 1979 |
case TARGET_NR_mknod: |
1793 |
ret = get_errno(mknod((const char *)arg1, arg2, arg3)); |
|
1980 |
p = lock_user_string(arg1); |
|
1981 |
ret = get_errno(mknod(p, arg2, arg3)); |
|
1982 |
unlock_user(p, arg1, 0); |
|
1794 | 1983 |
break; |
1795 | 1984 |
case TARGET_NR_chmod: |
1796 |
ret = get_errno(chmod((const char *)arg1, arg2)); |
|
1985 |
p = lock_user_string(arg1); |
|
1986 |
ret = get_errno(chmod(p, arg2)); |
|
1987 |
unlock_user(p, arg1, 0); |
|
1797 | 1988 |
break; |
1798 | 1989 |
#ifdef TARGET_NR_break |
1799 | 1990 |
case TARGET_NR_break: |
... | ... | |
1813 | 2004 |
/* need to look at the data field */ |
1814 | 2005 |
goto unimplemented; |
1815 | 2006 |
case TARGET_NR_umount: |
1816 |
ret = get_errno(umount((const char *)arg1)); |
|
2007 |
p = lock_user_string(arg1); |
|
2008 |
ret = get_errno(umount(p)); |
|
2009 |
unlock_user(p, arg1, 0); |
|
1817 | 2010 |
break; |
1818 | 2011 |
case TARGET_NR_stime: |
1819 | 2012 |
{ |
1820 |
int *time_ptr = (int *)arg1; |
|
1821 |
if (time_ptr) |
|
1822 |
tswap32s(time_ptr); |
|
1823 |
ret = get_errno(stime((time_t *)time_ptr)); |
|
2013 |
time_t host_time; |
|
2014 |
host_time = tgetl(arg1); |
|
2015 |
ret = get_errno(stime(&host_time)); |
|
1824 | 2016 |
} |
1825 | 2017 |
break; |
1826 | 2018 |
case TARGET_NR_ptrace: |
... | ... | |
1837 | 2029 |
break; |
1838 | 2030 |
case TARGET_NR_utime: |
1839 | 2031 |
{ |
1840 |
struct utimbuf tbuf, *tbuf1; |
|
1841 |
struct target_utimbuf *target_tbuf = (void *)arg2; |
|
1842 |
if (target_tbuf) { |
|
1843 |
get_user(tbuf.actime, &target_tbuf->actime); |
|
1844 |
get_user(tbuf.modtime, &target_tbuf->modtime); |
|
1845 |
tbuf1 = &tbuf; |
|
2032 |
struct utimbuf tbuf, *host_tbuf; |
|
2033 |
struct target_utimbuf *target_tbuf; |
|
2034 |
if (arg2) { |
|
2035 |
lock_user_struct(target_tbuf, arg2, 1); |
|
2036 |
tbuf.actime = tswapl(target_tbuf->actime); |
|
2037 |
tbuf.modtime = tswapl(target_tbuf->modtime); |
|
2038 |
unlock_user_struct(target_tbuf, arg2, 0); |
|
2039 |
host_tbuf = &tbuf; |
|
1846 | 2040 |
} else { |
1847 |
tbuf1 = NULL;
|
|
2041 |
host_tbuf = NULL;
|
|
1848 | 2042 |
} |
1849 |
ret = get_errno(utime((const char *)arg1, tbuf1)); |
|
2043 |
p = lock_user_string(arg1); |
|
2044 |
ret = get_errno(utime(p, host_tbuf)); |
|
2045 |
unlock_user(p, arg1, 0); |
|
1850 | 2046 |
} |
1851 | 2047 |
break; |
1852 | 2048 |
case TARGET_NR_utimes: |
1853 | 2049 |
{ |
1854 |
struct target_timeval *target_tvp = (struct target_timeval *)arg2; |
|
1855 | 2050 |
struct timeval *tvp, tv[2]; |
1856 |
if (target_tvp) { |
|
1857 |
target_to_host_timeval(&tv[0], &target_tvp[0]); |
|
1858 |
target_to_host_timeval(&tv[1], &target_tvp[1]); |
|
2051 |
if (arg2) { |
|
2052 |
target_to_host_timeval(&tv[0], arg2); |
|
2053 |
target_to_host_timeval(&tv[1], |
|
2054 |
arg2 + sizeof (struct target_timeval)); |
|
1859 | 2055 |
tvp = tv; |
1860 | 2056 |
} else { |
1861 | 2057 |
tvp = NULL; |
1862 | 2058 |
} |
1863 |
ret = get_errno(utimes((const char *)arg1, tvp)); |
|
2059 |
p = lock_user_string(arg1); |
|
2060 |
ret = get_errno(utimes(p, tvp)); |
|
2061 |
unlock_user(p, arg1, 0); |
|
1864 | 2062 |
} |
1865 | 2063 |
break; |
1866 | 2064 |
#ifdef TARGET_NR_stty |
... | ... | |
1872 | 2070 |
goto unimplemented; |
1873 | 2071 |
#endif |
1874 | 2072 |
case TARGET_NR_access: |
1875 |
ret = get_errno(access((const char *)arg1, arg2)); |
|
2073 |
p = lock_user_string(arg1); |
|
2074 |
ret = get_errno(access(p, arg2)); |
|
2075 |
unlock_user(p, arg1, 0); |
|
1876 | 2076 |
break; |
1877 | 2077 |
case TARGET_NR_nice: |
1878 | 2078 |
ret = get_errno(nice(arg1)); |
... | ... | |
1889 | 2089 |
ret = get_errno(kill(arg1, arg2)); |
1890 | 2090 |
break; |
1891 | 2091 |
case TARGET_NR_rename: |
1892 |
ret = get_errno(rename((const char *)arg1, (const char *)arg2)); |
|
2092 |
{ |
|
2093 |
void *p2; |
|
2094 |
p = lock_user_string(arg1); |
|
2095 |
p2 = lock_user_string(arg2); |
|
2096 |
ret = get_errno(rename(p, p2)); |
|
2097 |
unlock_user(p2, arg2, 0); |
|
2098 |
unlock_user(p, arg1, 0); |
|
2099 |
} |
|
1893 | 2100 |
break; |
1894 | 2101 |
case TARGET_NR_mkdir: |
1895 |
ret = get_errno(mkdir((const char *)arg1, arg2)); |
|
2102 |
p = lock_user_string(arg1); |
|
2103 |
ret = get_errno(mkdir(p, arg2)); |
|
2104 |
unlock_user(p, arg1, 0); |
|
1896 | 2105 |
break; |
1897 | 2106 |
case TARGET_NR_rmdir: |
1898 |
ret = get_errno(rmdir((const char *)arg1)); |
|
2107 |
p = lock_user_string(arg1); |
|
2108 |
ret = get_errno(rmdir(p)); |
|
2109 |
unlock_user(p, arg1, 0); |
|
1899 | 2110 |
break; |
1900 | 2111 |
case TARGET_NR_dup: |
1901 | 2112 |
ret = get_errno(dup(arg1)); |
1902 | 2113 |
break; |
1903 | 2114 |
case TARGET_NR_pipe: |
1904 | 2115 |
{ |
1905 |
int *pipe_ptr = (int *)arg1;
|
|
1906 |
ret = get_errno(pipe(pipe_ptr));
|
|
2116 |
int host_pipe[2];
|
|
2117 |
ret = get_errno(pipe(host_pipe));
|
|
1907 | 2118 |
if (!is_error(ret)) { |
1908 |
tswap32s(&pipe_ptr[0]);
|
|
1909 |
tswap32s(&pipe_ptr[1]);
|
|
2119 |
tput32(arg1, host_pipe[0]);
|
|
2120 |
tput32(arg1 + 4, host_pipe[1]);
|
|
1910 | 2121 |
} |
1911 | 2122 |
} |
1912 | 2123 |
break; |
1913 | 2124 |
case TARGET_NR_times: |
1914 | 2125 |
{ |
1915 |
struct target_tms *tmsp = (void *)arg1;
|
|
2126 |
struct target_tms *tmsp; |
|
1916 | 2127 |
struct tms tms; |
1917 | 2128 |
ret = get_errno(times(&tms)); |
1918 |
if (tmsp) { |
|
2129 |
if (arg1) { |
|
2130 |
tmsp = lock_user(arg1, sizeof(struct target_tms), 0); |
|
1919 | 2131 |
tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime)); |
1920 | 2132 |
tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime)); |
1921 | 2133 |
tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime)); |
... | ... | |
1935 | 2147 |
case TARGET_NR_acct: |
1936 | 2148 |
goto unimplemented; |
1937 | 2149 |
case TARGET_NR_umount2: |
1938 |
ret = get_errno(umount2((const char *)arg1, arg2)); |
|
2150 |
p = lock_user_string(arg1); |
|
2151 |
ret = get_errno(umount2(p, arg2)); |
|
2152 |
unlock_user(p, arg1, 0); |
|
1939 | 2153 |
break; |
1940 | 2154 |
#ifdef TARGET_NR_lock |
1941 | 2155 |
case TARGET_NR_lock: |
... | ... | |
1966 | 2180 |
ret = get_errno(umask(arg1)); |
1967 | 2181 |
break; |
1968 | 2182 |
case TARGET_NR_chroot: |
1969 |
ret = get_errno(chroot((const char *)arg1)); |
|
2183 |
p = lock_user_string(arg1); |
|
2184 |
ret = get_errno(chroot(p)); |
|
2185 |
unlock_user(p, arg1, 0); |
|
1970 | 2186 |
break; |
1971 | 2187 |
case TARGET_NR_ustat: |
1972 | 2188 |
goto unimplemented; |
... | ... | |
1984 | 2200 |
break; |
1985 | 2201 |
case TARGET_NR_sigaction: |
1986 | 2202 |
{ |
1987 |
struct target_old_sigaction *old_act = (void *)arg2; |
|
1988 |
struct target_old_sigaction *old_oact = (void *)arg3; |
|
2203 |
struct target_old_sigaction *old_act; |
|
1989 | 2204 |
struct target_sigaction act, oact, *pact; |
1990 |
if (old_act) { |
|
2205 |
if (arg2) { |
|
2206 |
lock_user_struct(old_act, arg2, 1); |
|
1991 | 2207 |
act._sa_handler = old_act->_sa_handler; |
1992 | 2208 |
target_siginitset(&act.sa_mask, old_act->sa_mask); |
1993 | 2209 |
act.sa_flags = old_act->sa_flags; |
1994 | 2210 |
act.sa_restorer = old_act->sa_restorer; |
2211 |
unlock_user_struct(old_act, arg2, 0); |
|
1995 | 2212 |
pact = &act; |
1996 | 2213 |
} else { |
1997 | 2214 |
pact = NULL; |
1998 | 2215 |
} |
1999 | 2216 |
ret = get_errno(do_sigaction(arg1, pact, &oact)); |
2000 |
if (!is_error(ret) && old_oact) { |
|
2001 |
old_oact->_sa_handler = oact._sa_handler; |
|
2002 |
old_oact->sa_mask = oact.sa_mask.sig[0]; |
|
2003 |
old_oact->sa_flags = oact.sa_flags; |
|
2004 |
old_oact->sa_restorer = oact.sa_restorer; |
|
2217 |
if (!is_error(ret) && arg3) { |
|
2218 |
lock_user_struct(old_act, arg3, 0); |
|
2219 |
old_act->_sa_handler = oact._sa_handler; |
|
2220 |
old_act->sa_mask = oact.sa_mask.sig[0]; |
|
2221 |
old_act->sa_flags = oact.sa_flags; |
|
2222 |
old_act->sa_restorer = oact.sa_restorer; |
|
2223 |
unlock_user_struct(old_act, arg3, 1); |
|
2005 | 2224 |
} |
2006 | 2225 |
} |
2007 | 2226 |
break; |
2008 | 2227 |
case TARGET_NR_rt_sigaction: |
2009 |
ret = get_errno(do_sigaction(arg1, (void *)arg2, (void *)arg3)); |
|
2228 |
{ |
|
2229 |
struct target_sigaction *act; |
|
2230 |
struct target_sigaction *oact; |
|
2231 |
|
|
2232 |
if (arg2) |
|
2233 |
lock_user_struct(act, arg2, 1); |
|
2234 |
else |
|
2235 |
act = NULL; |
|
2236 |
if (arg3) |
|
2237 |
lock_user_struct(oact, arg3, 0); |
|
2238 |
else |
|
2239 |
oact = NULL; |
|
2240 |
ret = get_errno(do_sigaction(arg1, act, oact)); |
|
2241 |
if (arg2) |
|
2242 |
unlock_user_struct(act, arg2, 0); |
|
2243 |
if (arg3) |
|
2244 |
unlock_user_struct(oact, arg3, 1); |
|
2245 |
} |
|
2010 | 2246 |
break; |
2011 | 2247 |
case TARGET_NR_sgetmask: |
2012 | 2248 |
{ |
... | ... | |
2033 | 2269 |
{ |
2034 | 2270 |
int how = arg1; |
2035 | 2271 |
sigset_t set, oldset, *set_ptr; |
2036 |
target_ulong *pset = (void *)arg2, *poldset = (void *)arg3; |
|
2037 | 2272 |
|
2038 |
if (pset) {
|
|
2273 |
if (arg2) {
|
|
2039 | 2274 |
switch(how) { |
2040 | 2275 |
case TARGET_SIG_BLOCK: |
2041 | 2276 |
how = SIG_BLOCK; |
... | ... | |
2050 | 2285 |
ret = -EINVAL; |
2051 | 2286 |
goto fail; |
2052 | 2287 |
} |
2053 |
target_to_host_old_sigset(&set, pset); |
|
2288 |
p = lock_user(arg2, sizeof(target_sigset_t), 1); |
|
2289 |
target_to_host_old_sigset(&set, p); |
|
2290 |
unlock_user(p, arg2, 0); |
|
2054 | 2291 |
set_ptr = &set; |
2055 | 2292 |
} else { |
2056 | 2293 |
how = 0; |
2057 | 2294 |
set_ptr = NULL; |
2058 | 2295 |
} |
2059 | 2296 |
ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); |
2060 |
if (!is_error(ret) && poldset) { |
|
2061 |
host_to_target_old_sigset(poldset, &oldset); |
|
2297 |
if (!is_error(ret) && arg3) { |
|
2298 |
p = lock_user(arg3, sizeof(target_sigset_t), 0); |
|
2299 |
host_to_target_old_sigset(p, &oldset); |
|
2300 |
unlock_user(p, arg3, sizeof(target_sigset_t)); |
|
2062 | 2301 |
} |
2063 | 2302 |
} |
2064 | 2303 |
break; |
... | ... | |
2066 | 2305 |
{ |
2067 | 2306 |
int how = arg1; |
2068 | 2307 |
sigset_t set, oldset, *set_ptr; |
2069 |
target_sigset_t *pset = (void *)arg2; |
|
2070 |
target_sigset_t *poldset = (void *)arg3; |
|
2071 | 2308 |
|
2072 |
if (pset) {
|
|
2309 |
if (arg2) {
|
|
2073 | 2310 |
switch(how) { |
2074 | 2311 |
case TARGET_SIG_BLOCK: |
2075 | 2312 |
how = SIG_BLOCK; |
... | ... | |
2084 | 2321 |
ret = -EINVAL; |
2085 | 2322 |
goto fail; |
2086 | 2323 |
} |
2087 |
target_to_host_sigset(&set, pset); |
|
2324 |
p = lock_user(arg2, sizeof(target_sigset_t), 1); |
|
2325 |
target_to_host_sigset(&set, p); |
|
2326 |
unlock_user(p, arg2, 0); |
|
2088 | 2327 |
set_ptr = &set; |
2089 | 2328 |
} else { |
2090 | 2329 |
how = 0; |
2091 | 2330 |
set_ptr = NULL; |
2092 | 2331 |
} |
2093 | 2332 |
ret = get_errno(sigprocmask(how, set_ptr, &oldset)); |
2094 |
if (!is_error(ret) && poldset) { |
|
2095 |
host_to_target_sigset(poldset, &oldset); |
|
2333 |
if (!is_error(ret) && arg3) { |
|
2334 |
p = lock_user(arg3, sizeof(target_sigset_t), 0); |
|
2335 |
host_to_target_sigset(p, &oldset); |
|
2336 |
unlock_user(p, arg3, sizeof(target_sigset_t)); |
|
2096 | 2337 |
} |
2097 | 2338 |
} |
2098 | 2339 |
break; |
... | ... | |
2101 | 2342 |
sigset_t set; |
2102 | 2343 |
ret = get_errno(sigpending(&set)); |
2103 | 2344 |
if (!is_error(ret)) { |
2104 |
host_to_target_old_sigset((target_ulong *)arg1, &set); |
|
2345 |
p = lock_user(arg1, sizeof(target_sigset_t), 0); |
|
2346 |
host_to_target_old_sigset(p, &set); |
|
2347 |
unlock_user(p, arg1, sizeof(target_sigset_t)); |
|
2105 | 2348 |
} |
2106 | 2349 |
} |
2107 | 2350 |
break; |
... | ... | |
2110 | 2353 |
sigset_t set; |
2111 | 2354 |
ret = get_errno(sigpending(&set)); |
2112 | 2355 |
if (!is_error(ret)) { |
2113 |
host_to_target_sigset((target_sigset_t *)arg1, &set); |
|
2356 |
p = lock_user(arg1, sizeof(target_sigset_t), 0); |
|
2357 |
host_to_target_sigset(p, &set); |
|
2358 |
unlock_user(p, arg1, sizeof(target_sigset_t)); |
|
2114 | 2359 |
} |
2115 | 2360 |
} |
2116 | 2361 |
break; |
2117 | 2362 |
case TARGET_NR_sigsuspend: |
2118 | 2363 |
{ |
2119 | 2364 |
sigset_t set; |
2120 |
target_to_host_old_sigset(&set, (target_ulong *)arg1); |
|
2365 |
p = lock_user(arg1, sizeof(target_sigset_t), 1); |
|
2366 |
target_to_host_old_sigset(&set, p); |
|
2367 |
unlock_user(p, arg1, 0); |
|
2121 | 2368 |
ret = get_errno(sigsuspend(&set)); |
2122 | 2369 |
} |
2123 | 2370 |
break; |
2124 | 2371 |
case TARGET_NR_rt_sigsuspend: |
2125 | 2372 |
{ |
2126 | 2373 |
sigset_t set; |
2127 |
target_to_host_sigset(&set, (target_sigset_t *)arg1); |
|
2374 |
p = lock_user(arg1, sizeof(target_sigset_t), 1); |
|
2375 |
target_to_host_sigset(&set, p); |
|
2376 |
unlock_user(p, arg1, 0); |
|
2128 | 2377 |
ret = get_errno(sigsuspend(&set)); |
2129 | 2378 |
} |
2130 | 2379 |
break; |
2131 | 2380 |
case TARGET_NR_rt_sigtimedwait: |
2132 | 2381 |
{ |
2133 |
target_sigset_t *target_set = (void *)arg1; |
|
2134 |
target_siginfo_t *target_uinfo = (void *)arg2; |
|
2135 |
struct target_timespec *target_uts = (void *)arg3; |
|
2136 | 2382 |
sigset_t set; |
2137 | 2383 |
struct timespec uts, *puts; |
2138 | 2384 |
siginfo_t uinfo; |
2139 | 2385 |
|
2140 |
target_to_host_sigset(&set, target_set); |
|
2141 |
if (target_uts) { |
|
2386 |
p = lock_user(arg1, sizeof(target_sigset_t), 1); |
|
2387 |
target_to_host_sigset(&set, p); |
|
2388 |
unlock_user(p, arg1, 0); |
|
2389 |
if (arg3) { |
|
2142 | 2390 |
puts = &uts; |
2143 |
puts->tv_sec = tswapl(target_uts->tv_sec); |
|
2144 |
puts->tv_nsec = tswapl(target_uts->tv_nsec); |
|
2391 |
target_to_host_timespec(puts, arg3); |
|
2145 | 2392 |
} else { |
2146 | 2393 |
puts = NULL; |
2147 | 2394 |
} |
2148 | 2395 |
ret = get_errno(sigtimedwait(&set, &uinfo, puts)); |
2149 |
if (!is_error(ret) && target_uinfo) { |
|
2150 |
host_to_target_siginfo(target_uinfo, &uinfo); |
|
2396 |
if (!is_error(ret) && arg2) { |
|
2397 |
p = lock_user(arg2, sizeof(target_sigset_t), 0); |
|
2398 |
host_to_target_siginfo(p, &uinfo); |
|
2399 |
unlock_user(p, arg2, sizeof(target_sigset_t)); |
|
2151 | 2400 |
} |
2152 | 2401 |
} |
2153 | 2402 |
break; |
2154 | 2403 |
case TARGET_NR_rt_sigqueueinfo: |
2155 | 2404 |
{ |
2156 | 2405 |
siginfo_t uinfo; |
2157 |
target_to_host_siginfo(&uinfo, (target_siginfo_t *)arg3); |
|
2406 |
p = lock_user(arg3, sizeof(target_sigset_t), 1); |
|
2407 |
target_to_host_siginfo(&uinfo, p); |
|
2408 |
unlock_user(p, arg1, 0); |
|
2158 | 2409 |
ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); |
2159 | 2410 |
} |
2160 | 2411 |
break; |
... | ... | |
2167 | 2418 |
ret = do_rt_sigreturn(cpu_env); |
2168 | 2419 |
break; |
2169 | 2420 |
case TARGET_NR_sethostname: |
2170 |
ret = get_errno(sethostname((const char *)arg1, arg2)); |
|
2421 |
p = lock_user_string(arg1); |
|
2422 |
ret = get_errno(sethostname(p, arg2)); |
|
2423 |
unlock_user(p, arg1, 0); |
|
2171 | 2424 |
break; |
2172 | 2425 |
case TARGET_NR_setrlimit: |
2173 | 2426 |
{ |
2174 | 2427 |
/* XXX: convert resource ? */ |
2175 | 2428 |
int resource = arg1; |
2176 |
struct target_rlimit *target_rlim = (void *)arg2;
|
|
2429 |
struct target_rlimit *target_rlim; |
|
2177 | 2430 |
struct rlimit rlim; |
2431 |
lock_user_struct(target_rlim, arg2, 1); |
|
2178 | 2432 |
rlim.rlim_cur = tswapl(target_rlim->rlim_cur); |
2179 | 2433 |
rlim.rlim_max = tswapl(target_rlim->rlim_max); |
2434 |
unlock_user_struct(target_rlim, arg2, 0); |
|
2180 | 2435 |
ret = get_errno(setrlimit(resource, &rlim)); |
2181 | 2436 |
} |
2182 | 2437 |
break; |
... | ... | |
2184 | 2439 |
{ |
2185 | 2440 |
/* XXX: convert resource ? */ |
2186 | 2441 |
int resource = arg1; |
2187 |
struct target_rlimit *target_rlim = (void *)arg2;
|
|
2442 |
struct target_rlimit *target_rlim; |
|
2188 | 2443 |
struct rlimit rlim; |
2189 | 2444 |
|
2190 | 2445 |
ret = get_errno(getrlimit(resource, &rlim)); |
2191 | 2446 |
if (!is_error(ret)) { |
2192 |
target_rlim->rlim_cur = tswapl(rlim.rlim_cur); |
|
2193 |
target_rlim->rlim_max = tswapl(rlim.rlim_max); |
|
2447 |
lock_user_struct(target_rlim, arg2, 0); |
|
2448 |
rlim.rlim_cur = tswapl(target_rlim->rlim_cur); |
|
2449 |
rlim.rlim_max = tswapl(target_rlim->rlim_max); |
|
2450 |
unlock_user_struct(target_rlim, arg2, 1); |
|
2194 | 2451 |
} |
2195 | 2452 |
} |
2196 | 2453 |
break; |
2197 | 2454 |
case TARGET_NR_getrusage: |
2198 | 2455 |
{ |
2199 | 2456 |
struct rusage rusage; |
2200 |
struct target_rusage *target_rusage = (void *)arg2; |
|
2201 | 2457 |
ret = get_errno(getrusage(arg1, &rusage)); |
2202 | 2458 |
if (!is_error(ret)) { |
2203 |
host_to_target_rusage(target_rusage, &rusage);
|
|
2459 |
host_to_target_rusage(arg2, &rusage);
|
|
2204 | 2460 |
} |
2205 | 2461 |
} |
2206 | 2462 |
break; |
2207 | 2463 |
case TARGET_NR_gettimeofday: |
2208 | 2464 |
{ |
2209 |
struct target_timeval *target_tv = (void *)arg1; |
|
2210 | 2465 |
struct timeval tv; |
Also available in: Unified diff