binder.c revision bcf38880c65297da58194eb0c0ce8d6e2bab7d94
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 2394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid hexdump(void *_data, unsigned len) 2494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned char *data = _data; 2694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned count; 2794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (count = 0; count < len; count++) { 2994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((count & 15) == 0) 3094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"%04x:", 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; 44bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu unsigned *offs = txn->data.ptr.offsets; 45bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu unsigned count = txn->offsets_size / 4; 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; 9194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned mapsize; 9294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 9394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 9494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct binder_state *binder_open(unsigned mapsize) 9594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 9694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_state *bs; 9794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 9894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs = malloc(sizeof(*bs)); 9994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!bs) { 10094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood errno = ENOMEM; 10194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 10294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 10394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 10494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs->fd = open("/dev/binder", O_RDWR); 10594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bs->fd < 0) { 10694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder: cannot open device (%s)\n", 10794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strerror(errno)); 10894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail_open; 10994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 11094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 11194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs->mapsize = mapsize; 11294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); 11394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bs->mapped == MAP_FAILED) { 11494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder: cannot map device (%s)\n", 11594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strerror(errno)); 11694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail_map; 11794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 11894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 11994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* TODO: check version */ 12094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 12194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return bs; 12294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 12394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail_map: 12494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood close(bs->fd); 12594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail_open: 12694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(bs); 12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 12894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 12994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_close(struct binder_state *bs) 13194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 13294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood munmap(bs->mapped, bs->mapsize); 13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood close(bs->fd); 13494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(bs); 13594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint binder_become_context_manager(struct binder_state *bs) 13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); 14094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 14194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint binder_write(struct binder_state *bs, void *data, unsigned len) 14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_write_read bwr; 14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_size = len; 14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_consumed = 0; 14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_buffer = (unsigned) data; 14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_size = 0; 15094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_consumed = 0; 15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_buffer = 0; 15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) { 15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder_write: ioctl failed (%s)\n", 15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood strerror(errno)); 15694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 15794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 15894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_send_reply(struct binder_state *bs, 16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *reply, 16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *buffer_to_free, 16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int status) 16494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct { 16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd_free; 16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *buffer; 16894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd_reply; 169bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data txn; 17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } __attribute__((packed)) data; 17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 17294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.cmd_free = BC_FREE_BUFFER; 17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.buffer = buffer_to_free; 17494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.cmd_reply = BC_REPLY; 175bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.target.ptr = 0; 17694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.cookie = 0; 17794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.code = 0; 17894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (status) { 17994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.flags = TF_STATUS_CODE; 18094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.data_size = sizeof(int); 181bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.offsets_size = 0; 182bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.data.ptr.buffer = &status; 183bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.data.ptr.offsets = 0; 18494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 18594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.flags = 0; 18694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood data.txn.data_size = reply->data - reply->data0; 187bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0); 188bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.data.ptr.buffer = reply->data0; 189bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu data.txn.data.ptr.offsets = reply->offs0; 19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, &data, sizeof(data)); 19294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 19394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 19494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint binder_parse(struct binder_state *bs, struct binder_io *bio, 19594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t *ptr, uint32_t size, binder_handler func) 19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int r = 1; 19894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t *end = ptr + (size / 4); 19994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 20094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (ptr < end) { 20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd = *ptr++; 20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if TRACE 20394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"%s:\n", cmd_name(cmd)); 20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 20594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood switch(cmd) { 20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_NOOP: 20794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_TRANSACTION_COMPLETE: 20994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_INCREFS: 21194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_ACQUIRE: 21294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_RELEASE: 21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_DECREFS: 21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if TRACE 21594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr," %08x %08x\n", ptr[0], ptr[1]); 21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif 21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr += 2; 21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 21994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_TRANSACTION: { 220bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr; 221bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu if ((end - ptr) * sizeof(uint32_t) < sizeof(*txn)) { 22294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("parse: txn too small!\n"); 22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 22494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 22594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_dump_txn(txn); 22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (func) { 22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned rdata[256/4]; 22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io msg; 22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io reply; 23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 23294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_init(&reply, rdata, sizeof(rdata), 4); 23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_init_from_txn(&msg, txn); 23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = func(bs, txn, &msg, &reply); 235bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu binder_send_reply(bs, &reply, txn->data.ptr.buffer, res); 23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr += sizeof(*txn) / sizeof(uint32_t); 23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 23994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 24094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_REPLY: { 241bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr; 242bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu if ((end - ptr) * sizeof(uint32_t) < sizeof(*txn)) { 24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("parse: reply too small!\n"); 24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 24694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_dump_txn(txn); 24794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bio) { 24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_init_from_txn(bio, txn); 24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio = 0; 25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* todo FREE BUFFER */ 25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr += (sizeof(*txn) / sizeof(uint32_t)); 25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = 0; 25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_DEAD_BINDER: { 25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_death *death = (void*) *ptr++; 25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood death->func(bs, death->ptr); 26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_FAILED_REPLY: 26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = -1; 26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood case BR_DEAD_REPLY: 26694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = -1; 26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood default: 26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("parse: OOPS %d\n", cmd); 27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return r; 27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_acquire(struct binder_state *bs, void *ptr) 27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd[2]; 28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[0] = BC_ACQUIRE; 28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[1] = (uint32_t) ptr; 28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, cmd, sizeof(cmd)); 28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_release(struct binder_state *bs, void *ptr) 28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd[2]; 28894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[0] = BC_RELEASE; 28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[1] = (uint32_t) ptr; 29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, cmd, sizeof(cmd)); 29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 29294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 29394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_link_to_death(struct binder_state *bs, void *ptr, struct binder_death *death) 29494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 29594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd[3]; 29694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[0] = BC_REQUEST_DEATH_NOTIFICATION; 29794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[1] = (uint32_t) ptr; 29894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[2] = (uint32_t) death; 29994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, cmd, sizeof(cmd)); 30094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 30194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint binder_call(struct binder_state *bs, 30494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *msg, struct binder_io *reply, 30594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *target, uint32_t code) 30694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 30794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 30894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_write_read bwr; 30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct { 31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd; 311bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct binder_transaction_data txn; 31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } writebuf; 31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned readbuf[32]; 31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (msg->flags & BIO_F_OVERFLOW) { 31694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder: txn buffer overflow\n"); 31794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 31894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 31994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 32094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writebuf.cmd = BC_TRANSACTION; 321bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu writebuf.txn.target.handle = target; 32294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writebuf.txn.code = code; 32394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writebuf.txn.flags = 0; 32494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood writebuf.txn.data_size = msg->data - msg->data0; 325bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0); 326bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu writebuf.txn.data.ptr.buffer = msg->data0; 327bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu writebuf.txn.data.ptr.offsets = msg->offs0; 32894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 32994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_size = sizeof(writebuf); 33094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_consumed = 0; 33194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_buffer = (unsigned) &writebuf; 33294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 33394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood hexdump(msg->data0, msg->data - msg->data0); 33494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 33594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_size = sizeof(readbuf); 33694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_consumed = 0; 33794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_buffer = (unsigned) readbuf; 33894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 33994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 34094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 34194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) { 34294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno)); 34394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 34494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 34594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 34694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = binder_parse(bs, reply, readbuf, bwr.read_consumed, 0); 34794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res == 0) return 0; 34894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) goto fail; 34994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail: 35294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memset(reply, 0, sizeof(*reply)); 35394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reply->flags |= BIO_F_IOERROR; 35494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 35594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 35694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_loop(struct binder_state *bs, binder_handler func) 35894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 35994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res; 36094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_write_read bwr; 36194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned readbuf[32]; 36294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_size = 0; 36494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_consumed = 0; 36594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.write_buffer = 0; 36694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood readbuf[0] = BC_ENTER_LOOPER; 36894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, readbuf, sizeof(unsigned)); 36994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 37194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_size = sizeof(readbuf); 37294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_consumed = 0; 37394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bwr.read_buffer = (unsigned) readbuf; 37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 37694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) { 37894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno)); 37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 38194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func); 38394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res == 0) { 38494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("binder_loop: unexpected reply?!\n"); 38594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 38694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (res < 0) { 38894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("binder_loop: io error %d %s\n", res, strerror(errno)); 38994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 39094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 39394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 394bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescuvoid bio_init_from_txn(struct binder_io *bio, struct binder_transaction_data *txn) 39594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 396bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu bio->data = bio->data0 = txn->data.ptr.buffer; 397bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu bio->offs = bio->offs0 = txn->data.ptr.offsets; 39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = txn->data_size; 399bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu bio->offs_avail = txn->offsets_size / 4; 40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags = BIO_F_SHARED; 40194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 40294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_init(struct binder_io *bio, void *data, 40494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t maxdata, uint32_t maxoffs) 40594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 40694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t n = maxoffs * sizeof(uint32_t); 40794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 40894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n > maxdata) { 40994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags = BIO_F_OVERFLOW; 41094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = 0; 41194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->offs_avail = 0; 41294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 41394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 41494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 41594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data = bio->data0 = (char *) data + n; 41694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->offs = bio->offs0 = data; 41794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = maxdata - n; 41894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->offs_avail = maxoffs; 41994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags = 0; 42094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void *bio_alloc(struct binder_io *bio, uint32_t size) 42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size = (size + 3) & (~3); 42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (size > bio->data_avail) { 42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags |= BIO_F_OVERFLOW; 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *ptr = bio->data; 43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data += size; 43194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail -= size; 43294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ptr; 43394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 43494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 43594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 43694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid binder_done(struct binder_state *bs, 43794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *msg, 43894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct binder_io *reply) 43994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 44094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (reply->flags & BIO_F_SHARED) { 44194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t cmd[2]; 44294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[0] = BC_FREE_BUFFER; 44394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmd[1] = (uint32_t) reply->data0; 44494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood binder_write(bs, cmd, sizeof(cmd)); 44594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reply->flags = 0; 44694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 44794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 44894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 449bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescustatic struct flat_binder_object *bio_alloc_obj(struct binder_io *bio) 45094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 451bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 45294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = bio_alloc(bio, sizeof(*obj)); 45494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (obj && bio->offs_avail) { 45694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->offs_avail--; 45794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *bio->offs++ = ((char*) obj) - ((char*) bio->data0); 45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return obj; 45994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 46094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags |= BIO_F_OVERFLOW; 46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 46594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_uint32(struct binder_io *bio, uint32_t n) 46694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 46794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t *ptr = bio_alloc(bio, sizeof(n)); 46894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ptr) 46994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *ptr = n; 47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 47194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 47294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_obj(struct binder_io *bio, void *ptr) 47394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 474bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 47594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 47694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = bio_alloc_obj(bio); 47794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!obj) 47894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 47994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 48194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->type = BINDER_TYPE_BINDER; 482bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu obj->binder = ptr; 48394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->cookie = 0; 48494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 48594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_ref(struct binder_io *bio, void *ptr) 48794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 488bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ptr) 49194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = bio_alloc_obj(bio); 49294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood else 49394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = bio_alloc(bio, sizeof(*obj)); 49494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!obj) 49694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 49994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->type = BINDER_TYPE_HANDLE; 500bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu obj->handle = ptr; 50194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj->cookie = 0; 50294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 50394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_string16(struct binder_io *bio, const uint16_t *str) 50594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 50694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t len; 50794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t *ptr; 50894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!str) { 51094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, 0xffffffff); 51194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 51294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood len = 0; 51594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (str[len]) len++; 51694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) { 51894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, 0xffffffff); 51994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 52094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 52194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 52294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, len); 52394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood len = (len + 1) * sizeof(uint16_t); 52494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr = bio_alloc(bio, len); 52594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (ptr) 52694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood memcpy(ptr, str, len); 52794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 52894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 52994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid bio_put_string16_x(struct binder_io *bio, const char *_str) 53094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 53194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned char *str = (unsigned char*) _str; 53294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t len; 53394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint16_t *ptr; 53494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 53594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!str) { 53694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, 0xffffffff); 53794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 53894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 53994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood len = strlen(_str); 54194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) { 54394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, 0xffffffff); 54494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 54594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 54694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio_put_uint32(bio, len); 54894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t)); 54994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!ptr) 55094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return; 55194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*str) 55394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *ptr++ = *str++; 55494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *ptr++ = 0; 55594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 55694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic void *bio_get(struct binder_io *bio, uint32_t size) 55894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 55994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood size = (size + 3) & (~3); 56094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 56194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bio->data_avail < size){ 56294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = 0; 56394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags |= BIO_F_OVERFLOW; 56494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 56594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 56694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood void *ptr = bio->data; 56794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data += size; 56894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail -= size; 56994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ptr; 57094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 57194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 57294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooduint32_t bio_get_uint32(struct binder_io *bio) 57494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 57594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood uint32_t *ptr = bio_get(bio, sizeof(*ptr)); 57694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return ptr ? *ptr : 0; 57794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 57894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooduint16_t *bio_get_string16(struct binder_io *bio, unsigned *sz) 58094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 58194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned len; 58294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood len = bio_get_uint32(bio); 58394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (sz) 58494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *sz = len; 58594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return bio_get(bio, (len + 1) * sizeof(uint16_t)); 58694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 58794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 588bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescustatic struct flat_binder_object *_bio_get_obj(struct binder_io *bio) 58994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 59094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned n; 59194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned off = bio->data - bio->data0; 59294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 59394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* TODO: be smarter about this? */ 59494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (n = 0; n < bio->offs_avail; n++) { 59594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (bio->offs[n] == off) 596bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu return bio_get(bio, sizeof(struct flat_binder_object)); 59794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 59894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 59994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->data_avail = 0; 60094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood bio->flags |= BIO_F_OVERFLOW; 60194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 60294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 60394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 60494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid *bio_get_ref(struct binder_io *bio) 60594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 606bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu struct flat_binder_object *obj; 60794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 60894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood obj = _bio_get_obj(bio); 60994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!obj) 61094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 61194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 61294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (obj->type == BINDER_TYPE_HANDLE) 613bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu return obj->handle; 61494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 61594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 61694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 617