/* * Copyright (c) 1991, 1992 Paul Kranenburg * Copyright (c) 1993 Branko Lankester * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey * Copyright (c) 2007 Adrian Taylor * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: time.c,v 1.19 2007/01/13 11:17:38 ldv Exp $ */ #include "defs.h" #include #include #ifdef LINUX #include #include #include #endif /* LINUX */ typedef unsigned int u32; void dump_bytes(data, size) char* data; unsigned long size; { int i; tprintf("["); for (i=0;i= '!' && data[i] <= '~') tprintf("%c", data[i]); else tprintf("."); } tprintf("]"); } void dump_data(tcp, buffer, size) struct tcb *tcp; signed long buffer; unsigned long size; { char* data = malloc(size); if (data != NULL) { if (umoven(tcp,buffer,size,data) == 0) { char* location = data; tprintf("["); while (location < data+size) { u32 cmd; cmd = *((u32*)location); location+=sizeof(u32); switch (cmd) { case bcINCREFS: { u32 object; object = *((u32*)location); location+=sizeof(u32); tprintf("bcINCREFS(target=0x%08x)",object); break; } case bcINCREFS_DONE: { void* ptr; void* cookie; ptr = *((void**)location); location+=sizeof(void*); cookie = *((void**)location); location+=sizeof(void*); tprintf("bcINCREFS_DONE(ptr=0x%08x,cookie=0x%08x)",(u32)ptr,(u32)cookie); break; } case bcACQUIRE: { u32 object; object = *((u32*)location); location+=sizeof(u32); tprintf("bcACQUIRE(target=0x%08x)",object); break; } case bcACQUIRE_DONE: { void* ptr; void* cookie; ptr = *((void**)location); location+=sizeof(void*); cookie = *((void**)location); location+=sizeof(void*); tprintf("bcACQUIRE_DONE(ptr=0x%08x,cookie=0x%08x)",(u32)ptr,(u32)cookie); break; } case bcATTEMPT_ACQUIRE: { u32 priority; u32 target; priority = *((u32*)location); location+=sizeof(u32); target = *((u32*)location); location+=sizeof(u32); tprintf("bcATTEMPT_ACQUIRE(priority=0x%08x,target=0x%08x)",priority,target); break; } case bcACQUIRE_RESULT: { u32 result; result = *((u32*)location); location+=sizeof(u32); tprintf("bcACQUIRE_RESULT(result=0x%08x)",result); break; } case bcRELEASE: { u32 object; object = *((u32*)location); location+=sizeof(u32); tprintf("bcRELEASE(target=0x%08x)",object); break; } case bcDECREFS: { u32 object; object = *((u32*)location); location+=sizeof(u32); tprintf("bcDECREFS(target=0x%08x)",object); break; } case bcFREE_BUFFER: { void* ptr; ptr = *((void**)location); location+=sizeof(void*); tprintf("bcFREE_BUFFER(ptr=0x%08x)",(u32)ptr); break; } case bcRETRIEVE_ROOT_OBJECT: { u32 object; object = *((u32*)location); location+=sizeof(u32); tprintf("bcRETRIEVE_ROOT_OBJECT(pid=%d)",object); break; } case bcTRANSACTION: case bcREPLY: { binder_transaction_data_t* transaction; transaction = ((binder_transaction_data_t*)location); location += sizeof(binder_transaction_data_t); if (cmd == bcTRANSACTION) tprintf("bcTRANSACTION({"); else tprintf("bcREPLY({"); tprintf("cookie=0x%08x,code=0x%08x,flags=0x%08x,priority=%d,data_size=%d,offsets_size=%d,data=",(u32)transaction->cookie,transaction->code,transaction->flags,transaction->priority,transaction->data_size,transaction->offsets_size); if (transaction->flags & tfInline) { dump_bytes(transaction->data.buf,8); } else { char* transdata; tprintf("{buffer=0x%08x,offsets=0x%08x,*buffer=",(u32)transaction->data.ptr.buffer,(u32)transaction->data.ptr.offsets); transdata=malloc(transaction->data_size); if (transdata != NULL) { if (umoven(tcp,(u32)transaction->data.ptr.buffer,transaction->data_size,transdata) == 0) { dump_bytes(transdata,transaction->data_size); } else tprintf("[...]"); free(transdata); } tprintf("}"); } tprintf("})"); break; } case bcREGISTER_LOOPER: { tprintf("bcREGISTER_LOOPER()"); break; } case bcENTER_LOOPER: { tprintf("bcENTER_LOOPER()"); break; } case bcEXIT_LOOPER: { tprintf("bcEXIT_LOOPER()"); break; } /*case bcCATCH_ROOT_OBJECTS: { tprintf("bcCATCH_ROOT_OBJECTS()"); break; }*/ case bcSTOP_PROCESS: { u32 target; u32 now; target = *((u32*)location); location+=sizeof(u32); now = *((u32*)location); location+=sizeof(u32); tprintf("bcSTOP_PROCESS(target=0x%08x,now=0x%08x)",target,now); break; } case bcSTOP_SELF: { u32 now; now = *((u32*)location); location+=sizeof(u32); tprintf("bcSTOP_SELF(now=0x%08x)",now); break; } case bcREQUEST_DEATH_NOTIFICATION: { u32 target; void* cookie; target = *((u32*)location); location+=sizeof(u32); cookie = *((void**)location); location+=sizeof(void*); tprintf("bcREQUEST_DEATH_NOTIFICATION(target=0x%08x,cookie=0x%08x)",target,(u32)cookie); break; } case bcCLEAR_DEATH_NOTIFICATION: { u32 target; void* cookie; target = *((u32*)location); location+=sizeof(u32); cookie = *((void**)location); location+=sizeof(void*); tprintf("bcCLEAR_DEATH_NOTIFICATION(target=0x%08x,cookie=0x%08x)",target,(u32)cookie); break; } case bcDEAD_BINDER_DONE: { void* cookie; cookie = *((void**)location); location+=sizeof(void*); tprintf("bcDEAD_BINDER_DONE(cookie=0x%08x)",(u32)cookie); break; } } } tprintf("]"); } else tprintf("{...}"); free(data); } else tprintf("{...}"); } int openbinder_ioctl(tcp, code, arg) struct tcb *tcp; long code; long arg; { switch (code) { case BINDER_WRITE_READ: if (exiting(tcp)) { binder_write_read_t wk; if (syserror(tcp) || umove(tcp,arg,&wk) < 0) tprintf(", %#lx", arg); else { tprintf(", {write_size=%ld,write_consumed=%ld,write_buffer=0x%lx,read_size=%ld,read_consumed=%ld,read_buffer=0x%lx",wk.write_size,wk.write_consumed,wk.write_buffer,wk.read_size,wk.read_consumed,wk.read_buffer); tprintf(",write_data="); dump_data(tcp,wk.write_buffer,wk.write_size); tprintf(",read_data={...}"); } } break; default: break; } return 1; }