This patch introduce decoding for binder ioctls including the command and return protocol from BINDER_WRITE_READ.
* binder.c: New file. * xlat/binder_driver_commands.in: New file. * xlat/binder_driver_returns.in: New file. * Makefile.am (strace_SOURCES): Add binder.c. * ioctl.c (ioctl_decode): Call binder_ioctl for 'b' ioctl commands. * defs.h (binder_ioctl): New prototype. * configure.ac: Check binder header. Signed-off-by: Antoine Damhet <antoine.dam...@lse.epita.fr> Reviewed-by: Gabriel Laskar <gabr...@lse.epita.fr> --- Makefile.am | 1 + binder.c | 162 +++++++++++++++++++++++++++++++++++++++++ configure.ac | 18 +++++ defs.h | 1 + ioctl.c | 4 + xlat/binder_driver_commands.in | 17 +++++ xlat/binder_driver_returns.in | 18 +++++ 7 files changed, 221 insertions(+) create mode 100644 binder.c create mode 100644 xlat/binder_driver_commands.in create mode 100644 xlat/binder_driver_returns.in diff --git a/Makefile.am b/Makefile.am index 77e0cc8..fb75e6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -78,6 +78,7 @@ strace_SOURCES = \ affinity.c \ aio.c \ alpha.c \ + binder.c \ bjm.c \ block.c \ bpf.c \ diff --git a/binder.c b/binder.c new file mode 100644 index 0000000..5997e85 --- /dev/null +++ b/binder.c @@ -0,0 +1,162 @@ +#include "defs.h" + +#if defined(HAVE_LINUX_ANDROID_BINDER_H) || defined(__ANDROID__) + +#include <linux/ioctl.h> + +/* + * The driver can support either 32 or 64 bit but not both at the same time. + */ +#if SIZEOF_LONG == 4 +# define BINDER_IPC_32BIT +#endif +#ifdef HAVE_LINUX_ANDROID_BINDER_H +# include <linux/android/binder.h> +#else +# include <linux/binder.h> +#endif + +#include "xlat/binder_driver_commands.h" +#include "xlat/binder_driver_returns.h" + +static int +decode_binder_commands_buffer(struct tcb *tcp, uintptr_t buffer, size_t pos, + size_t size, const struct xlat *x, const char *str) +{ + if (size < sizeof(uint32_t)) { + tprints("[]"); + return 0; + } + + if (abbrev(tcp)) { + tprints("[...]"); + return 0; + } + + uint32_t type; + tprints("["); + + goto print_one_commands_buffer; + while (pos + sizeof(uint32_t) <= size) { + tprints(", "); + +print_one_commands_buffer: + if (umove(tcp, buffer + pos, &type)) + return 1; + if (_IOC_SIZE(type) > 0) { + tprints("["); + printxval(x, type, str); + tprints(", "); + if (pos + sizeof(type) + _IOC_SIZE(type) <= size) + printstr(tcp, buffer + pos + sizeof(type), + _IOC_SIZE(type)); + tprints("]"); + } else + printxval(x, type, str); + pos += sizeof(uint32_t) + _IOC_SIZE(type); + } + + tprints("]"); + return 0; +} + +static int +decode_binder_write_read(struct tcb *tcp, const long addr) +{ + struct binder_write_read wr; + + if (entering(tcp)) { + tprints(", "); + if (umove_or_printaddr(tcp, addr, &wr)) + return RVAL_DECODED | 1; + + tprintf("{write_size=%" PRIu64 ", write_consumed=%" PRIu64 + ", write_buffer=", + (uint64_t)wr.write_size, + (uint64_t)wr.write_consumed); + if (decode_binder_commands_buffer(tcp, wr.write_buffer, + wr.write_consumed, wr.write_size, + binder_driver_commands, "BC_???")) { + tprints("}"); + return RVAL_DECODED | 1; + } + + tprintf(", read_size=%" PRIu64 ", read_consumed=%" PRIu64 "}", + (uint64_t)wr.read_size, + (uint64_t)wr.read_consumed); + return 0; + } + + if (syserror(tcp) || umove(tcp, addr, &wr)) + return RVAL_DECODED | 1; + + tprints(" => "); + + tprintf("{write_size=%" PRIu64 ", write_consumed=%" PRIu64 + ", read_size=%" PRIu64 ", read_consumed=%" PRIu64 + ", read_buffer=", + (uint64_t)wr.write_size, + (uint64_t)wr.write_consumed, + (uint64_t)wr.read_size, + (uint64_t)wr.read_consumed); + if (decode_binder_commands_buffer(tcp, wr.read_buffer, 0, + wr.read_consumed, + binder_driver_returns, "BR_???")) { + tprints("}"); + return RVAL_DECODED | 1; + } + + tprints("}"); + return RVAL_DECODED | 1; +} + +int +decode_binder_version(struct tcb *tcp, long addr) +{ + struct binder_version version; + + tprints(", "); + if (umove_or_printaddr(tcp, addr, &version)) + return RVAL_DECODED | 1; + + tprintf("{protocol_version=%" PRId32 "}", version.protocol_version); + return RVAL_DECODED | 1; +} + +int +binder_ioctl(struct tcb *tcp, const unsigned int code, long arg) +{ + if (!verbose(tcp)) + return RVAL_DECODED; + + if (code == BINDER_WRITE_READ) + return decode_binder_write_read(tcp, arg); + + if (entering(tcp)) { + switch (code) { + case BINDER_SET_IDLE_TIMEOUT: + tprints(", "); + printnum_int64(tcp, arg, "%lld"); + return RVAL_DECODED | 1; + case BINDER_SET_MAX_THREADS: + tprints(", "); + printnum_int(tcp, arg, "%u"); + return RVAL_DECODED | 1; + case BINDER_SET_IDLE_PRIORITY: + case BINDER_SET_CONTEXT_MGR: + case BINDER_THREAD_EXIT: + tprints(", "); + printnum_int(tcp, arg, "%d"); + return RVAL_DECODED | 1; + default: + break; + } + } else { + if (code == BINDER_VERSION) + return decode_binder_version(tcp, arg); + } + + return 0; +} + +#endif /* !(HAVE_LINUX_ANDROID_BINDER_H || __ANDROID__) */ diff --git a/configure.ac b/configure.ac index 56c9b30..b919449 100644 --- a/configure.ac +++ b/configure.ac @@ -440,6 +440,24 @@ AC_CHECK_HEADERS([linux/bpf.h], [ fi ]) +AC_CHECK_HEADERS([linux/android/binder.h], [[ #include <sys/types.h> +#include <linux/android/binder.h>]) + AC_CHECK_DECLS(m4_normalize([BC_TRANSACTION, BC_REPLY, BC_ACQUIRE_RESULT, + BC_FREE_BUFFER, BC_INCREFS, BC_ACQUIRE, + BC_RELEASE, BC_DECREFS, BC_INCREFS_DONE, + BC_ACQUIRE_DONE, BC_ATTEMPT_ACQUIRE, + BC_REGISTER_LOOPER, BC_ENTER_LOOPER, + BC_EXIT_LOOPER, BC_REQUEST_DEATH_NOTIFICATION, + BC_CLEAR_DEATH_NOTIFICATION, BC_DEAD_BINDER_DONE, + BR_ERROR, BR_OK, BR_TRANSACTION, BR_REPLY, + BR_ACQUIRE_RESULT, BR_DEAD_REPLY, + BR_TRANSACTION_COMPLETE, BR_INCREFS, BR_ACQUIRE, + BR_RELEASE, BR_DECREFS, BR_ATTEMPT_ACQUIRE, + BR_NOOP, BR_SPAWN_LOOPER, BR_FINISHED, + BR_DEAD_BINDER, BR_CLEAR_DEATH_NOTIFICATION_DONE, + BR_FAILED_REPLY]),,,[ #include <sys/types.h> +#include <linux/android/binder.h>])]) + AC_CHECK_TYPES([struct statfs], [ AC_CHECK_MEMBERS([struct statfs.f_frsize],,, [#include <linux/types.h> #include <asm/statfs.h>]) diff --git a/defs.h b/defs.h index 724d4f3..c028fbc 100644 --- a/defs.h +++ b/defs.h @@ -659,6 +659,7 @@ struct strace_statfs; extern void print_struct_statfs(struct tcb *tcp, long); extern void print_struct_statfs64(struct tcb *tcp, long, unsigned long); +extern int binder_ioctl(struct tcb *, const unsigned int, long); extern int file_ioctl(struct tcb *, const unsigned int, long); extern int fs_x_ioctl(struct tcb *, const unsigned int, long); extern int loop_ioctl(struct tcb *, const unsigned int, long); diff --git a/ioctl.c b/ioctl.c index e4b20d9..54aa9a7 100644 --- a/ioctl.c +++ b/ioctl.c @@ -282,6 +282,10 @@ ioctl_decode(struct tcb *tcp) case 0x94: return btrfs_ioctl(tcp, code, arg); #endif +#if defined(HAVE_LINUX_ANDROID_BINDER_H) || defined(__ANDROID__) + case 'b': + return binder_ioctl(tcp, code, arg); +#endif default: break; } diff --git a/xlat/binder_driver_commands.in b/xlat/binder_driver_commands.in new file mode 100644 index 0000000..84d481c --- /dev/null +++ b/xlat/binder_driver_commands.in @@ -0,0 +1,17 @@ +BC_TRANSACTION +BC_REPLY +BC_ACQUIRE_RESULT +BC_FREE_BUFFER +BC_INCREFS +BC_ACQUIRE +BC_RELEASE +BC_DECREFS +BC_INCREFS_DONE +BC_ACQUIRE_DONE +BC_ATTEMPT_ACQUIRE +BC_REGISTER_LOOPER +BC_ENTER_LOOPER +BC_EXIT_LOOPER +BC_REQUEST_DEATH_NOTIFICATION +BC_CLEAR_DEATH_NOTIFICATION +BC_DEAD_BINDER_DONE diff --git a/xlat/binder_driver_returns.in b/xlat/binder_driver_returns.in new file mode 100644 index 0000000..dc4c4c1 --- /dev/null +++ b/xlat/binder_driver_returns.in @@ -0,0 +1,18 @@ +BR_ERROR +BR_OK +BR_TRANSACTION +BR_REPLY +BR_ACQUIRE_RESULT +BR_DEAD_REPLY +BR_TRANSACTION_COMPLETE +BR_INCREFS +BR_ACQUIRE +BR_RELEASE +BR_DECREFS +BR_ATTEMPT_ACQUIRE +BR_NOOP +BR_SPAWN_LOOPER +BR_FINISHED +BR_DEAD_BINDER +BR_CLEAR_DEATH_NOTIFICATION_DONE +BR_FAILED_REPLY -- 2.8.3 ------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports. http://sdm.link/zohomanageengine _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel