binder.c revision 9b738bb4110926b85da65d36b2e6f1a50199ec4c
194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Copyright 2008 The Android Open Source Project 294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdio.h> 594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdlib.h> 694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <errno.h> 794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <unistd.h> 894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <fcntl.h> 994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <sys/mman.h> 1094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "binder.h" 1294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define MAX_BIO_SIZE (1 << 30) 1494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define TRACE 0 1694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define LOG_TAG "Binder" 1894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <cutils/log.h> 1994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 20bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescuvoid bio_init_from_txn(struct binder_io *io, struct binder_transaction_data *txn); 2194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if TRACE 239b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuvoid hexdump(void *_data, size_t len) 2494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned char *data = _data; 269b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t count; 2794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (count = 0; count < len; count++) { 2994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((count & 15) == 0) 309b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu fprintf(stderr,"%04zu:", count); 3194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr," %02x %c", *data, 3294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood (*data < 32) || (*data > 126) ? '.' : *data); 3394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data++; 3494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((count & 15) == 15) 3594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"\n"); 3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 3794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((count & 15) != 0) 3894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"\n"); 3994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 4094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 41bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescuvoid binder_dump_txn(struct binder_transaction_data *txn) 4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 43bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 449b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t *offs = txn->data.ptr.offsets; 459b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t count = txn->offsets_size / sizeof(size_t); 4694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr," target %p cookie %p code %08x flags %08x\n", 48bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu txn->target.ptr, txn->cookie, txn->code, txn->flags); 49bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu fprintf(stderr," pid %8d uid %8d data %zu offs %zu\n", 50bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu txn->sender_pid, txn->sender_euid, txn->data_size, txn->offsets_size); 51bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu hexdump(txn->data.ptr.buffer, txn->data_size); 5294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (count--) { 53bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu obj = (struct flat_binder_object *) (((char*) txn->data.ptr.buffer) + *offs++); 5494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr," - type %08x flags %08x ptr %p cookie %p\n", 55bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu obj->type, obj->flags, obj->binder, obj->cookie); 5694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 5794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 5894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define NAME(n) case n: return #n 6094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodconst char *cmd_name(uint32_t cmd) 6194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 6294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch(cmd) { 6394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_NOOP); 6494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_TRANSACTION_COMPLETE); 6594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_INCREFS); 6694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_ACQUIRE); 6794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_RELEASE); 6894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_DECREFS); 6994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_TRANSACTION); 7094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_REPLY); 7194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_FAILED_REPLY); 7294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_DEAD_REPLY); 7394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood NAME(BR_DEAD_BINDER); 7494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood default: return "???"; 7594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 7694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 7794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#else 7894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define hexdump(a,b) do{} while (0) 7994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define binder_dump_txn(txn) do{} while (0) 8094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 8194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 8294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define BIO_F_SHARED 0x01 /* needs to be buffer freed */ 8394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define BIO_F_OVERFLOW 0x02 /* ran out of space */ 8494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define BIO_F_IOERROR 0x04 8594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define BIO_F_MALLOCED 0x08 /* needs to be free()'d */ 8694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 8794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct binder_state 8894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 8994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int fd; 9094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *mapped; 919b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t mapsize; 9294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 9394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 949b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct binder_state *binder_open(size_t mapsize) 9594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 9694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_state *bs; 97a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu struct binder_version vers; 9894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 9994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs = malloc(sizeof(*bs)); 10094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!bs) { 10194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood errno = ENOMEM; 1029b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 10394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 10494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 10594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs->fd = open("/dev/binder", O_RDWR); 10694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bs->fd < 0) { 10794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder: cannot open device (%s)\n", 10894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strerror(errno)); 10994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail_open; 11094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 11194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 112a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) || 113a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) { 114a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu fprintf(stderr, "binder: driver version differs from user space\n"); 115a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu goto fail_open; 116a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu } 117a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu 11894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs->mapsize = mapsize; 11994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); 12094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bs->mapped == MAP_FAILED) { 12194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder: cannot map device (%s)\n", 12294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strerror(errno)); 12394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail_map; 12494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 12594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 12694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return bs; 12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 12894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail_map: 12994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood close(bs->fd); 13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail_open: 13194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(bs); 1329b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 13494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 13594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_close(struct binder_state *bs) 13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood munmap(bs->mapped, bs->mapsize); 13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood close(bs->fd); 13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(bs); 14094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 14194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint binder_become_context_manager(struct binder_state *bs) 14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); 14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1479b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuint binder_write(struct binder_state *bs, void *data, size_t len) 14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_write_read bwr; 15094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_size = len; 15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_consumed = 0; 15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_buffer = (unsigned) data; 15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_size = 0; 15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_consumed = 0; 15694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_buffer = 0; 15794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 15894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) { 15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder_write: ioctl failed (%s)\n", 16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strerror(errno)); 16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 16494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_send_reply(struct binder_state *bs, 16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *reply, 1679b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu const void *buffer_to_free, 16894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int status) 16994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct { 17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd_free; 17294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *buffer; 17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd_reply; 174bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data txn; 17594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } __attribute__((packed)) data; 17694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 17794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.cmd_free = BC_FREE_BUFFER; 17894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.buffer = buffer_to_free; 17994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.cmd_reply = BC_REPLY; 180bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.target.ptr = 0; 18194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.cookie = 0; 18294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.code = 0; 18394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (status) { 18494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.flags = TF_STATUS_CODE; 18594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.data_size = sizeof(int); 186bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.offsets_size = 0; 187bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.data.ptr.buffer = &status; 188bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.data.ptr.offsets = 0; 18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.flags = 0; 19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.data_size = reply->data - reply->data0; 192bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0); 193bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.data.ptr.buffer = reply->data0; 194bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.data.ptr.offsets = reply->offs0; 19594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, &data, sizeof(data)); 19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 19894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 19994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint binder_parse(struct binder_state *bs, struct binder_io *bio, 20094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t *ptr, uint32_t size, binder_handler func) 20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int r = 1; 20394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t *end = ptr + (size / 4); 20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 20594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (ptr < end) { 20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd = *ptr++; 20794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if TRACE 20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"%s:\n", cmd_name(cmd)); 20994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch(cmd) { 21194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_NOOP: 21294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_TRANSACTION_COMPLETE: 21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 21594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_INCREFS: 21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_ACQUIRE: 21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_RELEASE: 21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_DECREFS: 21994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if TRACE 22094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr," %08x %08x\n", ptr[0], ptr[1]); 22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 22294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr += 2; 22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 22494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_TRANSACTION: { 225bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr; 226bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu if ((end - ptr) * sizeof(uint32_t) < sizeof(*txn)) { 22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("parse: txn too small!\n"); 22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_dump_txn(txn); 23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (func) { 23294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned rdata[256/4]; 23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io msg; 23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io reply; 23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_init(&reply, rdata, sizeof(rdata), 4); 23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_init_from_txn(&msg, txn); 23994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = func(bs, txn, &msg, &reply); 240bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu binder_send_reply(bs, &reply, txn->data.ptr.buffer, res); 24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr += sizeof(*txn) / sizeof(uint32_t); 24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_REPLY: { 246bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr; 247bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu if ((end - ptr) * sizeof(uint32_t) < sizeof(*txn)) { 24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("parse: reply too small!\n"); 24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_dump_txn(txn); 25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bio) { 25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_init_from_txn(bio, txn); 25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio = 0; 25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* todo FREE BUFFER */ 25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr += (sizeof(*txn) / sizeof(uint32_t)); 25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = 0; 26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_DEAD_BINDER: { 26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_death *death = (void*) *ptr++; 26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood death->func(bs, death->ptr); 26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 26694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_FAILED_REPLY: 26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = -1; 26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_DEAD_REPLY: 27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = -1; 27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood default: 27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("parse: OOPS %d\n", cmd); 27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return r; 28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_acquire(struct binder_state *bs, void *ptr) 28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd[2]; 28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[0] = BC_ACQUIRE; 28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[1] = (uint32_t) ptr; 28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, cmd, sizeof(cmd)); 28894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_release(struct binder_state *bs, void *ptr) 29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 29294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd[2]; 29394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[0] = BC_RELEASE; 29494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[1] = (uint32_t) ptr; 29594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, cmd, sizeof(cmd)); 29694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 29794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 29894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_link_to_death(struct binder_state *bs, void *ptr, struct binder_death *death) 29994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 30094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd[3]; 30194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[0] = BC_REQUEST_DEATH_NOTIFICATION; 30294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[1] = (uint32_t) ptr; 30394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[2] = (uint32_t) death; 30494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, cmd, sizeof(cmd)); 30594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 30694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint binder_call(struct binder_state *bs, 30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *msg, struct binder_io *reply, 31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *target, uint32_t code) 31194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_write_read bwr; 31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct { 31594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd; 316bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data txn; 31794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } writebuf; 31894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned readbuf[32]; 31994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 32094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (msg->flags & BIO_F_OVERFLOW) { 32194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder: txn buffer overflow\n"); 32294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 32394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 32494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 32594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writebuf.cmd = BC_TRANSACTION; 326bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu writebuf.txn.target.handle = target; 32794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writebuf.txn.code = code; 32894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writebuf.txn.flags = 0; 32994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writebuf.txn.data_size = msg->data - msg->data0; 330bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0); 331bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu writebuf.txn.data.ptr.buffer = msg->data0; 332bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu writebuf.txn.data.ptr.offsets = msg->offs0; 33394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 33494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_size = sizeof(writebuf); 33594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_consumed = 0; 33694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_buffer = (unsigned) &writebuf; 3379b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 33894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood hexdump(msg->data0, msg->data - msg->data0); 33994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 34094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_size = sizeof(readbuf); 34194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_consumed = 0; 34294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_buffer = (unsigned) readbuf; 34394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 34494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 34594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 34694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) { 34794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno)); 34894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 34994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = binder_parse(bs, reply, readbuf, bwr.read_consumed, 0); 35294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res == 0) return 0; 35394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) goto fail; 35494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail: 35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memset(reply, 0, sizeof(*reply)); 35894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reply->flags |= BIO_F_IOERROR; 35994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 36094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 36194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_loop(struct binder_state *bs, binder_handler func) 36394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 36494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 36594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_write_read bwr; 36694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned readbuf[32]; 36794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_size = 0; 36994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_consumed = 0; 37094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_buffer = 0; 3719b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 37294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood readbuf[0] = BC_ENTER_LOOPER; 37394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, readbuf, sizeof(unsigned)); 37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 37694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_size = sizeof(readbuf); 37794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_consumed = 0; 37894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_buffer = (unsigned) readbuf; 37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 38194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) { 38394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno)); 38494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 38594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 38694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func); 38894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res == 0) { 38994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("binder_loop: unexpected reply?!\n"); 39094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 39194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) { 39394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("binder_loop: io error %d %s\n", res, strerror(errno)); 39494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 39594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 399bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescuvoid bio_init_from_txn(struct binder_io *bio, struct binder_transaction_data *txn) 40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 401bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu bio->data = bio->data0 = txn->data.ptr.buffer; 402bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu bio->offs = bio->offs0 = txn->data.ptr.offsets; 40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = txn->data_size; 404bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu bio->offs_avail = txn->offsets_size / 4; 40594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags = BIO_F_SHARED; 40694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 40794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 40894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_init(struct binder_io *bio, void *data, 4099b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t maxdata, size_t maxoffs) 41094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 4119b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t n = maxoffs * sizeof(size_t); 41294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 41394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n > maxdata) { 41494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags = BIO_F_OVERFLOW; 41594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = 0; 41694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->offs_avail = 0; 41794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 41894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 41994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data = bio->data0 = (char *) data + n; 42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->offs = bio->offs0 = data; 42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = maxdata - n; 42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->offs_avail = maxoffs; 42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags = 0; 42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void *bio_alloc(struct binder_io *bio, uint32_t size) 42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size = (size + 3) & (~3); 43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (size > bio->data_avail) { 43194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags |= BIO_F_OVERFLOW; 4329b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 43394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 43494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *ptr = bio->data; 43594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data += size; 43694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail -= size; 43794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ptr; 43894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 43994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 44094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 44194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_done(struct binder_state *bs, 44294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *msg, 44394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *reply) 44494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 44594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (reply->flags & BIO_F_SHARED) { 44694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd[2]; 44794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[0] = BC_FREE_BUFFER; 44894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[1] = (uint32_t) reply->data0; 44994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, cmd, sizeof(cmd)); 45094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reply->flags = 0; 45194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 45294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 45394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 454bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescustatic struct flat_binder_object *bio_alloc_obj(struct binder_io *bio) 45594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 456bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 45794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = bio_alloc(bio, sizeof(*obj)); 4599b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 46094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (obj && bio->offs_avail) { 46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->offs_avail--; 46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *bio->offs++ = ((char*) obj) - ((char*) bio->data0); 46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return obj; 46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 46594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 46694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags |= BIO_F_OVERFLOW; 4679b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 46894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 46994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_uint32(struct binder_io *bio, uint32_t n) 47194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 47294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t *ptr = bio_alloc(bio, sizeof(n)); 47394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ptr) 47494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *ptr = n; 47594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 47694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 47794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_obj(struct binder_io *bio, void *ptr) 47894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 479bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 48094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = bio_alloc_obj(bio); 48294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!obj) 48394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 48494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 48694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->type = BINDER_TYPE_BINDER; 487bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu obj->binder = ptr; 48894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->cookie = 0; 48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 49094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_ref(struct binder_io *bio, void *ptr) 49294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 493bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 49494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ptr) 49694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = bio_alloc_obj(bio); 49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood else 49894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = bio_alloc(bio, sizeof(*obj)); 49994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!obj) 50194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 50294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 50494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->type = BINDER_TYPE_HANDLE; 505bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu obj->handle = ptr; 50694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->cookie = 0; 50794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 50894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_string16(struct binder_io *bio, const uint16_t *str) 51094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 5119b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 51294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t *ptr; 51394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!str) { 51594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, 0xffffffff); 51694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 51794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood len = 0; 52094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (str[len]) len++; 52194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 52294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) { 52394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, 0xffffffff); 52494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 52594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 52694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5279b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu /* Note: The payload will carry 32bit size instead of size_t */ 5289b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu bio_put_uint32(bio, (uint32_t) len); 52994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood len = (len + 1) * sizeof(uint16_t); 53094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr = bio_alloc(bio, len); 53194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ptr) 53294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcpy(ptr, str, len); 53394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 53494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 53594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_string16_x(struct binder_io *bio, const char *_str) 53694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 53794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned char *str = (unsigned char*) _str; 5389b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 53994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t *ptr; 54094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!str) { 54294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, 0xffffffff); 54394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 54494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 54594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood len = strlen(_str); 54794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) { 54994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, 0xffffffff); 55094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 55194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 55294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5539b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu /* Note: The payload will carry 32bit size instead of size_t */ 55494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, len); 55594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t)); 55694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!ptr) 55794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 55894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*str) 56094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *ptr++ = *str++; 56194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *ptr++ = 0; 56294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 56394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5649b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustatic void *bio_get(struct binder_io *bio, size_t size) 56594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 56694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size = (size + 3) & (~3); 56794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 56894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bio->data_avail < size){ 56994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = 0; 57094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags |= BIO_F_OVERFLOW; 5719b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 57294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 57394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *ptr = bio->data; 57494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data += size; 57594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail -= size; 57694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ptr; 57794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 57894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 57994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 58094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooduint32_t bio_get_uint32(struct binder_io *bio) 58194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 58294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t *ptr = bio_get(bio, sizeof(*ptr)); 58394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ptr ? *ptr : 0; 58494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 58594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5869b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuuint16_t *bio_get_string16(struct binder_io *bio, size_t *sz) 58794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 5889b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t len; 5899b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu 5909b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu /* Note: The payload will carry 32bit size instead of size_t */ 5919b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu len = (size_t) bio_get_uint32(bio); 59294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (sz) 59394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *sz = len; 59494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return bio_get(bio, (len + 1) * sizeof(uint16_t)); 59594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 59694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 597bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescustatic struct flat_binder_object *_bio_get_obj(struct binder_io *bio) 59894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 5999b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t n; 6009b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu size_t off = bio->data - bio->data0; 60194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 60294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* TODO: be smarter about this? */ 60394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (n = 0; n < bio->offs_avail; n++) { 60494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bio->offs[n] == off) 605bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu return bio_get(bio, sizeof(struct flat_binder_object)); 60694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 60794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 60894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = 0; 60994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags |= BIO_F_OVERFLOW; 6109b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu return NULL; 61194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 61294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 61394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid *bio_get_ref(struct binder_io *bio) 61494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 615bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 61694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 61794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = _bio_get_obj(bio); 61894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!obj) 61994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 62094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 62194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (obj->type == BINDER_TYPE_HANDLE) 622bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu return obj->handle; 62394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 62494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 62594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 626