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