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