syscall_emul.cc (14124:9742fcde81e1) syscall_emul.cc (14129:7a41ca7e465c)
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;

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

861 // not sure if this is totally valid, but we'll pass it through
862 // to the underlying OS
863 warn("fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd);
864 return fcntl(sim_fd, cmd);
865 }
866}
867
868SyscallReturn
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;

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

861 // not sure if this is totally valid, but we'll pass it through
862 // to the underlying OS
863 warn("fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd);
864 return fcntl(sim_fd, cmd);
865 }
866}
867
868SyscallReturn
869pipeImpl(SyscallDesc *desc, int callnum, ThreadContext *tc, bool pseudoPipe)
869pipeImpl(SyscallDesc *desc, int callnum, ThreadContext *tc, bool pseudo_pipe,
870 bool is_pipe2)
870{
871 Addr tgt_addr = 0;
871{
872 Addr tgt_addr = 0;
873 int flags = 0;
872 auto p = tc->getProcessPtr();
874 auto p = tc->getProcessPtr();
873 if (!pseudoPipe) {
875 if (!pseudo_pipe) {
874 int index = 0;
875 tgt_addr = p->getSyscallArg(tc, index);
876 int index = 0;
877 tgt_addr = p->getSyscallArg(tc, index);
878 if (is_pipe2) {
879 flags = p->getSyscallArg(tc, index);
880 }
876 }
877
878 int sim_fds[2], tgt_fds[2];
879
880 int pipe_retval = pipe(sim_fds);
881 if (pipe_retval == -1)
882 return -errno;
883
884 auto rend = PipeFDEntry::EndType::read;
885 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
886 tgt_fds[0] = p->fds->allocFD(rpfd);
881 }
882
883 int sim_fds[2], tgt_fds[2];
884
885 int pipe_retval = pipe(sim_fds);
886 if (pipe_retval == -1)
887 return -errno;
888
889 auto rend = PipeFDEntry::EndType::read;
890 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
891 tgt_fds[0] = p->fds->allocFD(rpfd);
892 int sim_fd_rpfd = rpfd->getSimFD();
887
888 auto wend = PipeFDEntry::EndType::write;
889 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
890 tgt_fds[1] = p->fds->allocFD(wpfd);
893
894 auto wend = PipeFDEntry::EndType::write;
895 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
896 tgt_fds[1] = p->fds->allocFD(wpfd);
897 int sim_fd_wpfd = wpfd->getSimFD();
891
892 /**
893 * Now patch the read object to record the target file descriptor chosen
894 * as the write end of the pipe.
895 */
896 rpfd->setPipeReadSource(tgt_fds[1]);
897
898 /**
899 * Alpha Linux convention for pipe() is that fd[0] is returned as
900 * the return value of the function, and fd[1] is returned in r20.
901 */
898
899 /**
900 * Now patch the read object to record the target file descriptor chosen
901 * as the write end of the pipe.
902 */
903 rpfd->setPipeReadSource(tgt_fds[1]);
904
905 /**
906 * Alpha Linux convention for pipe() is that fd[0] is returned as
907 * the return value of the function, and fd[1] is returned in r20.
908 */
902 if (pseudoPipe) {
909 if (pseudo_pipe) {
903 tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]);
904 return tgt_fds[0];
905 }
906
907 /**
908 * Copy the target file descriptors into buffer space and then copy
909 * the buffer space back into the target address space.
910 */
911 BufferArg tgt_handle(tgt_addr, sizeof(int[2]));
912 int *buf_ptr = (int*)tgt_handle.bufferPtr();
913 buf_ptr[0] = tgt_fds[0];
914 buf_ptr[1] = tgt_fds[1];
915 tgt_handle.copyOut(tc->getVirtProxy());
910 tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]);
911 return tgt_fds[0];
912 }
913
914 /**
915 * Copy the target file descriptors into buffer space and then copy
916 * the buffer space back into the target address space.
917 */
918 BufferArg tgt_handle(tgt_addr, sizeof(int[2]));
919 int *buf_ptr = (int*)tgt_handle.bufferPtr();
920 buf_ptr[0] = tgt_fds[0];
921 buf_ptr[1] = tgt_fds[1];
922 tgt_handle.copyOut(tc->getVirtProxy());
923
924 // pipe2 has additional behavior if flags != 0
925 if (is_pipe2 && flags) {
926 // pipe2 only uses O_NONBLOCK, O_CLOEXEC, and (O_NONBLOCK | O_CLOEXEC)
927 // if flags set to anything else, return EINVAL
928 if ((flags != O_CLOEXEC) && (flags != O_NONBLOCK) &&
929 (flags != (O_CLOEXEC | O_NONBLOCK))) {
930 return -EINVAL;
931 }
932
933 /*
934 If O_NONBLOCK is passed in as a flag to pipe2, set O_NONBLOCK file
935 status flag for two new open file descriptors.
936 */
937 if (flags & O_NONBLOCK) {
938 /*
939 O_NONBLOCK is set when the programmer wants to avoid a separate
940 call(s) to fcntl in their code, so mirror the fcntl
941 implementation for handling file descriptors -- rely on host to
942 maintain file status flags.
943 */
944 if (fcntl(sim_fd_rpfd, F_SETFL, O_NONBLOCK)) {
945 return -errno;
946 }
947 if (fcntl(sim_fd_wpfd, F_SETFL, O_NONBLOCK)) {
948 return -errno;
949 }
950 }
951
952 /*
953 If O_CLOEXEC is passed in as a flag to pipe2, set close-on-exec
954 (FD_CLOEXEC) file status flag for two new open file descriptors.
955 */
956 if (flags & O_CLOEXEC) {
957 rpfd->setCOE(true);
958 wpfd->setCOE(true);
959 }
960 }
961
916 return 0;
917}
918
919SyscallReturn
920pipePseudoFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
921{
922 return pipeImpl(desc, callnum, tc, true);
923}
924
925SyscallReturn
926pipeFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
927{
928 return pipeImpl(desc, callnum, tc, false);
929}
930
931SyscallReturn
962 return 0;
963}
964
965SyscallReturn
966pipePseudoFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
967{
968 return pipeImpl(desc, callnum, tc, true);
969}
970
971SyscallReturn
972pipeFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
973{
974 return pipeImpl(desc, callnum, tc, false);
975}
976
977SyscallReturn
978pipe2Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
979{
980 // call pipeImpl since the only difference between pipe and pipe2 is
981 // the flags values and what they do (at the end of pipeImpl)
982 return pipeImpl(desc, callnum, tc, false, true);
983}
984
985SyscallReturn
932setpgidFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
933{
934 int index = 0;
935 auto process = tc->getProcessPtr();
936 int pid = process->getSyscallArg(tc, index);
937 int pgid = process->getSyscallArg(tc, index);
938
939 if (pgid < 0)

--- 841 unchanged lines hidden ---
986setpgidFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
987{
988 int index = 0;
989 auto process = tc->getProcessPtr();
990 int pid = process->getSyscallArg(tc, index);
991 int pgid = process->getSyscallArg(tc, index);
992
993 if (pgid < 0)

--- 841 unchanged lines hidden ---