Beispiel #1
0
        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;
        }
Beispiel #2
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;
        }
Beispiel #3
0
        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;
        }