This patch finishes the decoding of the content of
binder_driver_return_protocol and binder_driver_command_protocol.

* binder.c: Completed.
* xlat/binder_object_flags.in: New file.
* xlat/binder_transaction_flags.in: New file.

Signed-off-by: Antoine Damhet <antoine.dam...@lse.epita.fr>
Reviewed-by: Gabriel Laskar <gabr...@lse.epita.fr>
---
 binder.c                         | 283 +++++++++++++++++++++++++++++++++++++--
 configure.ac                     |   7 +-
 xlat/binder_transaction_flags.in |   4 +
 xlat/binder_types.in             |   5 +
 4 files changed, 286 insertions(+), 13 deletions(-)
 create mode 100644 xlat/binder_transaction_flags.in
 create mode 100644 xlat/binder_types.in

diff --git a/binder.c b/binder.c
index 5997e85..9eb4930 100644
--- a/binder.c
+++ b/binder.c
@@ -18,10 +18,272 @@
 
 #include "xlat/binder_driver_commands.h"
 #include "xlat/binder_driver_returns.h"
+#include "xlat/binder_transaction_flags.h"
+#include "xlat/binder_types.h"
+
+static void
+decode_flat_binder_object(struct flat_binder_object *obj)
+{
+       tprints("{type=");
+       printxval(binder_types, obj->type, "BINDER_TYPE_???");
+       tprints(", flags=");
+
+       if (obj->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS)
+               tprints("FLAT_BINDER_FLAG_ACCEPTS_FDS|");
+       tprintf("%" PRIx32, FLAT_BINDER_FLAG_PRIORITY_MASK & obj->flags);
+
+       switch (obj->type) {
+       case BINDER_TYPE_HANDLE:
+       case BINDER_TYPE_WEAK_HANDLE:
+       case BINDER_TYPE_FD:
+               tprintf(", {handle=%" PRIu32 "}", obj->handle);
+               break;
+       case BINDER_TYPE_BINDER:
+       case BINDER_TYPE_WEAK_BINDER:
+               tprintf(", {binder=0x%" PRIx64 "}", (uint64_t)obj->binder);
+               break;
+       default:
+               break;
+       }
+
+       tprintf(", cookie=0x%" PRIx64 "}", (uint64_t)obj->cookie);
+}
+
+static bool
+print_flat_binder_object(struct tcb *tcp, void *offset, size_t elem_size,
+               void *buffer)
+{
+       (void)elem_size;
+       binder_size_t *i = offset;
+       struct flat_binder_object obj;
+
+       if (umove(tcp, (uintptr_t)buffer + *i, &obj))
+               return false;
+
+       decode_flat_binder_object(&obj);
+       return true;
+}
+
+static int
+decode_binder_transaction_buffer(struct tcb *tcp, struct 
binder_transaction_data *tr)
+{
+       binder_size_t sz;
+
+       return !print_array(tcp,
+                       tr->data.ptr.offsets,
+                       tr->offsets_size / sizeof(binder_size_t),
+                       &sz,
+                       sizeof(binder_size_t),
+                       umoven_or_printaddr,
+                       print_flat_binder_object,
+                       (void *)tr->data.ptr.buffer);
+}
+
+static int
+decode_binder_transaction(struct tcb *tcp, uintptr_t addr, int reply,
+               int command)
+{
+       struct binder_transaction_data tr;
+
+       if (umove(tcp, addr, &tr))
+               return 1;
+
+       tprints("{");
+       if (!reply) {
+               if (command)
+                       tprintf("{handle=%" PRIu32 "}, ", tr.target.handle);
+               else
+                       tprintf("{ptr=0x%" PRIx64 "}, ",
+                                       (uint64_t)tr.target.ptr);
+       }
+
+       tprintf("cookie=0x%" PRIx64 ", code=%" PRIu32 ", flags=",
+                       (uint64_t)tr.cookie, tr.code);
+       printflags(binder_transaction_flags, tr.flags, "TF_???");
+       tprintf(", sender_pid=%d, sender_euid=%d, data_size=%" PRIu64
+                       ", offsets_size=%" PRIu64,
+                       tr.sender_pid, tr.sender_euid,
+                       (uint64_t)tr.data_size, (uint64_t)tr.offsets_size);
+
+       tprints(", data=[");
+       int err = 0;
+
+       if (!tr.offsets_size)
+               printstr(tcp, tr.data.ptr.buffer, tr.data_size);
+       else
+               err = decode_binder_transaction_buffer(tcp, &tr);
+
+       tprints("]}");
+       return err;
+}
+
+static void
+decode_binder_ptr_cookie(struct tcb *tcp, uintptr_t addr)
+{
+       struct binder_ptr_cookie ptr;
+
+       if (!umove(tcp, addr, &ptr))
+               tprintf("{ptr=0x%" PRIx64 ", cookie=0x%" PRIx64 "}",
+                               (uint64_t)ptr.ptr, (uint64_t)ptr.cookie);
+}
+
+static void
+decode_binder_pri_desc(struct tcb *tcp, uintptr_t addr)
+{
+       struct binder_pri_desc desc;
+
+       if (!umove(tcp, addr, &desc))
+               tprintf("{priority=%" PRId32 ", desc=%" PRIu32 "}",
+                               desc.priority, desc.desc);
+}
+
+static void
+decode_binder_handle_cookie(struct tcb *tcp, uintptr_t addr)
+{
+       struct binder_handle_cookie handle;
+
+       if (!umove(tcp, addr, &handle))
+               tprintf("{handle=%" PRIu32 ", cookie=0x%" PRIx64 "}",
+                               handle.handle, (uint64_t)handle.cookie);
+}
+
+static void
+decode_binder_pri_ptr_cookie(struct tcb *tcp, uintptr_t addr)
+{
+       struct binder_pri_ptr_cookie ptr;
+
+       if (!umove(tcp, addr, &ptr))
+               tprintf("{priority=%" PRId32 ", ptr=0x%" PRIx64
+                               ", cookie=0x%" PRIx64 "}",
+                               ptr.priority, (uint64_t)ptr.ptr,
+                               (uint64_t)ptr.cookie);
+}
+
+static int
+decode_binder_commands_parameters(struct tcb *tcp, uint32_t type, uintptr_t 
addr)
+{
+       int err = 0;
+
+       tprints("[");
+       printxval(binder_driver_commands, type, "BC_???");
+       tprints(", ");
+
+       switch (type) {
+       case BC_TRANSACTION:
+               err = decode_binder_transaction(tcp, addr, 0, 1);
+               break;
+       case BC_REPLY:
+               err = decode_binder_transaction(tcp, addr, 1, 1);
+               break;
+       case BC_ACQUIRE_RESULT: {
+               int32_t i;
+
+               if (umove(tcp, addr, &i))
+                       err = 1;
+               else
+                       tprintf("%" PRId32, i);
+               }
+               break;
+       case BC_FREE_BUFFER:
+       case BC_DEAD_BINDER_DONE: {
+               binder_uintptr_t ptr;
+
+               if (umove(tcp, addr, &ptr))
+                       err = 1;
+               else
+                       tprintf("0x%" PRIx64, (uint64_t)ptr);
+               }
+               break;
+       case BC_INCREFS:
+       case BC_ACQUIRE:
+       case BC_RELEASE:
+       case BC_DECREFS: {
+               uint32_t i;
+
+               if (umove(tcp, addr, &i))
+                       err = 1;
+               else
+                       tprintf("%" PRIu32, i);
+               }
+               break;
+       case BC_INCREFS_DONE:
+       case BC_ACQUIRE_DONE:
+               decode_binder_ptr_cookie(tcp, addr);
+               break;
+       case BC_ATTEMPT_ACQUIRE:
+               decode_binder_pri_desc(tcp, addr);
+               break;
+       case BC_REQUEST_DEATH_NOTIFICATION:
+       case BC_CLEAR_DEATH_NOTIFICATION:
+               decode_binder_handle_cookie(tcp, addr);
+               break;
+       default:
+               printstr(tcp, addr, _IOC_SIZE(type));
+               break;
+       }
+
+       tprints("]");
+       return err;
+}
+
+static int
+decode_binder_returns_parameters(struct tcb *tcp, uint32_t type, uintptr_t 
addr)
+{
+       int err = 0;
+
+       tprints("[");
+       printxval(binder_driver_returns, type, "BR_???");
+       tprints(", ");
+
+       switch (type) {
+       case BR_TRANSACTION:
+               err = decode_binder_transaction(tcp, addr, 0, 0);
+               break;
+       case BR_REPLY:
+               err = decode_binder_transaction(tcp, addr, 1, 0);
+               break;
+       case BR_ACQUIRE_RESULT:
+       case BR_ERROR: {
+               int32_t i;
+
+               if (umove(tcp, addr, &i))
+                       err = 1;
+               else
+                       tprintf("%" PRId32, i);
+               }
+               break;
+       case BR_INCREFS:
+       case BR_ACQUIRE:
+       case BR_RELEASE:
+       case BR_DECREFS:
+               decode_binder_ptr_cookie(tcp, addr);
+               break;
+       case BR_ATTEMPT_ACQUIRE:
+               decode_binder_pri_ptr_cookie(tcp, addr);
+               break;
+       case BR_DEAD_BINDER:
+       case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
+               binder_uintptr_t ptr;
+
+               if (umove(tcp, addr, &ptr))
+                       err = 1;
+               else
+                       tprintf("0x%" PRIx64, (uint64_t)ptr);
+               }
+               break;
+       default:
+               printstr(tcp, addr, _IOC_SIZE(type));
+               break;
+       }
+
+       tprints("]");
+       return err;
+}
 
 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)
