Home | History | Annotate | Download | only in servicemanager
      1 /* Copyright 2008 The Android Open Source Project
      2  */
      3 
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <errno.h>
      7 #include <unistd.h>
      8 #include <fcntl.h>
      9 #include <sys/mman.h>
     10 
     11 #include "binder.h"
     12 
     13 #define MAX_BIO_SIZE (1 << 30)
     14 
     15 #define TRACE 0
     16 
     17 #define LOG_TAG "Binder"
     18 #include <cutils/log.h>
     19 
     20 void bio_init_from_txn(struct binder_io *io, struct binder_txn *txn);
     21 
     22 #if TRACE
     23 void hexdump(void *_data, unsigned len)
     24 {
     25     unsigned char *data = _data;
     26     unsigned count;
     27 
     28     for (count = 0; count < len; count++) {
     29         if ((count & 15) == 0)
     30             fprintf(stderr,"%04x:", count);
     31         fprintf(stderr," %02x %c", *data,
     32                 (*data < 32) || (*data > 126) ? '.' : *data);
     33         data++;
     34         if ((count & 15) == 15)
     35             fprintf(stderr,"\n");
     36     }
     37     if ((count & 15) != 0)
     38         fprintf(stderr,"\n");
     39 }
     40 
     41 void binder_dump_txn(struct binder_txn *txn)
     42 {
     43     struct binder_object *obj;
     44     unsigned *offs = txn->offs;
     45     unsigned count = txn->offs_size / 4;
     46 
     47     fprintf(stderr,"  target %p  cookie %p  code %08x  flags %08x\n",
     48             txn->target, txn->cookie, txn->code, txn->flags);
     49     fprintf(stderr,"  pid %8d  uid %8d  data %8d  offs %8d\n",
     50             txn->sender_pid, txn->sender_euid, txn->data_size, txn->offs_size);
     51     hexdump(txn->data, txn->data_size);
     52     while (count--) {
     53         obj = (void*) (((char*) txn->data) + *offs++);
     54         fprintf(stderr,"  - type %08x  flags %08x  ptr %p  cookie %p\n",
     55                 obj->type, obj->flags, obj->pointer, obj->cookie);
     56     }
     57 }
     58 
     59 #define NAME(n) case n: return #n
     60 const char *cmd_name(uint32_t cmd)
     61 {
     62     switch(cmd) {
     63         NAME(BR_NOOP);
     64         NAME(BR_TRANSACTION_COMPLETE);
     65         NAME(BR_INCREFS);
     66         NAME(BR_ACQUIRE);
     67         NAME(BR_RELEASE);
     68         NAME(BR_DECREFS);
     69         NAME(BR_TRANSACTION);
     70         NAME(BR_REPLY);
     71         NAME(BR_FAILED_REPLY);
     72         NAME(BR_DEAD_REPLY);
     73         NAME(BR_DEAD_BINDER);
     74     default: return "???";
     75     }
     76 }
     77 #else
     78 #define hexdump(a,b) do{} while (0)
     79 #define binder_dump_txn(txn)  do{} while (0)
     80 #endif
     81 
     82 #define BIO_F_SHARED    0x01  /* needs to be buffer freed */
     83 #define BIO_F_OVERFLOW  0x02  /* ran out of space */
     84 #define BIO_F_IOERROR   0x04
     85 #define BIO_F_MALLOCED  0x08  /* needs to be free()'d */
     86 
     87 struct binder_state
     88 {
     89     int fd;
     90     void *mapped;
     91     unsigned mapsize;
     92 };
     93 
     94 struct binder_state *binder_open(unsigned mapsize)
     95 {
     96     struct binder_state *bs;
     97 
     98     bs = malloc(sizeof(*bs));
     99     if (!bs) {
    100         errno = ENOMEM;
    101         return 0;
    102     }
    103 
    104     bs->fd = open("/dev/binder", O_RDWR);
    105     if (bs->fd < 0) {
    106         fprintf(stderr,"binder: cannot open device (%s)\n",
    107                 strerror(errno));
    108         goto fail_open;
    109     }
    110 
    111     bs->mapsize = mapsize;
    112     bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    113     if (bs->mapped == MAP_FAILED) {
    114         fprintf(stderr,"binder: cannot map device (%s)\n",
    115                 strerror(errno));
    116         goto fail_map;
    117     }
    118 
    119         /* TODO: check version */
    120 
    121     return bs;
    122 
    123 fail_map:
    124     close(bs->fd);
    125 fail_open:
    126     free(bs);
    127     return 0;
    128 }
    129 
    130 void binder_close(struct binder_state *bs)
    131 {
    132     munmap(bs->mapped, bs->mapsize);
    133     close(bs->fd);
    134     free(bs);
    135 }
    136 
    137 int binder_become_context_manager(struct binder_state *bs)
    138 {
    139     return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
    140 }
    141 
    142 int binder_write(struct binder_state *bs, void *data, unsigned len)
    143 {
    144     struct binder_write_read bwr;
    145     int res;
    146     bwr.write_size = len;
    147     bwr.write_consumed = 0;
    148     bwr.write_buffer = (unsigned) data;
    149     bwr.read_size = 0;
    150     bwr.read_consumed = 0;
    151     bwr.read_buffer = 0;
    152     res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    153     if (res < 0) {
    154         fprintf(stderr,"binder_write: ioctl failed (%s)\n",
    155                 strerror(errno));
    156     }
    157     return res;
    158 }
    159 
    160 void binder_send_reply(struct binder_state *bs,
    161                        struct binder_io *reply,
    162                        void *buffer_to_free,
    163                        int status)
    164 {
    165     struct {
    166         uint32_t cmd_free;
    167         void *buffer;
    168         uint32_t cmd_reply;
    169         struct binder_txn txn;
    170     } __attribute__((packed)) data;
    171 
    172     data.cmd_free = BC_FREE_BUFFER;
    173     data.buffer = buffer_to_free;
    174     data.cmd_reply = BC_REPLY;
    175     data.txn.target = 0;
    176     data.txn.cookie = 0;
    177     data.txn.code = 0;
    178     if (status) {
    179         data.txn.flags = TF_STATUS_CODE;
    180         data.txn.data_size = sizeof(int);
    181         data.txn.offs_size = 0;
    182         data.txn.data = &status;
    183         data.txn.offs = 0;
    184     } else {
    185         data.txn.flags = 0;
    186         data.txn.data_size = reply->data - reply->data0;
    187         data.txn.offs_size = ((char*) reply->offs) - ((char*) reply->offs0);
    188         data.txn.data = reply->data0;
    189         data.txn.offs = reply->offs0;
    190     }
    191     binder_write(bs, &data, sizeof(data));
    192 }
    193 
    194 int binder_parse(struct binder_state *bs, struct binder_io *bio,
    195                  uint32_t *ptr, uint32_t size, binder_handler func)
    196 {
    197     int r = 1;
    198     uint32_t *end = ptr + (size / 4);
    199 
    200     while (ptr < end) {
    201         uint32_t cmd = *ptr++;
    202 #if TRACE
    203         fprintf(stderr,"%s:\n", cmd_name(cmd));
    204 #endif
    205         switch(cmd) {
    206         case BR_NOOP:
    207             break;
    208         case BR_TRANSACTION_COMPLETE:
    209             break;
    210         case BR_INCREFS:
    211         case BR_ACQUIRE:
    212         case BR_RELEASE:
    213         case BR_DECREFS:
    214 #if TRACE
    215             fprintf(stderr,"  %08x %08x\n", ptr[0], ptr[1]);
    216 #endif
    217             ptr += 2;
    218             break;
    219         case BR_TRANSACTION: {
    220             struct binder_txn *txn = (void *) ptr;
    221             if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
    222                 ALOGE("parse: txn too small!\n");
    223                 return -1;
    224             }
    225             binder_dump_txn(txn);
    226             if (func) {
    227                 unsigned rdata[256/4];
    228                 struct binder_io msg;
    229                 struct binder_io reply;
    230                 int res;
    231 
    232                 bio_init(&reply, rdata, sizeof(rdata), 4);
    233                 bio_init_from_txn(&msg, txn);
    234                 res = func(bs, txn, &msg, &reply);
    235                 binder_send_reply(bs, &reply, txn->data, res);
    236             }
    237             ptr += sizeof(*txn) / sizeof(uint32_t);
    238             break;
    239         }
    240         case BR_REPLY: {
    241             struct binder_txn *txn = (void*) ptr;
    242             if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
    243                 ALOGE("parse: reply too small!\n");
    244                 return -1;
    245             }
    246             binder_dump_txn(txn);
    247             if (bio) {
    248                 bio_init_from_txn(bio, txn);
    249                 bio = 0;
    250             } else {
    251                     /* todo FREE BUFFER */
    252             }
    253             ptr += (sizeof(*txn) / sizeof(uint32_t));
    254             r = 0;
    255             break;
    256         }
    257         case BR_DEAD_BINDER: {
    258             struct binder_death *death = (void*) *ptr++;
    259             death->func(bs, death->ptr);
    260             break;
    261         }
    262         case BR_FAILED_REPLY:
    263             r = -1;
    264             break;
    265         case BR_DEAD_REPLY:
    266             r = -1;
    267             break;
    268         default:
    269             ALOGE("parse: OOPS %d\n", cmd);
    270             return -1;
    271         }
    272     }
    273 
    274     return r;
    275 }
    276 
    277 void binder_acquire(struct binder_state *bs, void *ptr)
    278 {
    279     uint32_t cmd[2];
    280     cmd[0] = BC_ACQUIRE;
    281     cmd[1] = (uint32_t) ptr;
    282     binder_write(bs, cmd, sizeof(cmd));
    283 }
    284 
    285 void binder_release(struct binder_state *bs, void *ptr)
    286 {
    287     uint32_t cmd[2];
    288     cmd[0] = BC_RELEASE;
    289     cmd[1] = (uint32_t) ptr;
    290     binder_write(bs, cmd, sizeof(cmd));
    291 }
    292 
    293 void binder_link_to_death(struct binder_state *bs, void *ptr, struct binder_death *death)
    294 {
    295     uint32_t cmd[3];
    296     cmd[0] = BC_REQUEST_DEATH_NOTIFICATION;
    297     cmd[1] = (uint32_t) ptr;
    298     cmd[2] = (uint32_t) death;
    299     binder_write(bs, cmd, sizeof(cmd));
    300 }
    301 
    302 
    303 int binder_call(struct binder_state *bs,
    304                 struct binder_io *msg, struct binder_io *reply,
    305                 void *target, uint32_t code)
    306 {
    307     int res;
    308     struct binder_write_read bwr;
    309     struct {
    310         uint32_t cmd;
    311         struct binder_txn txn;
    312     } writebuf;
    313     unsigned readbuf[32];
    314 
    315     if (msg->flags & BIO_F_OVERFLOW) {
    316         fprintf(stderr,"binder: txn buffer overflow\n");
    317         goto fail;
    318     }
    319 
    320     writebuf.cmd = BC_TRANSACTION;
    321     writebuf.txn.target = target;
    322     writebuf.txn.code = code;
    323     writebuf.txn.flags = 0;
    324     writebuf.txn.data_size = msg->data - msg->data0;
    325     writebuf.txn.offs_size = ((char*) msg->offs) - ((char*) msg->offs0);
    326     writebuf.txn.data = msg->data0;
    327     writebuf.txn.offs = msg->offs0;
    328 
    329     bwr.write_size = sizeof(writebuf);
    330     bwr.write_consumed = 0;
    331     bwr.write_buffer = (unsigned) &writebuf;
    332 
    333     hexdump(msg->data0, msg->data - msg->data0);
    334     for (;;) {
    335         bwr.read_size = sizeof(readbuf);
    336         bwr.read_consumed = 0;
    337         bwr.read_buffer = (unsigned) readbuf;
    338 
    339         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    340 
    341         if (res < 0) {
    342             fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));
    343             goto fail;
    344         }
    345 
    346         res = binder_parse(bs, reply, readbuf, bwr.read_consumed, 0);
    347         if (res == 0) return 0;
    348         if (res < 0) goto fail;
    349     }
    350 
    351 fail:
    352     memset(reply, 0, sizeof(*reply));
    353     reply->flags |= BIO_F_IOERROR;
    354     return -1;
    355 }
    356 
    357 void binder_loop(struct binder_state *bs, binder_handler func)
    358 {
    359     int res;
    360     struct binder_write_read bwr;
    361     unsigned readbuf[32];
    362 
    363     bwr.write_size = 0;
    364     bwr.write_consumed = 0;
    365     bwr.write_buffer = 0;
    366 
    367     readbuf[0] = BC_ENTER_LOOPER;
    368     binder_write(bs, readbuf, sizeof(unsigned));
    369 
    370     for (;;) {
    371         bwr.read_size = sizeof(readbuf);
    372         bwr.read_consumed = 0;
    373         bwr.read_buffer = (unsigned) readbuf;
    374 
    375         res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    376 
    377         if (res < 0) {
    378             ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
    379             break;
    380         }
    381 
    382         res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
    383         if (res == 0) {
    384             ALOGE("binder_loop: unexpected reply?!\n");
    385             break;
    386         }
    387         if (res < 0) {
    388             ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
    389             break;
    390         }
    391     }
    392 }
    393 
    394 void bio_init_from_txn(struct binder_io *bio, struct binder_txn *txn)
    395 {
    396     bio->data = bio->data0 = txn->data;
    397     bio->offs = bio->offs0 = txn->offs;
    398     bio->data_avail = txn->data_size;
    399     bio->offs_avail = txn->offs_size / 4;
    400     bio->flags = BIO_F_SHARED;
    401 }
    402 
    403 void bio_init(struct binder_io *bio, void *data,
    404               uint32_t maxdata, uint32_t maxoffs)
    405 {
    406     uint32_t n = maxoffs * sizeof(uint32_t);
    407 
    408     if (n > maxdata) {
    409         bio->flags = BIO_F_OVERFLOW;
    410         bio->data_avail = 0;
    411         bio->offs_avail = 0;
    412         return;
    413     }
    414 
    415     bio->data = bio->data0 = (char *) data + n;
    416     bio->offs = bio->offs0 = data;
    417     bio->data_avail = maxdata - n;
    418     bio->offs_avail = maxoffs;
    419     bio->flags = 0;
    420 }
    421 
    422 static void *bio_alloc(struct binder_io *bio, uint32_t size)
    423 {
    424     size = (size + 3) & (~3);
    425     if (size > bio->data_avail) {
    426         bio->flags |= BIO_F_OVERFLOW;
    427         return 0;
    428     } else {
    429         void *ptr = bio->data;
    430         bio->data += size;
    431         bio->data_avail -= size;
    432         return ptr;
    433     }
    434 }
    435 
    436 void binder_done(struct binder_state *bs,
    437                  struct binder_io *msg,
    438                  struct binder_io *reply)
    439 {
    440     if (reply->flags & BIO_F_SHARED) {
    441         uint32_t cmd[2];
    442         cmd[0] = BC_FREE_BUFFER;
    443         cmd[1] = (uint32_t) reply->data0;
    444         binder_write(bs, cmd, sizeof(cmd));
    445         reply->flags = 0;
    446     }
    447 }
    448 
    449 static struct binder_object *bio_alloc_obj(struct binder_io *bio)
    450 {
    451     struct binder_object *obj;
    452 
    453     obj = bio_alloc(bio, sizeof(*obj));
    454 
    455     if (obj && bio->offs_avail) {
    456         bio->offs_avail--;
    457         *bio->offs++ = ((char*) obj) - ((char*) bio->data0);
    458         return obj;
    459     }
    460 
    461     bio->flags |= BIO_F_OVERFLOW;
    462     return 0;
    463 }
    464 
    465 void bio_put_uint32(struct binder_io *bio, uint32_t n)
    466 {
    467     uint32_t *ptr = bio_alloc(bio, sizeof(n));
    468     if (ptr)
    469         *ptr = n;
    470 }
    471 
    472 void bio_put_obj(struct binder_io *bio, void *ptr)
    473 {
    474     struct binder_object *obj;
    475 
    476     obj = bio_alloc_obj(bio);
    477     if (!obj)
    478         return;
    479 
    480     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    481     obj->type = BINDER_TYPE_BINDER;
    482     obj->pointer = ptr;
    483     obj->cookie = 0;
    484 }
    485 
    486 void bio_put_ref(struct binder_io *bio, void *ptr)
    487 {
    488     struct binder_object *obj;
    489 
    490     if (ptr)
    491         obj = bio_alloc_obj(bio);
    492     else
    493         obj = bio_alloc(bio, sizeof(*obj));
    494 
    495     if (!obj)
    496         return;
    497 
    498     obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    499     obj->type = BINDER_TYPE_HANDLE;
    500     obj->pointer = ptr;
    501     obj->cookie = 0;
    502 }
    503 
    504 void bio_put_string16(struct binder_io *bio, const uint16_t *str)
    505 {
    506     uint32_t len;
    507     uint16_t *ptr;
    508 
    509     if (!str) {
    510         bio_put_uint32(bio, 0xffffffff);
    511         return;
    512     }
    513 
    514     len = 0;
    515     while (str[len]) len++;
    516 
    517     if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
    518         bio_put_uint32(bio, 0xffffffff);
    519         return;
    520     }
    521 
    522     bio_put_uint32(bio, len);
    523     len = (len + 1) * sizeof(uint16_t);
    524     ptr = bio_alloc(bio, len);
    525     if (ptr)
    526         memcpy(ptr, str, len);
    527 }
    528 
    529 void bio_put_string16_x(struct binder_io *bio, const char *_str)
    530 {
    531     unsigned char *str = (unsigned char*) _str;
    532     uint32_t len;
    533     uint16_t *ptr;
    534 
    535     if (!str) {
    536         bio_put_uint32(bio, 0xffffffff);
    537         return;
    538     }
    539 
    540     len = strlen(_str);
    541 
    542     if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
    543         bio_put_uint32(bio, 0xffffffff);
    544         return;
    545     }
    546 
    547     bio_put_uint32(bio, len);
    548     ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t));
    549     if (!ptr)
    550         return;
    551 
    552     while (*str)
    553         *ptr++ = *str++;
    554     *ptr++ = 0;
    555 }
    556 
    557 static void *bio_get(struct binder_io *bio, uint32_t size)
    558 {
    559     size = (size + 3) & (~3);
    560 
    561     if (bio->data_avail < size){
    562         bio->data_avail = 0;
    563         bio->flags |= BIO_F_OVERFLOW;
    564         return 0;
    565     }  else {
    566         void *ptr = bio->data;
    567         bio->data += size;
    568         bio->data_avail -= size;
    569         return ptr;
    570     }
    571 }
    572 
    573 uint32_t bio_get_uint32(struct binder_io *bio)
    574 {
    575     uint32_t *ptr = bio_get(bio, sizeof(*ptr));
    576     return ptr ? *ptr : 0;
    577 }
    578 
    579 uint16_t *bio_get_string16(struct binder_io *bio, unsigned *sz)
    580 {
    581     unsigned len;
    582     len = bio_get_uint32(bio);
    583     if (sz)
    584         *sz = len;
    585     return bio_get(bio, (len + 1) * sizeof(uint16_t));
    586 }
    587 
    588 static struct binder_object *_bio_get_obj(struct binder_io *bio)
    589 {
    590     unsigned n;
    591     unsigned off = bio->data - bio->data0;
    592 
    593         /* TODO: be smarter about this? */
    594     for (n = 0; n < bio->offs_avail; n++) {
    595         if (bio->offs[n] == off)
    596             return bio_get(bio, sizeof(struct binder_object));
    597     }
    598 
    599     bio->data_avail = 0;
    600     bio->flags |= BIO_F_OVERFLOW;
    601     return 0;
    602 }
    603 
    604 void *bio_get_ref(struct binder_io *bio)
    605 {
    606     struct binder_object *obj;
    607 
    608     obj = _bio_get_obj(bio);
    609     if (!obj)
    610         return 0;
    611 
    612     if (obj->type == BINDER_TYPE_HANDLE)
    613         return obj->pointer;
    614 
    615     return 0;
    616 }
    617