Example #1
0
 public override int GetHashCode()
 {
     return(_value.ToInt32());
 }
Example #2
0
        public static int mmap2(Thread current, UserPtr addr, int length, int prot, int flags, int fd, int pgoffset)
        {
            Contract.Requires(current.Parent == current.Parent.Space.GhostOwner);

            Pointer targetAddr = new Pointer(Arch.ArchDefinition.PageAlign(addr.Value.ToUInt32()));

            //Arch.Console.Write("mmap2:");
            //Arch.Console.Write(addr.Value.ToInt32());
            //Arch.Console.Write(" sz=");
            //Arch.Console.Write(length);
            //Arch.Console.Write(" prot=");
            //Arch.Console.Write(prot);
            //Arch.Console.WriteLine();

            var proc = current.Parent;
            var space = proc.Space;
            Contract.Assert(proc == space.GhostOwner);

            if ((flags & MAP_FIXED) == 0)
            {
                if (targetAddr == Pointer.Zero || space.ContainRegion(targetAddr, length))
                    targetAddr = space.FindFreeRegion(length);
            }
            else if (Arch.ArchDefinition.PageOffset(addr.Value.ToInt32()) != 0)
            {
                return -ErrorCode.EINVAL;
            }

            targetAddr = new Pointer(Arch.ArchDefinition.PageIndex(targetAddr.ToUInt32()));

            if (targetAddr == Pointer.Zero || length == 0)
                return -ErrorCode.EINVAL;

            File file = null;
            GenericINode inode = null;

            if ((flags & MAP_ANONYMOUS) == 0)
            {
                file = proc.LookupFile(fd);
                if (file == null)
                    return -ErrorCode.EBADF;

                inode = file.inode;
            }

            int memorySize = Arch.ArchDefinition.PageAlign(length);

            // fix for code contract
            if (length > memorySize)
                length = memorySize;

            if ((file != null && length == 0) || length < 0)
                return -ErrorCode.EINVAL;

            if (file == null)
            {
                pgoffset = 0;
                length = 0;
            }

            //
            // Be careful for shared mapping -- which could be a shared memory region coming from Linux.
            // In this case we'll need to (1) call mmap() in the shadow process to obtain a valid mapping
            // (2) when a page fault happens, grabs the physical page from linux.
            //
            if ((flags & MAP_SHARED) != 0 && SharedWithLinux(inode))
            {
                // Don't know how to deal with it...
                if (addr != UserPtr.Zero)
                   return -ErrorCode.EINVAL;

                var vaddr = Arch.IPCStubs.linux_sys_alien_mmap2(current.Parent.helperPid, addr.Value, length,
                    prot, flags, inode.LinuxFd, pgoffset);

                if (vaddr > AddressSpace.KERNEL_OFFSET)
                    return -ErrorCode.EINVAL;

                switch (inode.kind)
                {
                    case GenericINode.INodeKind.BinderSharedINodeKind:
                    case GenericINode.INodeKind.AshmemINodeKind:
                    case GenericINode.INodeKind.ScreenBufferINodeKind:
                        inode.AlienSharedMemoryINode.vaddrInShadowProcess = new Pointer(vaddr);
                        break;

                    default:
                        // UNIMPLEMENTED... let's return EINVAL to make sure we can catch it.
                        return -ErrorCode.EINVAL;
                }
            }

            var r = space.AddMapping(ProtToAccessFlag(prot), flags, file,
                (uint)pgoffset * Arch.ArchDefinition.PageSize, length, targetAddr, memorySize);

            if (r < 0)
                return r;

            //
            // HACK for binder IPC
            //
            if (inode != null && inode.kind == GenericINode.INodeKind.BinderINodeKind)
            {
                proc.binderVMStart = new UserPtr(targetAddr);
                proc.binderVMSize = length;
            }

            return targetAddr.ToInt32();
        }
Example #3
0
        public static int mmap2(Thread current, UserPtr addr, int length, int prot, int flags, int fd, int pgoffset)
        {
            Contract.Requires(current.Parent == current.Parent.Space.GhostOwner);

            Pointer targetAddr = new Pointer(Arch.ArchDefinition.PageAlign(addr.Value.ToUInt32()));

            //Arch.Console.Write("mmap2:");
            //Arch.Console.Write(addr.Value.ToInt32());
            //Arch.Console.Write(" sz=");
            //Arch.Console.Write(length);
            //Arch.Console.Write(" prot=");
            //Arch.Console.Write(prot);
            //Arch.Console.WriteLine();

            var proc  = current.Parent;
            var space = proc.Space;

            Contract.Assert(proc == space.GhostOwner);

            if ((flags & MAP_FIXED) == 0)
            {
                if (targetAddr == Pointer.Zero || space.ContainRegion(targetAddr, length))
                {
                    targetAddr = space.FindFreeRegion(length);
                }
            }
            else if (Arch.ArchDefinition.PageOffset(addr.Value.ToInt32()) != 0)
            {
                return(-ErrorCode.EINVAL);
            }

            targetAddr = new Pointer(Arch.ArchDefinition.PageIndex(targetAddr.ToUInt32()));

            if (targetAddr == Pointer.Zero || length == 0)
            {
                return(-ErrorCode.EINVAL);
            }

            File         file  = null;
            GenericINode inode = null;

            if ((flags & MAP_ANONYMOUS) == 0)
            {
                file = proc.LookupFile(fd);
                if (file == null)
                {
                    return(-ErrorCode.EBADF);
                }

                inode = file.inode;
            }

            int memorySize = Arch.ArchDefinition.PageAlign(length);

            // fix for code contract
            if (length > memorySize)
            {
                length = memorySize;
            }

            if ((file != null && length == 0) || length < 0)
            {
                return(-ErrorCode.EINVAL);
            }

            if (file == null)
            {
                pgoffset = 0;
                length   = 0;
            }

            //
            // Be careful for shared mapping -- which could be a shared memory region coming from Linux.
            // In this case we'll need to (1) call mmap() in the shadow process to obtain a valid mapping
            // (2) when a page fault happens, grabs the physical page from linux.
            //
            if ((flags & MAP_SHARED) != 0 && SharedWithLinux(inode))
            {
                // Don't know how to deal with it...
                if (addr != UserPtr.Zero)
                {
                    return(-ErrorCode.EINVAL);
                }

                var vaddr = Arch.IPCStubs.linux_sys_alien_mmap2(current.Parent.helperPid, addr.Value, length,
                                                                prot, flags, inode.LinuxFd, pgoffset);

                if (vaddr > AddressSpace.KERNEL_OFFSET)
                {
                    return(-ErrorCode.EINVAL);
                }

                switch (inode.kind)
                {
                case GenericINode.INodeKind.BinderSharedINodeKind:
                case GenericINode.INodeKind.AshmemINodeKind:
                case GenericINode.INodeKind.ScreenBufferINodeKind:
                    inode.AlienSharedMemoryINode.vaddrInShadowProcess = new Pointer(vaddr);
                    break;

                default:
                    // UNIMPLEMENTED... let's return EINVAL to make sure we can catch it.
                    return(-ErrorCode.EINVAL);
                }
            }

            var r = space.AddMapping(ProtToAccessFlag(prot), flags, file,
                                     (uint)pgoffset * Arch.ArchDefinition.PageSize, length, targetAddr, memorySize);

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

            //
            // HACK for binder IPC
            //
            if (inode != null && inode.kind == GenericINode.INodeKind.BinderINodeKind)
            {
                proc.binderVMStart = new UserPtr(targetAddr);
                proc.binderVMSize  = length;
            }

            return(targetAddr.ToInt32());
        }