private int HandleWriteRead(Thread current, UserPtr userBwr, ref Arch.ExceptionRegisters pt_regs) { var bwr = new binder_write_read(); if (userBwr.Read(current, out bwr) != 0) { return(-ErrorCode.EFAULT); } if (bwr.write_size > 0 || bwr.read_size > 0) { var ret = HandleWriteRead(current, ref pt_regs, userBwr, bwr); if (ret < 0) { bwr.read_consumed = 0; if (userBwr.Write(current, ref bwr) != 0) { return(-ErrorCode.EFAULT); } } } if (userBwr.Write(current, ref bwr) != 0) { return(-ErrorCode.EFAULT); } return(0); }
public VBinderCompletion(Thread current, UserPtr ptr_label, UserPtr userBuf, uint size) : base(current, Kind.VBinderCompletionKind) { this.ptr_label = ptr_label; this.userBuf = userBuf; this.size = size; }
public FutexCompletionEntry(Thread current, UserPtr uaddr, uint bitset) : base(current, Kind.FutexCompletionKind) { this.uaddr = uaddr; this.bitset = bitset; this.timeoutNode = null; }
public void Remove(AddressSpace parent, UserPtr startPage, UserPtr endPage) { Utils.Assert(Arch.ArchDefinition.PageOffset(startPage.Value.ToUInt32()) == 0); Utils.Assert(Arch.ArchDefinition.PageOffset(endPage.Value.ToUInt32()) == 0); for (var page = startPage; page < endPage; page += Arch.ArchDefinition.PageSize) { var directory_index = DirectoryIndex(page); var table_index = TableIndex(page); var table = Directory[directory_index]; if (table == null) { continue; } if (table[table_index] == Pointer.Zero) { continue; } FreePhysicalPage(table[table_index]); table[table_index] = Pointer.Zero; } Arch.NativeMethods.l4api_flush_regions(parent.impl._value, startPage.Value, endPage.Value, (int)MemoryRegion.FAULT_MASK); }
public IOCompletion(Thread current, Type type, UserPtr userBuf, int len, File file, ByteBufferRef buf) : base(current, Kind.IOCompletionKind, buf) { this.type = type; this.userBuf = userBuf; this.len = len; this.posToUpdate = file; }
public void Add(UserPtr userAddress, Pointer virtualAddr) { Utils.Assert(virtualAddr != Pointer.Zero); var directory_index = DirectoryIndex(userAddress); var table_index = TableIndex(userAddress); var table = GetOrCreateTable(directory_index); Utils.Assert(table[table_index] == Pointer.Zero); table[table_index] = virtualAddr; }
public int ArchFStat64(Thread current, UserPtr buf) { var ret = IPCStubs.linux_sys_fstat64(current.Parent.helperPid, Fd); if (ret < 0) return ret; if (buf.Write(current, new Pointer(Globals.LinuxIPCBuffer.Location), GenericINode.SIZE_OF_STAT64) != 0) return -ErrorCode.EFAULT; return 0; }
public int ArchFStat64(Thread current, UserPtr buf) { var ret = IPCStubs.linux_sys_fstat64(current.Parent.helperPid, Fd); if (ret < 0) { return(ret); } if (buf.Write(current, new Pointer(Globals.LinuxIPCBuffer.Location), GenericINode.SIZE_OF_STAT64) != 0) { return(-ErrorCode.EFAULT); } return(0); }
public Pointer UserToVirt(UserPtr addr) { var directory_index = DirectoryIndex(addr); if (Directory[directory_index] == null) { return(Pointer.Zero); } var table_index = TableIndex(addr); var virtualAddr = Directory[directory_index][table_index]; if (virtualAddr == Pointer.Zero) { return(Pointer.Zero); } virtualAddr += Arch.ArchDefinition.PageOffset(addr.Value.ToInt32()); return(virtualAddr); }
public void Remove(AddressSpace parent, UserPtr startPage, UserPtr endPage) { Utils.Assert(Arch.ArchDefinition.PageOffset(startPage.Value.ToUInt32()) == 0); Utils.Assert(Arch.ArchDefinition.PageOffset(endPage.Value.ToUInt32()) == 0); for (var page = startPage; page < endPage; page += Arch.ArchDefinition.PageSize) { var directory_index = DirectoryIndex(page); var table_index = TableIndex(page); var table = Directory[directory_index]; if (table == null) continue; if (table[table_index] == Pointer.Zero) continue; FreePhysicalPage(table[table_index]); table[table_index] = Pointer.Zero; } Arch.NativeMethods.l4api_flush_regions(parent.impl._value, startPage.Value, endPage.Value, (int)MemoryRegion.FAULT_MASK); }
internal int ArchRead(Thread current, ref ExceptionRegisters regs, UserPtr userBuf, int len, uint pos, File file) { var buf = Globals.AllocateAlignedCompletionBuffer(len); if (!buf.isValid) { return(-ErrorCode.ENOMEM); } var iocp = IOCompletion.CreateReadIOCP(current, userBuf, len, file, buf); var r = IPCStubs.ReadAsync(current.Parent.helperPid, current.impl._value.thread._value, new Pointer(buf.Location), fd, len, pos); if (r < 0) { iocp.Dispose(); return(r); } Globals.CompletionQueue.Enqueue(iocp); current.SaveState(ref regs); current.AsyncReturn = true; return(0); }
internal BinderCompletion(Thread current, UserPtr userBwrBuf, sys_binder_write_desc desc, ByteBufferRef buf) : base(current, Kind.BinderCompletionKind, buf) { this.userBwrBuf = userBwrBuf; this.desc = desc; }
private int HandleWriteRead(Thread current, ref Arch.ExceptionRegisters regs, UserPtr userBwr, binder_write_read bwr) { var writeBuf = bwr.write_buffer; var writeSize = bwr.write_size; var buf = Globals.AllocateAlignedCompletionBuffer(MARSHAL_BUF_PAGES * Arch.ArchDefinition.PageSize); if (!buf.isValid) { return(-ErrorCode.ENOMEM); } var marshaler = new BinderIPCMarshaler(current, buf); if (bwr.write_consumed != 0) { Arch.Console.WriteLine("BinderINode::HandleWriteRead: write_consumed != 0"); Utils.Panic(); } var r = marshaler.Marshal(writeBuf, writeSize); if (r < 0) { Arch.Console.WriteLine("Marshaling error"); Globals.CompletionQueueAllocator.FreePages(new Pointer(buf.Location), MARSHAL_BUF_PAGES); return(-1); } sys_binder_write_desc desc; desc.buffer_size = marshaler.WriteCursor; desc.bwr_write_size = writeSize; desc.write_buffer = new Pointer(buf.Location); desc.patch_table_entries = marshaler.CurrentPatchEntry; desc.patch_table_offset = marshaler.PatchTableOffset; desc.read_consumed = 0; desc.write_consumed = 0; var binder_cp = new BinderCompletion(current, userBwr, desc, buf); r = Arch.IPCStubs.linux_sys_binder_write_read_async(current.Parent.helperPid, current.impl._value.thread._value, desc); if (r < 0) { binder_cp.Dispose(); return(r); } Globals.CompletionQueue.Enqueue(binder_cp); current.SaveState(ref regs); current.AsyncReturn = true; return(0); }
internal int Write(Thread current, ref Arch.ExceptionRegisters regs, UserPtr userBuf, int len, uint pos, File file) { var buf = Globals.AllocateAlignedCompletionBuffer(len); if (!buf.isValid) return -ErrorCode.ENOMEM; var l = userBuf.Read(current, buf, len); var bytesToBeWritten = len - l; var ret = Write(current, ref regs, ref buf, bytesToBeWritten, pos, file); // Buffer hasn't been taken by write(), free it here if (buf.isValid) Globals.CompletionQueueAllocator.FreePages(new Pointer(buf.Location), buf.Length >> Arch.ArchDefinition.PageShift); return ret; }
internal int Ioctl(Thread current, ref Arch.ExceptionRegisters pt_regs, uint cmd, UserPtr userBuf) { switch (cmd) { case BINDER_WRITE_READ: return(HandleWriteRead(current, userBuf, ref pt_regs)); case BINDER_VERSION: if (userBuf.Write(current, BINDER_CURRENT_PROTOCOL_VERSION) != 0) { return(-ErrorCode.EINVAL); } return(0); case BINDER_SET_IDLE_TIMEOUT: case BINDER_SET_MAX_THREADS: case BINDER_SET_IDLE_PRIORITY: case BINDER_SET_CONTEXT_MGR: case BINDER_THREAD_EXIT: // skipping return(0); default: return(-ErrorCode.EINVAL); } }
private int Ioctl(Thread current, uint cmd, UserPtr arg1) { //Arch.Console.Write("ioctl:, cmd="); //Arch.Console.Write(cmd); //Arch.Console.WriteLine(); // marshal arguments switch (cmd) { case AshmemINode.ASHMEM_SET_NAME: case AshmemINode.ASHMEM_PIN: case AshmemINode.ASHMEM_UNPIN: 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: return AshmemINode.AshmemIoctl(this, current, cmd, arg1); case FileSystem.FIONREAD: return LinuxIoctl(current, cmd, arg1); default: return -1; } }
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; }
internal static IOCompletion CreateReadIOCP(Thread current, UserPtr userBuf, int len, File file, ByteBufferRef buf) { return(new IOCompletion(current, Type.Read, userBuf, len, file, buf)); }
private static int TableIndex(UserPtr addr) { return (int)((addr.Value.ToUInt32() & PGT_IDX_MASK) >> Arch.ArchDefinition.PageShift); }
private static int TableIndex(UserPtr addr) { return((int)((addr.Value.ToUInt32() & PGT_IDX_MASK) >> Arch.ArchDefinition.PageShift)); }
internal int Read(Thread current, ref Arch.ExceptionRegisters regs, UserPtr userBuf, int len, uint pos, File file) { switch (kind) { case INodeKind.ArchINodeKind: case INodeKind.SocketINodeKind: return ArchINode.ArchRead(current, ref regs, userBuf, len, pos, file); case INodeKind.SecureFSINodeKind: return SFSINode.SFSRead(current, ref regs, userBuf, len, pos, file); } return -ErrorCode.EINVAL; }
private int HandleWriteRead(Thread current, ref Arch.ExceptionRegisters regs, UserPtr userBwr, binder_write_read bwr) { var writeBuf = bwr.write_buffer; var writeSize = bwr.write_size; var buf = Globals.AllocateAlignedCompletionBuffer(MARSHAL_BUF_PAGES * Arch.ArchDefinition.PageSize); if (!buf.isValid) return -ErrorCode.ENOMEM; var marshaler = new BinderIPCMarshaler(current, buf); if (bwr.write_consumed != 0) { Arch.Console.WriteLine("BinderINode::HandleWriteRead: write_consumed != 0"); Utils.Panic(); } var r = marshaler.Marshal(writeBuf, writeSize); if (r < 0) { Arch.Console.WriteLine("Marshaling error"); Globals.CompletionQueueAllocator.FreePages(new Pointer(buf.Location), MARSHAL_BUF_PAGES); return -1; } sys_binder_write_desc desc; desc.buffer_size = marshaler.WriteCursor; desc.bwr_write_size = writeSize; desc.write_buffer = new Pointer(buf.Location); desc.patch_table_entries = marshaler.CurrentPatchEntry; desc.patch_table_offset = marshaler.PatchTableOffset; desc.read_consumed = 0; desc.write_consumed = 0; var binder_cp = new BinderCompletion(current, userBwr, desc, buf); r = Arch.IPCStubs.linux_sys_binder_write_read_async(current.Parent.helperPid, current.impl._value.thread._value, desc); if (r < 0) { binder_cp.Dispose(); return r; } Globals.CompletionQueue.Enqueue(binder_cp); current.SaveState(ref regs); current.AsyncReturn = true; return 0; }
internal int FStat64(Thread current, UserPtr buf) { switch (kind) { case INodeKind.ArchINodeKind: return ArchINode.ArchFStat64(current, buf); case INodeKind.SecureFSINodeKind: return SFSINode.SFSFStat64(current, buf); } return -ErrorCode.EINVAL; }
internal int ArchRead(Thread current, ref ExceptionRegisters regs, UserPtr userBuf, int len, uint pos, File file) { var buf = Globals.AllocateAlignedCompletionBuffer(len); if (!buf.isValid) return -ErrorCode.ENOMEM; var iocp = IOCompletion.CreateReadIOCP(current, userBuf, len, file, buf); var r = IPCStubs.ReadAsync(current.Parent.helperPid, current.impl._value.thread._value, new Pointer(buf.Location), fd, len, pos); if (r < 0) { iocp.Dispose(); return r; } Globals.CompletionQueue.Enqueue(iocp); current.SaveState(ref regs); current.AsyncReturn = true; return 0; }
private static int DirectoryIndex(UserPtr addr) { return (int)(addr.Value.ToUInt32() >> (Arch.ArchDefinition.PageShift + PGT_SHIFT)); }
internal static IOCompletion CreateReadIOCP(Thread current, UserPtr userBuf, int len, File file, ByteBufferRef buf) { return new IOCompletion(current, Type.Read, userBuf, len, file, buf); }
internal int Ioctl(Thread current, ref Arch.ExceptionRegisters pt_regs, uint cmd, UserPtr userBuf) { switch (cmd) { case BINDER_WRITE_READ: return HandleWriteRead(current, userBuf, ref pt_regs); case BINDER_VERSION: if (userBuf.Write(current, BINDER_CURRENT_PROTOCOL_VERSION) != 0) return -ErrorCode.EINVAL; return 0; case BINDER_SET_IDLE_TIMEOUT: case BINDER_SET_MAX_THREADS: case BINDER_SET_IDLE_PRIORITY: case BINDER_SET_CONTEXT_MGR: case BINDER_THREAD_EXIT: // skipping return 0; default: return -ErrorCode.EINVAL; } }
private static int DirectoryIndex(UserPtr addr) { return((int)(addr.Value.ToUInt32() >> (Arch.ArchDefinition.PageShift + PGT_SHIFT))); }
public Pointer UserToVirt(UserPtr addr) { var directory_index = DirectoryIndex(addr); if (Directory[directory_index] == null) return Pointer.Zero; var table_index = TableIndex(addr); var virtualAddr = Directory[directory_index][table_index]; if (virtualAddr == Pointer.Zero) return Pointer.Zero; virtualAddr += Arch.ArchDefinition.PageOffset(addr.Value.ToInt32()); return virtualAddr; }
private int HandleWriteRead(Thread current, UserPtr userBwr, ref Arch.ExceptionRegisters pt_regs) { var bwr = new binder_write_read(); if (userBwr.Read(current, out bwr) != 0) return -ErrorCode.EFAULT; if (bwr.write_size > 0 || bwr.read_size > 0) { var ret = HandleWriteRead(current, ref pt_regs, userBwr, bwr); if (ret < 0) { bwr.read_consumed = 0; if (userBwr.Write(current, ref bwr) != 0) return -ErrorCode.EFAULT; } } if (userBwr.Write(current, ref bwr) != 0) return -ErrorCode.EFAULT; return 0; }