示例#1
0
        public static int ClockGetTime(Thread current, int clock_id, UserPtr tp)
        {
            timespec res;
            res.tv_nsec = res.tv_sec = 0;
            switch (clock_id)
            {
                case CLOCK_REALTIME:
                case CLOCK_PROCESS_CPUTIME_ID:
                case CLOCK_THREAD_CPUTIME_ID:
                    res = GetTime(UptimeTimeSpec);
                    break;

                case CLOCK_MONOTONIC:
                    res = GetTime(MonotonicTimeSpec);
                    break;

                default:
                    Arch.Console.Write("Unimplemented ClockGetTime:");
                    Arch.Console.Write(clock_id);
                    Arch.Console.WriteLine();
                    return -ErrorCode.ENOSYS;
            }

            if (tp.Write(current, ref res) != 0)
                return -ErrorCode.EFAULT;

            return 0;
        }
示例#2
0
        public static int ClockGetTime(Thread current, int clock_id, UserPtr tp)
        {
            timespec res;

            res.tv_nsec = res.tv_sec = 0;
            switch (clock_id)
            {
            case CLOCK_REALTIME:
            case CLOCK_PROCESS_CPUTIME_ID:
            case CLOCK_THREAD_CPUTIME_ID:
                res = GetTime(UptimeTimeSpec);
                break;

            case CLOCK_MONOTONIC:
                res = GetTime(MonotonicTimeSpec);
                break;

            default:
                Arch.Console.Write("Unimplemented ClockGetTime:");
                Arch.Console.Write(clock_id);
                Arch.Console.WriteLine();
                return(-ErrorCode.ENOSYS);
            }

            if (tp.Write(current, ref res) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(0);
        }
示例#3
0
        private static int Recv(Thread current, ref Arch.ExceptionRegisters regs, UserPtr ptr_label, UserPtr userBuf, uint size)
        {
            Contract.Requires(current.VBinderState.Owner == current);

            if (!current.Parent.Space.VerifyWrite(userBuf, size) || !current.Parent.Space.VerifyWrite(ptr_label, sizeof(int)))
            {
                return(-ErrorCode.EFAULT);
            }

            var b = current.VBinderState.NoPendingMessages();

            if (b)
            {
                var entry = new VBinderCompletion(current, ptr_label, userBuf, size);
                current.VBinderState.Completion = entry;

                current.SaveState(ref regs);
                current.AsyncReturn = true;
                return(0);
            }
            else
            {
                var msg = current.VBinderState.TakeMessage();

                Contract.Assert(msg.GhostTarget == current);

                var length = msg.Length;
                ptr_label.Write(current.Parent, msg.label);
                userBuf.Write(current, new Pointer(msg.payload.Location), length);
                msg.Recycle();
                return(length);
            }
        }
示例#4
0
        internal int TranslateToUserFdlist(Thread current, ByteBufferRef buf, int poll_ret, int maxfds, UserPtr userPtr, short event_type)
        {
            Contract.Requires(poll_ret * pollfd.Size < buf.Length);

            if (userPtr == UserPtr.Zero)
                return 0;

            var res = 0;
            var len = (maxfds + 7) / 8;
            var vec = new FixedSizeBitVector(maxfds);

            for (int i = 0; i < poll_ret; i++)
            {
                var poll_struct = pollfd.Deserialize(buf, i * pollfd.Size);
                var linux_fd = poll_struct.fd;
                var node = Lookup(linux_fd);
                if (node == null)
                    return -ErrorCode.EBADF;

                if ((poll_struct.revents & event_type & node.event_type) != 0)
                {
                    vec.Set(node.expressos_fd);
                    ++res;
                }
            }

            if (userPtr.Write(current, vec.Buffer) != 0)
                return -ErrorCode.EFAULT;

            return res;
        }
示例#5
0
        private static int StatAt64(Thread current, UserPtr filenamePtr, UserPtr buf, bool followSymlink)
        {
            var proc = current.Parent;
            int err;

            filenamePtr.ReadString(current, Globals.LinuxIPCBuffer);
            if (followSymlink)
            {
                err = Arch.IPCStubs.linux_sys_stat64(proc.helperPid);
            }
            else
            {
                err = Arch.IPCStubs.linux_sys_lstat64(proc.helperPid);
            }
            if (err != 0)
            {
                return(err);
            }

            if (buf.Write(current, new Pointer(Globals.LinuxIPCBuffer.Location), SIZE_OF_STAT64) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(0);
        }
示例#6
0
        private int LinuxIoctl(Thread current, uint cmd, UserPtr arg1)
        {
            var msg_buf = Globals.LinuxIPCBuffer;
            int ret     = 0;

            // marshal arguments
            switch (cmd)
            {
            case FileSystem.FIONREAD:
                break;

            default:
                return(-ErrorCode.ENOTTY);
            }

            ret = Arch.IPCStubs.linux_sys_vfs_linux_ioctl(current.Parent.helperPid, LinuxFd, cmd, arg1.Value.ToInt32());

            if (ret < 0)
            {
                return(ret);
            }

            // unmarshal if necessary
            if (cmd == FileSystem.FIONREAD)
            {
                if (arg1.Write(current, new Pointer(msg_buf.Location), sizeof(int)) != 0)
                {
                    return(-ErrorCode.EFAULT);
                }
            }

            return(ret);
        }
示例#7
0
        internal static int AshmemIoctl(GenericINode generic_inode, Thread current, uint cmd, UserPtr arg1)
        {
            Contract.Requires(Globals.LinuxIPCBuffer.Length >= AshmemINode.ASHMEM_PIN_SIZE);

            int ret = 0;

            switch (cmd)
            {
                case AshmemINode.ASHMEM_SET_NAME:
                    arg1.ReadString(current, Globals.LinuxIPCBuffer);
                    break;

                case AshmemINode.ASHMEM_PIN:
                case AshmemINode.ASHMEM_UNPIN:
                    if (arg1.Read(current, Globals.LinuxIPCBuffer, AshmemINode.ASHMEM_PIN_SIZE) != 0)
                        ret = -ErrorCode.EFAULT;
                    break;

                case AshmemINode.ASHMEM_GET_NAME:
                case AshmemINode.ASHMEM_SET_SIZE:
                case AshmemINode.ASHMEM_GET_SIZE:
                case AshmemINode.ASHMEM_SET_PROT_MASK:
                case AshmemINode.ASHMEM_GET_PROT_MASK:
                case AshmemINode.ASHMEM_GET_PIN_STATUS:
                case AshmemINode.ASHMEM_PURGE_ALL_CACHES:
                    break;

                default:
                    ret = -ErrorCode.ENOSYS;
                    break;
            }

            if (ret < 0)
                return ret;

            var linux_fd = generic_inode.LinuxFd;

            ret = Arch.IPCStubs.linux_sys_vfs_ashmem_ioctl(current.Parent.helperPid, linux_fd, cmd, arg1.Value.ToInt32());

            if (ret < 0)
                  return ret;

            // unmarshal if necessary
            if (cmd == AshmemINode.ASHMEM_GET_NAME)
            {
                var length = Util.Strnlen(Globals.LinuxIPCBuffer, AshmemINode.ASHMEM_NAME_LEN);
                // include terminator
                if (length < AshmemINode.ASHMEM_NAME_LEN)
                    length++;

                var buf = Globals.LinuxIPCBuffer.Slice(0, length);
                if (arg1.Write(current, Globals.LinuxIPCBuffer) != 0)
                    return -ErrorCode.EFAULT;
            }

            return ret;
        }
示例#8
0
        private static int PushInt(Process proc, int v, ref UserPtr stack_top)
        {
            stack_top -= sizeof(int);
            if (stack_top.Write(proc, v) != 0)
            {
                return(-1);
            }

            return(0);
        }
示例#9
0
        public static int Pipe(Thread current, UserPtr pipeFd)
        {
            var proc = current.Parent;
            var helperPid = proc.helperPid;
            int fd0, fd1;

            var ret = Arch.IPCStubs.Pipe(helperPid, out fd0, out fd1);

            if (ret < 0)
            {
                return(ret);
            }

            var inode1 = new Arch.ArchINode(fd0, 0, helperPid);
            var inode2 = new Arch.ArchINode(fd1, 0, helperPid);

            // XXX: are the permission settings correct?
            var file1 = new File(proc, inode1, FileFlags.ReadWrite, 0);

            var rfd0 = proc.GetUnusedFd();

            proc.InstallFd(rfd0, file1);

            var file2 = new File(proc, inode2, FileFlags.ReadWrite, 0);

            var rfd1 = proc.GetUnusedFd();

            proc.InstallFd(rfd1, file2);

            //Arch.Console.Write("pipe: linux_fd [");
            //Arch.Console.Write(fd0);
            //Arch.Console.Write(",");
            //Arch.Console.Write(fd1);
            //Arch.Console.Write("] => [");
            //Arch.Console.Write(rfd0);
            //Arch.Console.Write(",");
            //Arch.Console.Write(rfd1);
            //Arch.Console.Write("], ret=");
            //Arch.Console.Write(ret);
            //Arch.Console.WriteLine();

            if (pipeFd.Write(current, rfd0) != 0 || (pipeFd + sizeof(int)).Write(current, rfd1) != 0)
            {
                Arch.IPCStubs.Close(helperPid, fd0);
                Arch.IPCStubs.Close(helperPid, fd1);

                return(-ErrorCode.EFAULT);
            }

            return(ret);
        }
示例#10
0
        public static int Gettimeofday(Thread current, UserPtr timeval)
        {
            timespec res = GetTime(UptimeTimeSpec);
            timeval  r;

            r.tv_sec  = res.tv_sec;
            r.tv_usec = res.tv_nsec / 1000;

            if (timeval.Write(current, ref r) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(0);
        }
示例#11
0
        private static UserPtr[] PushCharArray(Process proc, ASCIIString[] arr, ref UserPtr stack_top)
        {
            var res = new UserPtr[arr.Length];

            for (int i = 0; i < arr.Length; ++i)
            {
                // Include the terminator
                stack_top -= arr[i].Length + 1;
                res[i]     = stack_top;
                if (stack_top.Write(proc, arr[i].GetByteString()) != 0)
                {
                    return(null);
                }
            }
            return(res);
        }
示例#12
0
        public static int SetThreadArea(Thread current, UserPtr userDescriptor)
        {
            var info = new userdesc();

            if (userDescriptor.Read(current, out info) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            var ret = NativeMethods.l4api_set_thread_area(current.impl._value.thread, current.TLSArray, -1, ref info, 1);

            if (userDescriptor.Write(current, info) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(ret);
        }
示例#13
0
        internal int SFSFStat64(Thread current, UserPtr buf)
        {
            var ret = Arch.IPCStubs.linux_sys_fstat64(helperPid, Fd);

            if (ret < 0)
            {
                return(ret);
            }

            FileSystem.SetSizeFromStat64(Globals.LinuxIPCBuffer, FileSize);

            if (buf.Write(current, new Pointer(Globals.LinuxIPCBuffer.Location), GenericINode.SIZE_OF_STAT64) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(0);
        }
        public static int UnmarshalReadBuffer(Thread thr, ByteBufferRef completionBuf, ref sys_binder_write_desc desc, UserPtr readBuffer, int readBufferSize)
        {
            var proc         = thr.Parent;
            var marshaledPtr = new Pointer(completionBuf.Location);

            //Arch.Console.Write("read_consumed:");
            //Arch.Console.Write(desc.read_consumed);
            //BinderIPCMarshaler.DumpBuf(new Pointer(completionBuf.Location), (int)desc.read_consumed);

            if (proc.binderVMStart == UserPtr.Zero)
            {
                Arch.Console.WriteLine("proc.binderVMStart == UserPtr.Zero");
                return(-ErrorCode.EFAULT);
            }

            if (UnmarshalDataEntries(thr, completionBuf, ref desc) != 0)
            {
                Arch.Console.WriteLine("UnmarshalDataEntries failed");
                return(-ErrorCode.ENOMEM);
            }

            if (desc.read_consumed > completionBuf.Length)
            {
                Arch.Console.WriteLine("UnmarshalReadBuffer: bad input");
                return(-ErrorCode.ENOMEM);
            }

            // Patch pointers and convert file descriptors
            var b = completionBuf.Slice(0, desc.read_consumed);

            if (PatchReadBuffer(thr, b) != 0)
            {
                Arch.Console.WriteLine("Failed to patch read buffer");
                return(-ErrorCode.EINVAL);
            }

            if (readBuffer.Write(thr, marshaledPtr, desc.read_consumed) != 0)
            {
                Arch.Console.WriteLine("readBuffer.Write failed");
                return(-ErrorCode.ENOMEM);
            }

            return(0);
        }
示例#15
0
        private static int PushProgramHeaderAndAuxliraryVectors(Process proc, File file, ELF32Header eh, ref UserPtr stackTop)
        {
            var  programHeaderLength = eh.NumOfProgramHeader * eh.ProgramHeaderSize;
            var  buf = new byte[programHeaderLength];
            uint pos = eh.ProgramHeaderOffest;

            if (file.Read(buf, ref pos) != programHeaderLength)
            {
                return(-ErrorCode.ENOMEM);
            }

            stackTop -= programHeaderLength;
            UserPtr ph_ptr = stackTop;

            if (ph_ptr.Write(proc, buf) != 0)
            {
                return(-ErrorCode.ENOMEM);
            }

            // align
            stackTop = UserPtr.RoundDown(stackTop);

            var aux_vector = new uint[LengthOfAuxVector];

            aux_vector[0] = AT_PHDR;
            aux_vector[1] = ph_ptr.Value.ToUInt32();
            aux_vector[2] = AT_ENTRY;
            aux_vector[3] = eh.EntryPoint;
            aux_vector[4] = AT_PHNUM;
            aux_vector[5] = eh.NumOfProgramHeader;
            aux_vector[6] = 0;
            aux_vector[7] = 0;

            var auxVectorSize = sizeof(uint) * LengthOfAuxVector;

            stackTop -= auxVectorSize;

            if (stackTop.Write(proc, aux_vector) != 0)
            {
                return(-ErrorCode.ENOMEM);
            }

            return(0);
        }
示例#16
0
        public static int UnmarshalReadBuffer(Thread thr, ByteBufferRef completionBuf, ref sys_binder_write_desc desc, UserPtr readBuffer, int readBufferSize)
        {
            var proc = thr.Parent;
            var marshaledPtr = new Pointer(completionBuf.Location);

            //Arch.Console.Write("read_consumed:");
            //Arch.Console.Write(desc.read_consumed);
            //BinderIPCMarshaler.DumpBuf(new Pointer(completionBuf.Location), (int)desc.read_consumed);

            if (proc.binderVMStart == UserPtr.Zero)
            {
                Arch.Console.WriteLine("proc.binderVMStart == UserPtr.Zero");
                return -ErrorCode.EFAULT;
            }

            if (UnmarshalDataEntries(thr, completionBuf, ref desc) != 0)
            {
                Arch.Console.WriteLine("UnmarshalDataEntries failed");
                return -ErrorCode.ENOMEM;
            }

            if (desc.read_consumed > completionBuf.Length)
            {
                Arch.Console.WriteLine("UnmarshalReadBuffer: bad input");
                return -ErrorCode.ENOMEM;
            }

            // Patch pointers and convert file descriptors
            var b = completionBuf.Slice(0, desc.read_consumed);
            if (PatchReadBuffer(thr, b) != 0)
            {
                Arch.Console.WriteLine("Failed to patch read buffer");
                return -ErrorCode.EINVAL;
            }

            if (readBuffer.Write(thr, marshaledPtr, desc.read_consumed) != 0)
            {
                Arch.Console.WriteLine("readBuffer.Write failed");
                return -ErrorCode.ENOMEM;
            }

            return 0;
        }
示例#17
0
        public static int Nanosleep(Thread current, ref Arch.ExceptionRegisters regs, UserPtr rqtp, UserPtr rmtp)
        {
            timespec ts;
            timespec trem;

            trem.tv_sec  = 0;
            trem.tv_nsec = 0;

            if (rqtp.Read(current, out ts) != 0 || rmtp.Write(current, ref trem) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            Globals.TimeoutQueue.Enqueue(ts.ToMilliseconds(), current);
            var c = new SleepCompletion(current);

            Globals.CompletionQueue.Enqueue(c);
            current.SaveState(ref regs);
            current.AsyncReturn = true;
            return(0);
        }
示例#18
0
        private static int RecvFrom(Thread current, int sockfd, UserPtr userBuf, int len, int flags, UserPtr sockaddr, UserPtr p_addrlen)
        {
            var proc = current.Parent;
            var file = proc.LookupFile(sockfd);

            if (file == null)
            {
                return(-ErrorCode.EBADF);
            }

            int addrlen;

            if (p_addrlen.Read(current, out addrlen) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            var buf = Globals.LinuxIPCBuffer;

            if (len + addrlen > buf.Length)
            {
                return(-ErrorCode.ENOMEM);
            }

            var ret = Arch.IPCStubs.Recvfrom(proc.helperPid, file.inode.LinuxFd, len, flags, ref addrlen);

            if (ret < 0)
            {
                return(ret);
            }

            var left = userBuf.Write(current, new Pointer(buf.Location), ret);

            if (sockaddr.Write(current, new Pointer(buf.Location + ret - left), addrlen) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(ret - left);
        }
示例#19
0
        internal int TranslateToUserFdlist(Thread current, ByteBufferRef buf, int poll_ret, int maxfds, UserPtr userPtr, short event_type)
        {
            Contract.Requires(poll_ret * pollfd.Size < buf.Length);

            if (userPtr == UserPtr.Zero)
            {
                return(0);
            }

            var res = 0;
            var len = (maxfds + 7) / 8;
            var vec = new FixedSizeBitVector(maxfds);

            for (int i = 0; i < poll_ret; i++)
            {
                var poll_struct = pollfd.Deserialize(buf, i * pollfd.Size);
                var linux_fd    = poll_struct.fd;
                var node        = Lookup(linux_fd);
                if (node == null)
                {
                    return(-ErrorCode.EBADF);
                }

                if ((poll_struct.revents & event_type & node.event_type) != 0)
                {
                    vec.Set(node.expressos_fd);
                    ++res;
                }
            }

            if (userPtr.Write(current, vec.Buffer) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(res);
        }
示例#20
0
        private static int PushInt(Process proc, int v, ref UserPtr stack_top)
        {
            stack_top -= sizeof(int);
            if (stack_top.Write(proc, v) != 0)
                return -1;

            return 0;
        }
示例#21
0
 private static UserPtr[] PushCharArray(Process proc, ASCIIString[] arr, ref UserPtr stack_top)
 {
     var res = new UserPtr[arr.Length];
     for (int i = 0; i < arr.Length; ++i)
     {
         // Include the terminator
         stack_top -= arr[i].Length + 1;
         res[i] = stack_top;
         if (stack_top.Write(proc, arr[i].GetByteString()) != 0)
             return null;
     }
     return res;
 }
示例#22
0
 public static int Getcwd(Thread current, UserPtr buf, int length)
 {
     buf.Write(current, CWDStr.GetByteString());
     return(0);
 }
示例#23
0
        private static int RecvFrom(Thread current, int sockfd, UserPtr userBuf, int len, int flags, UserPtr sockaddr, UserPtr p_addrlen)
        {
            var proc = current.Parent;
            var file = proc.LookupFile(sockfd);
            if (file == null)
                return -ErrorCode.EBADF;

            int addrlen;
            if (p_addrlen.Read(current, out addrlen) != 0)
                return -ErrorCode.EFAULT;

            var buf = Globals.LinuxIPCBuffer;
            if (len + addrlen > buf.Length)
            {
                return -ErrorCode.ENOMEM;
            }

            var ret = Arch.IPCStubs.Recvfrom(proc.helperPid, file.inode.LinuxFd, len, flags, ref addrlen);
            if (ret < 0)
                return ret;

            var left = userBuf.Write(current, new Pointer(buf.Location), ret);

            if (sockaddr.Write(current, new Pointer(buf.Location + ret - left), addrlen) != 0)
                return -ErrorCode.EFAULT;

            return ret - left;
        }
示例#24
0
        private static int StatAt64(Thread current, UserPtr filenamePtr, UserPtr buf, bool followSymlink)
        {
            var proc = current.Parent;
            int err;
            filenamePtr.ReadString(current, Globals.LinuxIPCBuffer);
            if (followSymlink)
            {
                err = Arch.IPCStubs.linux_sys_stat64(proc.helperPid);
            }
            else
            {
                err = Arch.IPCStubs.linux_sys_lstat64(proc.helperPid);
            }
            if (err != 0)
                return err;

            if (buf.Write(current, new Pointer(Globals.LinuxIPCBuffer.Location), SIZE_OF_STAT64) != 0)
                return -ErrorCode.EFAULT;

            return 0;
        }
示例#25
0
        public static int Pipe(Thread current, UserPtr pipeFd)
        {
            var proc = current.Parent;
            var helperPid = proc.helperPid;
            int fd0, fd1;

            var ret = Arch.IPCStubs.Pipe(helperPid, out fd0, out fd1);

            if (ret < 0)
                return ret;

            var inode1 = new Arch.ArchINode(fd0, 0, helperPid);
            var inode2 = new Arch.ArchINode(fd1, 0, helperPid);

            // XXX: are the permission settings correct?
            var file1 = new File(proc, inode1, FileFlags.ReadWrite, 0);

            var rfd0 = proc.GetUnusedFd();
            proc.InstallFd(rfd0, file1);

            var file2 = new File(proc, inode2, FileFlags.ReadWrite, 0);

            var rfd1 = proc.GetUnusedFd();
            proc.InstallFd(rfd1, file2);

            //Arch.Console.Write("pipe: linux_fd [");
            //Arch.Console.Write(fd0);
            //Arch.Console.Write(",");
            //Arch.Console.Write(fd1);
            //Arch.Console.Write("] => [");
            //Arch.Console.Write(rfd0);
            //Arch.Console.Write(",");
            //Arch.Console.Write(rfd1);
            //Arch.Console.Write("], ret=");
            //Arch.Console.Write(ret);
            //Arch.Console.WriteLine();

            if (pipeFd.Write(current, rfd0) != 0 || (pipeFd + sizeof(int)).Write(current, rfd1) != 0)
            {
                Arch.IPCStubs.Close(helperPid, fd0);
                Arch.IPCStubs.Close(helperPid, fd1);

                return -ErrorCode.EFAULT;
            }

            return ret;
        }
示例#26
0
 public static int UName(Thread current, UserPtr buf)
 {
     var res = buf.Write(current, UTSNameInfo);
     return res == 0 ? 0 : -1;
 }
示例#27
0
        private int LinuxIoctl(Thread current, uint cmd, UserPtr arg1)
        {
            var msg_buf = Globals.LinuxIPCBuffer;
            int ret = 0;

            // marshal arguments
            switch (cmd)
            {
                case FileSystem.FIONREAD:
                    break;

                default:
                    return -ErrorCode.ENOTTY;
            }

            ret = Arch.IPCStubs.linux_sys_vfs_linux_ioctl(current.Parent.helperPid, LinuxFd, cmd, arg1.Value.ToInt32());

            if (ret < 0)
                return ret;

            // unmarshal if necessary
            if (cmd == FileSystem.FIONREAD)
            {
                if (arg1.Write(current, new Pointer(msg_buf.Location), sizeof(int)) != 0)
                    return -ErrorCode.EFAULT;
            }

            return ret;
        }
示例#28
0
        internal static int AshmemIoctl(GenericINode generic_inode, Thread current, uint cmd, UserPtr arg1)
        {
            Contract.Requires(Globals.LinuxIPCBuffer.Length >= AshmemINode.ASHMEM_PIN_SIZE);

            int ret = 0;

            switch (cmd)
            {
            case AshmemINode.ASHMEM_SET_NAME:
                arg1.ReadString(current, Globals.LinuxIPCBuffer);
                break;

            case AshmemINode.ASHMEM_PIN:
            case AshmemINode.ASHMEM_UNPIN:
                if (arg1.Read(current, Globals.LinuxIPCBuffer, AshmemINode.ASHMEM_PIN_SIZE) != 0)
                {
                    ret = -ErrorCode.EFAULT;
                }
                break;

            case AshmemINode.ASHMEM_GET_NAME:
            case AshmemINode.ASHMEM_SET_SIZE:
            case AshmemINode.ASHMEM_GET_SIZE:
            case AshmemINode.ASHMEM_SET_PROT_MASK:
            case AshmemINode.ASHMEM_GET_PROT_MASK:
            case AshmemINode.ASHMEM_GET_PIN_STATUS:
            case AshmemINode.ASHMEM_PURGE_ALL_CACHES:
                break;

            default:
                ret = -ErrorCode.ENOSYS;
                break;
            }

            if (ret < 0)
            {
                return(ret);
            }

            var linux_fd = generic_inode.LinuxFd;

            ret = Arch.IPCStubs.linux_sys_vfs_ashmem_ioctl(current.Parent.helperPid, linux_fd, cmd, arg1.Value.ToInt32());

            if (ret < 0)
            {
                return(ret);
            }

            // unmarshal if necessary
            if (cmd == AshmemINode.ASHMEM_GET_NAME)
            {
                var length = Util.Strnlen(Globals.LinuxIPCBuffer, AshmemINode.ASHMEM_NAME_LEN);
                // include terminator
                if (length < AshmemINode.ASHMEM_NAME_LEN)
                {
                    length++;
                }

                var buf = Globals.LinuxIPCBuffer.Slice(0, length);
                if (arg1.Write(current, Globals.LinuxIPCBuffer) != 0)
                {
                    return(-ErrorCode.EFAULT);
                }
            }

            return(ret);
        }
示例#29
0
        public static int UName(Thread current, UserPtr buf)
        {
            var res = buf.Write(current, UTSNameInfo);

            return(res == 0 ? 0 : -1);
        }
示例#30
0
        private static int Recv(Thread current, ref Arch.ExceptionRegisters regs, UserPtr ptr_label, UserPtr userBuf, uint size)
        {
            Contract.Requires(current.VBinderState.Owner == current);

            if (!current.Parent.Space.VerifyWrite(userBuf, size) || !current.Parent.Space.VerifyWrite(ptr_label, sizeof(int)))
                return -ErrorCode.EFAULT;

            var b = current.VBinderState.NoPendingMessages();
            if (b)
            {
                var entry = new VBinderCompletion(current, ptr_label, userBuf, size);
                current.VBinderState.Completion = entry;

                current.SaveState(ref regs);
                current.AsyncReturn = true;
                return 0;
            }
            else
            {
                var msg = current.VBinderState.TakeMessage();

                Contract.Assert(msg.GhostTarget == current);

                var length = msg.Length;
                ptr_label.Write(current.Parent, msg.label);
                userBuf.Write(current, new Pointer(msg.payload.Location), length);
                msg.Recycle();
                return length;
            }
        }
示例#31
0
 public static int Getcwd(Thread current, UserPtr buf, int length)
 {
     buf.Write(current, CWDStr.GetByteString());
     return 0;
 }
示例#32
0
        public static int Nanosleep(Thread current, ref Arch.ExceptionRegisters regs, UserPtr rqtp, UserPtr rmtp)
        {
            timespec ts;
            timespec trem;

            trem.tv_sec = 0;
            trem.tv_nsec = 0;

            if (rqtp.Read(current, out ts) != 0 || rmtp.Write(current, ref trem) != 0)
                return -ErrorCode.EFAULT;

            Globals.TimeoutQueue.Enqueue(ts.ToMilliseconds(), current);
            var c = new SleepCompletion(current);

            Globals.CompletionQueue.Enqueue(c);
            current.SaveState(ref regs);
            current.AsyncReturn = true;
            return 0;
        }
示例#33
0
        private static int PushProgramHeaderAndAuxliraryVectors(Process proc, File file, ELF32Header eh, ref UserPtr stackTop)
        {
            var programHeaderLength = eh.NumOfProgramHeader * eh.ProgramHeaderSize;
            var buf = new byte[programHeaderLength];
            uint pos = eh.ProgramHeaderOffest;

            if (file.Read(buf, ref pos) != programHeaderLength)
                return -ErrorCode.ENOMEM;

            stackTop -= programHeaderLength;
            UserPtr ph_ptr = stackTop;

            if (ph_ptr.Write(proc, buf) != 0)
                return -ErrorCode.ENOMEM;

            // align
            stackTop = UserPtr.RoundDown(stackTop);

            var aux_vector = new uint[LengthOfAuxVector];
            aux_vector[0] = AT_PHDR;
            aux_vector[1] = ph_ptr.Value.ToUInt32();
            aux_vector[2] = AT_ENTRY;
            aux_vector[3] = eh.EntryPoint;
            aux_vector[4] = AT_PHNUM;
            aux_vector[5] = eh.NumOfProgramHeader;
            aux_vector[6] = 0;
            aux_vector[7] = 0;

            var auxVectorSize = sizeof(uint) * LengthOfAuxVector;
            stackTop -= auxVectorSize;

            if (stackTop.Write(proc, aux_vector) != 0)
                return -ErrorCode.ENOMEM;

            return 0;
        }
示例#34
0
        public static int Gettimeofday(Thread current, UserPtr timeval)
        {
            timespec res = GetTime(UptimeTimeSpec);
            timeval r;
            r.tv_sec = res.tv_sec;
            r.tv_usec = res.tv_nsec / 1000;

            if (timeval.Write(current, ref r) != 0)
                return -ErrorCode.EFAULT;

            return 0;
        }