syscall_emul.cc (11907:48a3d32da9d8) syscall_emul.cc (11908:2fd0307d03e9)
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 612 unchanged lines hidden (view full) ---

621 uid_t hostOwner = owner;
622 uint32_t group = p->getSyscallArg(tc, index);
623 gid_t hostGroup = group;
624
625 int result = fchown(sim_fd, hostOwner, hostGroup);
626 return (result == -1) ? -errno : result;
627}
628
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 612 unchanged lines hidden (view full) ---

621 uid_t hostOwner = owner;
622 uint32_t group = p->getSyscallArg(tc, index);
623 gid_t hostGroup = group;
624
625 int result = fchown(sim_fd, hostOwner, hostGroup);
626 return (result == -1) ? -errno : result;
627}
628
629
630/**
629/**
631 * TODO: there's a bit more involved here since file descriptors created with
632 * dup are supposed to share a file description. So, there is a problem with
633 * maintaining fields like file offset or flags since an update to such a
634 * field won't be reflected in the metadata for the fd entries that we
635 * maintain to hold metadata for checkpoint restoration.
630 * FIXME: The file description is not shared among file descriptors created
631 * with dup. Really, it's difficult to maintain fields like file offset or
632 * flags since an update to such a field won't be reflected in the metadata
633 * for the fd entries that we maintain for checkpoint restoration.
636 */
637SyscallReturn
638dupFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
639{
640 int index = 0;
641 int tgt_fd = p->getSyscallArg(tc, index);
642
643 auto old_hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
644 if (!old_hbfdp)
645 return -EBADF;
646 int sim_fd = old_hbfdp->getSimFD();
647
648 int result = dup(sim_fd);
634 */
635SyscallReturn
636dupFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
637{
638 int index = 0;
639 int tgt_fd = p->getSyscallArg(tc, index);
640
641 auto old_hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
642 if (!old_hbfdp)
643 return -EBADF;
644 int sim_fd = old_hbfdp->getSimFD();
645
646 int result = dup(sim_fd);
649 int local_errno = errno;
647 if (result == -1)
648 return -errno;
650
649
651 std::shared_ptr<FDEntry> new_fdep = old_hbfdp->clone();
652 auto new_hbfdp = std::dynamic_pointer_cast<HBFDEntry>(new_fdep);
650 auto new_hbfdp = std::dynamic_pointer_cast<HBFDEntry>(old_hbfdp->clone());
653 new_hbfdp->setSimFD(result);
651 new_hbfdp->setSimFD(result);
652 new_hbfdp->setCOE(false);
653 return p->fds->allocFD(new_hbfdp);
654}
654
655
655 return (result == -1) ? -local_errno : p->fds->allocFD(new_fdep);
656SyscallReturn
657dup2Func(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
658{
659 int index = 0;
660
661 int old_tgt_fd = p->getSyscallArg(tc, index);
662 auto old_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[old_tgt_fd]);
663 if (!old_hbp)
664 return -EBADF;
665 int old_sim_fd = old_hbp->getSimFD();
666
667 /**
668 * We need a valid host file descriptor number to be able to pass into
669 * the second parameter for dup2 (newfd), but we don't know what the
670 * viable numbers are; we execute the open call to retrieve one.
671 */
672 int res_fd = dup2(old_sim_fd, open("/dev/null", O_RDONLY));
673 if (res_fd == -1)
674 return -errno;
675
676 int new_tgt_fd = p->getSyscallArg(tc, index);
677 auto new_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[new_tgt_fd]);
678 if (new_hbp)
679 p->fds->closeFDEntry(new_tgt_fd);
680 new_hbp = std::dynamic_pointer_cast<HBFDEntry>(old_hbp->clone());
681 new_hbp->setSimFD(res_fd);
682 new_hbp->setCOE(false);
683
684 return p->fds->allocFD(new_hbp);
656}
657
658SyscallReturn
659fcntlFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
660{
661 int arg;
662 int index = 0;
663 int tgt_fd = p->getSyscallArg(tc, index);

--- 62 unchanged lines hidden (view full) ---

726 // not sure if this is totally valid, but we'll pass it through
727 // to the underlying OS
728 warn("fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd);
729 return fcntl(sim_fd, cmd);
730 }
731}
732
733SyscallReturn
685}
686
687SyscallReturn
688fcntlFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
689{
690 int arg;
691 int index = 0;
692 int tgt_fd = p->getSyscallArg(tc, index);

--- 62 unchanged lines hidden (view full) ---

755 // not sure if this is totally valid, but we'll pass it through
756 // to the underlying OS
757 warn("fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd);
758 return fcntl(sim_fd, cmd);
759 }
760}
761
762SyscallReturn
734pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process,
735 ThreadContext *tc)
763pipeImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc,
764 bool pseudoPipe)
736{
765{
766 Addr tgt_addr = 0;
767 if (!pseudoPipe) {
768 int index = 0;
769 tgt_addr = p->getSyscallArg(tc, index);
770 }
771
737 int sim_fds[2], tgt_fds[2];
738
739 int pipe_retval = pipe(sim_fds);
772 int sim_fds[2], tgt_fds[2];
773
774 int pipe_retval = pipe(sim_fds);
740 if (pipe_retval < 0)
741 return pipe_retval;
775 if (pipe_retval == -1)
776 return -errno;
742
743 auto rend = PipeFDEntry::EndType::read;
744 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
777
778 auto rend = PipeFDEntry::EndType::read;
779 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
780 tgt_fds[0] = p->fds->allocFD(rpfd);
745
746 auto wend = PipeFDEntry::EndType::write;
747 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
781
782 auto wend = PipeFDEntry::EndType::write;
783 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
784 tgt_fds[1] = p->fds->allocFD(wpfd);
748
785
749 tgt_fds[0] = process->fds->allocFD(rpfd);
750 tgt_fds[1] = process->fds->allocFD(wpfd);
751
752 /**
753 * Now patch the read object to record the target file descriptor chosen
754 * as the write end of the pipe.
755 */
756 rpfd->setPipeReadSource(tgt_fds[1]);
757
758 /**
759 * Alpha Linux convention for pipe() is that fd[0] is returned as
760 * the return value of the function, and fd[1] is returned in r20.
761 */
786 /**
787 * Now patch the read object to record the target file descriptor chosen
788 * as the write end of the pipe.
789 */
790 rpfd->setPipeReadSource(tgt_fds[1]);
791
792 /**
793 * Alpha Linux convention for pipe() is that fd[0] is returned as
794 * the return value of the function, and fd[1] is returned in r20.
795 */
762 tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]);
763 return sim_fds[0];
796 if (pseudoPipe) {
797 tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]);
798 return tgt_fds[0];
799 }
800
801 /**
802 * Copy the target file descriptors into buffer space and then copy
803 * the buffer space back into the target address space.
804 */
805 BufferArg tgt_handle(tgt_addr, sizeof(int[2]));
806 int *buf_ptr = (int*)tgt_handle.bufferPtr();
807 buf_ptr[0] = tgt_fds[0];
808 buf_ptr[1] = tgt_fds[1];
809 tgt_handle.copyOut(tc->getMemProxy());
810 return 0;
764}
765
766SyscallReturn
811}
812
813SyscallReturn
814pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process,
815 ThreadContext *tc)
816{
817 return pipeImpl(desc, callnum, process, tc, true);
818}
819
820SyscallReturn
821pipeFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
822{
823 return pipeImpl(desc, callnum, process, tc, false);
824}
825
826SyscallReturn
767setpgidFunc(SyscallDesc *desc, int callnum, Process *process,
768 ThreadContext *tc)
769{
770 int index = 0;
771 int pid = process->getSyscallArg(tc, index);
772 int pgid = process->getSyscallArg(tc, index);
773
774 if (pgid < 0)

--- 169 unchanged lines hidden ---
827setpgidFunc(SyscallDesc *desc, int callnum, Process *process,
828 ThreadContext *tc)
829{
830 int index = 0;
831 int pid = process->getSyscallArg(tc, index);
832 int pgid = process->getSyscallArg(tc, index);
833
834 if (pgid < 0)

--- 169 unchanged lines hidden ---