+               size_t size, const struct xlat *x, const char *str,
+               int (*const decode_func)(struct tcb *, uint32_t, uintptr_t))
 {
        if (size < sizeof(uint32_t)) {
                tprints("[]");
@@ -43,15 +305,10 @@ decode_binder_commands_buffer(struct tcb *tcp, uintptr_t 
buffer, size_t pos,
 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
+               if (_IOC_SIZE(type) > 0
+                               && pos + sizeof(type) + _IOC_SIZE(type) <= size)
+                       decode_func(tcp, type, buffer + pos + sizeof(uint32_t));
+               else
                        printxval(x, type, str);
                pos += sizeof(uint32_t) + _IOC_SIZE(type);
        }
@@ -76,7 +333,8 @@ decode_binder_write_read(struct tcb *tcp, const long addr)
                                (uint64_t)wr.write_consumed);
                if (decode_binder_commands_buffer(tcp, wr.write_buffer,
                                        wr.write_consumed, wr.write_size,
-                                       binder_driver_commands, "BC_???")) {
+                                       binder_driver_commands, "BC_???",
+                                       decode_binder_commands_parameters)) {
                        tprints("}");
                        return RVAL_DECODED | 1;
                }
@@ -101,7 +359,8 @@ decode_binder_write_read(struct tcb *tcp, const long addr)
                        (uint64_t)wr.read_consumed);
        if (decode_binder_commands_buffer(tcp, wr.read_buffer, 0,
                                wr.read_consumed,
-                               binder_driver_returns, "BR_???")) {
+                               binder_driver_returns, "BR_???",
+                               decode_binder_returns_parameters)) {
                tprints("}");
                return RVAL_DECODED | 1;
        }
