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 void HandleAsyncCall(BinderCompletion entry, int retval, int write_consumed, int read_consumed, int buffer_size, int data_entries) { var current = entry.thr; int ret = retval; if (retval < 0) { entry.Dispose(); current.ReturnFromCompletion(retval); return; } var bwr = new binder_write_read(); entry.userBwrBuf.Read(current, out bwr); var desc = entry.desc; bwr.write_consumed = write_consumed; bwr.read_consumed = read_consumed; desc.read_consumed = read_consumed; desc.patch_table_entries = data_entries; desc.buffer_size = buffer_size; int r = 0; r = ReadBufferUnmarshaler.UnmarshalReadBuffer(current, entry.buf, ref desc, bwr.read_buffer, bwr.read_consumed); if (r < 0) { Arch.Console.WriteLine("UnmarshalReadBuffer failed"); ret = r; } if (entry.userBwrBuf.Write(current, ref bwr) != 0) { Arch.Console.WriteLine("entry.userBwrBuf.Write failed"); ret = -ErrorCode.EFAULT; } entry.Dispose(); current.ReturnFromCompletion(ret); return; }
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; }