diff --git a/configure.ac b/configure.ac
index b919449..1797d0a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -455,7 +455,12 @@ AC_CHECK_HEADERS([linux/android/binder.h], [[ #include 
<sys/types.h>
                                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>
+                               BR_FAILED_REPLY,
+                               TF_ONE_WAY, TF_ROOT_OBJECT, TF_STATUS_CODE,
+                               TF_ACCEPT_FDS,
+                               BINDER_TYPE_BINDER, BINDER_TYPE_WEAK_BINDER,
+                               BINDER_TYPE_HANDLE, BINDER_TYPE_WEAK_HANDLE,
+                               BINDER_TYPE_FD]),,,[ #include <sys/types.h>
 #include <linux/android/binder.h>])])
 
 AC_CHECK_TYPES([struct statfs], [
diff --git a/xlat/binder_transaction_flags.in b/xlat/binder_transaction_flags.in
new file mode 100644
index 0000000..101242d
--- /dev/null
+++ b/xlat/binder_transaction_flags.in
@@ -0,0 +1,4 @@
+TF_ONE_WAY
+TF_ROOT_OBJECT
+TF_STATUS_CODE
+TF_ACCEPT_FDS
diff --git a/xlat/binder_types.in b/xlat/binder_types.in
new file mode 100644
index 0000000..3a9b24f
--- /dev/null
+++ b/xlat/binder_types.in
@@ -0,0 +1,5 @@
+BINDER_TYPE_BINDER
+BINDER_TYPE_WEAK_BINDER
+BINDER_TYPE_HANDLE
+BINDER_TYPE_WEAK_HANDLE
+BINDER_TYPE_FD
-- 
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

Reply via email to