Skip to content

Commit

Permalink
[gbinder] Expose transaction code macros, add binder error status cod…
Browse files Browse the repository at this point in the history
…es. JB#61891

Useful for implementation of DUMP and other internal transactions (except
for the silly ones). Also define proper status codes and translate the
existing ones as the current GBINDER_STATUS_FAILED is not recognized.
  • Loading branch information
abranson committed Apr 25, 2024
1 parent 29718f9 commit 5e8e7df
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 34 deletions.
37 changes: 35 additions & 2 deletions include/gbinder_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,47 @@ GBinderLocalReply*

#define GBINDER_TX_FLAG_ONEWAY (0x01)

/* Other possible errors added from system/core/libutils/include/utils/Errors.h
* Legacy GBINDER_STATUS values preserved, but translated over the wire.
*/
typedef enum gbinder_status {
GBINDER_STATUS_OK = 0,
GBINDER_STATUS_FAILED,
GBINDER_STATUS_DEAD_OBJECT
GBINDER_STATUS_FAILED, /* maps to UNKNOWN_ERROR */
GBINDER_STATUS_DEAD_OBJECT,
GBINDER_STATUS_UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN
GBINDER_STATUS_NO_MEMORY = -ENOMEM,
GBINDER_STATUS_INVALID_OPERATION = -ENOSYS,
GBINDER_STATUS_BAD_VALUE = -EINVAL,
GBINDER_STATUS_BAD_TYPE = (GBINDER_STATUS_UNKNOWN_ERROR + 1),
GBINDER_STATUS_NAME_NOT_FOUND = -ENOENT,
GBINDER_STATUS_PERMISSION_DENIED = -EPERM,
GBINDER_STATUS_NO_INIT = -ENODEV,
GBINDER_STATUS_ALREADY_EXISTS = -EEXIST,
GBINDER_STATUS_FAILED_TRANSACTION = (GBINDER_STATUS_UNKNOWN_ERROR + 2),
#if !defined(_WIN32)
GBINDER_STATUS_BAD_INDEX = -EOVERFLOW,
GBINDER_STATUS_NOT_ENOUGH_DATA = -ENODATA,
GBINDER_STATUS_WOULD_BLOCK = -EWOULDBLOCK,
GBINDER_STATUS_TIMED_OUT = -ETIMEDOUT,
GBINDER_STATUS_UNKNOWN_TRANSACTION = -EBADMSG,
#else
GBINDER_STATUS_BAD_INDEX = -E2BIG,
GBINDER_STATUS_NOT_ENOUGH_DATA = (GBINDER_STATUS_UNKNOWN_ERROR + 3),
GBINDER_STATUS_WOULD_BLOCK = (GBINDER_STATUS_UNKNOWN_ERROR + 4),
GBINDER_STATUS_TIMED_OUT = (GBINDER_STATUS_UNKNOWN_ERROR + 5),
GBINDER_STATUS_UNKNOWN_TRANSACTION = (GBINDER_STATUS_UNKNOWN_ERROR + 6),
#endif
GBINDER_STATUS_FDS_NOT_ALLOWED = (GBINDER_STATUS_UNKNOWN_ERROR + 7),
GBINDER_STATUS_UNEXPECTED_NULL = (GBINDER_STATUS_UNKNOWN_ERROR + 8),
} GBINDER_STATUS;

/* Utility macros for generating internal binder transaction codes
* such as DUMP and INTERFACE
*/
#define GBINDER_FOURCC(c1,c2,c3,c4) \
(((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4))
#define GBINDER_AIDL_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_HIDL_TRANSACTION(c2,c3,c4) GBINDER_FOURCC(0x0f,c2,c3,c4)

#define GBINDER_FIRST_CALL_TRANSACTION (0x00000001)

Expand Down
29 changes: 23 additions & 6 deletions src/gbinder_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,10 +454,23 @@ gbinder_driver_reply_status(
memcpy(buf, code, sizeof(*code));
ptr += sizeof(*code);

/* Translate legacy gbinder_status codes to recognizable values */
gint32 mapped_status;
switch (status) {
case GBINDER_STATUS_FAILED:
mapped_status = GBINDER_STATUS_UNKNOWN_ERROR;
break;
case GBINDER_STATUS_DEAD_OBJECT:
mapped_status = -EPIPE;
break;
default:
mapped_status = status;
break;
}
/* Data */
ptr += io->encode_status_reply(ptr, &status);
ptr += io->encode_status_reply(ptr, &mapped_status);

GVERBOSE("< BC_REPLY (%d)", status);
GVERBOSE("< BC_REPLY (%d)", mapped_status);
memset(&write, 0, sizeof(write));
write.ptr = (uintptr_t)buf;
write.size = ptr - buf;
Expand Down Expand Up @@ -835,15 +848,19 @@ gbinder_driver_txstatus(
*/
switch (tx.status) {
case (-EAGAIN):
case GBINDER_STATUS_FAILED:
case GBINDER_STATUS_DEAD_OBJECT:
txstatus = (-EFAULT);
GWARN("Replacing tx status %d with %d", tx.status, txstatus);
case GBINDER_STATUS_UNKNOWN_ERROR:
txstatus = GBINDER_STATUS_FAILED;
break;
case -EPIPE:
txstatus = GBINDER_STATUS_DEAD_OBJECT;
break;
default:
txstatus = tx.status;
break;
}
if (txstatus != tx.status) {
GWARN("Replacing tx status %d with %d", tx.status, txstatus);
}
} else {
gbinder_driver_handle_command(self, context, cmd, data);
}
Expand Down
6 changes: 3 additions & 3 deletions src/gbinder_rpc_protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ gbinder_rpc_protocol_aidl_read_rpc_header(
guint32 txcode,
char** iface)
{
if (txcode > GBINDER_TRANSACTION(0,0,0)) {
if (txcode > GBINDER_AIDL_TRANSACTION(0,0,0)) {
/* Internal transaction e.g. GBINDER_DUMP_TRANSACTION etc. */
*iface = NULL;
} else if (gbinder_reader_read_int32(reader, NULL)) {
Expand Down Expand Up @@ -156,7 +156,7 @@ gbinder_rpc_protocol_aidl2_read_rpc_header(
guint32 txcode,
char** iface)
{
if (txcode > GBINDER_TRANSACTION(0,0,0)) {
if (txcode > GBINDER_AIDL_TRANSACTION(0,0,0)) {
/* Internal transaction e.g. GBINDER_DUMP_TRANSACTION etc. */
*iface = NULL;
} else if (gbinder_reader_read_int32(reader, NULL) /* flags */ &&
Expand Down Expand Up @@ -199,7 +199,7 @@ gbinder_rpc_protocol_aidl3_read_rpc_header(
guint32 txcode,
char** iface)
{
if (txcode > GBINDER_TRANSACTION(0,0,0)) {
if (txcode > GBINDER_AIDL_TRANSACTION(0,0,0)) {
*iface = NULL;
} else if (gbinder_reader_read_int32(reader, NULL) /* flags */ &&
gbinder_reader_read_int32(reader, NULL) /* work source */ &&
Expand Down
33 changes: 16 additions & 17 deletions src/gbinder_types_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,24 @@ typedef struct gbinder_ipc_sync_api GBinderIpcSyncApi;
#define GBINDER_INTERNAL G_GNUC_INTERNAL
#define GBINDER_DESTRUCTOR __attribute__((destructor))

#define GBINDER_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_PING_TRANSACTION GBINDER_TRANSACTION('P','N','G')
#define GBINDER_DUMP_TRANSACTION GBINDER_TRANSACTION('D','M','P')
#define GBINDER_SHELL_COMMAND_TRANSACTION GBINDER_TRANSACTION('C','M','D')
#define GBINDER_INTERFACE_TRANSACTION GBINDER_TRANSACTION('N','T','F')
#define GBINDER_SYSPROPS_TRANSACTION GBINDER_TRANSACTION('S','P','R')
/* Internal transactions from frameworks/native/libs/binder/include/binder/IBinder.h */
#define GBINDER_PING_TRANSACTION GBINDER_AIDL_TRANSACTION('P','N','G')
#define GBINDER_DUMP_TRANSACTION GBINDER_AIDL_TRANSACTION('D','M','P')
#define GBINDER_SHELL_COMMAND_TRANSACTION GBINDER_AIDL_TRANSACTION('C','M','D')
#define GBINDER_INTERFACE_TRANSACTION GBINDER_AIDL_TRANSACTION('N','T','F')
#define GBINDER_SYSPROPS_TRANSACTION GBINDER_AIDL_TRANSACTION('S','P','R')

/* platform/system/tools/hidl/Interface.cpp */
#define HIDL_FOURCC(c2,c3,c4) GBINDER_FOURCC(0x0f,c2,c3,c4)
#define HIDL_PING_TRANSACTION HIDL_FOURCC('P','N','G')
#define HIDL_DESCRIPTOR_CHAIN_TRANSACTION HIDL_FOURCC('C','H','N')
#define HIDL_GET_DESCRIPTOR_TRANSACTION HIDL_FOURCC('D','S','C')
#define HIDL_SYSPROPS_CHANGED_TRANSACTION HIDL_FOURCC('S','Y','S')
#define HIDL_LINK_TO_DEATH_TRANSACTION HIDL_FOURCC('L','T','D')
#define HIDL_UNLINK_TO_DEATH_TRANSACTION HIDL_FOURCC('U','T','D')
#define HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION HIDL_FOURCC('I','N','T')
#define HIDL_GET_REF_INFO_TRANSACTION HIDL_FOURCC('R','E','F')
#define HIDL_DEBUG_TRANSACTION HIDL_FOURCC('D','B','G')
#define HIDL_HASH_CHAIN_TRANSACTION HIDL_FOURCC('H','S','H')
#define HIDL_PING_TRANSACTION GBINDER_HIDL_TRANSACTION('P','N','G')
#define HIDL_DESCRIPTOR_CHAIN_TRANSACTION GBINDER_HIDL_TRANSACTION('C','H','N')
#define HIDL_GET_DESCRIPTOR_TRANSACTION GBINDER_HIDL_TRANSACTION('D','S','C')
#define HIDL_SYSPROPS_CHANGED_TRANSACTION GBINDER_HIDL_TRANSACTION('S','Y','S')
#define HIDL_LINK_TO_DEATH_TRANSACTION GBINDER_HIDL_TRANSACTION('L','T','D')
#define HIDL_UNLINK_TO_DEATH_TRANSACTION GBINDER_HIDL_TRANSACTION('U','T','D')
#define HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION GBINDER_HIDL_TRANSACTION('I','N','T')
#define HIDL_GET_REF_INFO_TRANSACTION GBINDER_HIDL_TRANSACTION('R','E','F')
#define HIDL_DEBUG_TRANSACTION GBINDER_HIDL_TRANSACTION('D','B','G')
#define HIDL_HASH_CHAIN_TRANSACTION GBINDER_HIDL_TRANSACTION('H','S','H')

/* As a special case, ServiceManager's handle is zero */
#define GBINDER_SERVICEMANAGER_HANDLE (0)
Expand Down
3 changes: 1 addition & 2 deletions test/binder-call/binder-call.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@

#define DEFAULT_DEVICE GBINDER_DEFAULT_BINDER

#define GBINDER_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_INTERFACE_TRANSACTION GBINDER_TRANSACTION('N','T','F')
#define GBINDER_INTERFACE_TRANSACTION GBINDER_AIDL_TRANSACTION('N','T','F')

static const char pname[] = "binder-call";

Expand Down
3 changes: 1 addition & 2 deletions test/binder-dump/binder-dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@

#define DEV_DEFAULT GBINDER_DEFAULT_BINDER

#define GBINDER_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_DUMP_TRANSACTION GBINDER_TRANSACTION('D','M','P')
#define GBINDER_DUMP_TRANSACTION GBINDER_AIDL_TRANSACTION('D','M','P')

typedef struct app_options {
char* dev;
Expand Down
4 changes: 2 additions & 2 deletions unit/unit_ipc/unit_ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,15 +346,15 @@ test_sync_reply_error(
g_assert(!gbinder_ipc_sync_main.sync_reply(ipc,handle,code,req,&status));
g_assert_cmpint(status, == ,expected_status);

/* GBINDER_STATUS_FAILED gets replaced with -EFAULT */
/* Should return GBINDER_STATUS_FAILED */
test_binder_ignore_dead_object(fd);
test_binder_br_noop(fd, TX_THREAD);
test_binder_br_transaction_complete(fd, TX_THREAD);
test_binder_br_noop(fd, TX_THREAD);
test_binder_br_reply_status(fd, TX_THREAD, unexpected_status);

g_assert(!gbinder_ipc_sync_main.sync_reply(ipc,handle,code,req,&status));
g_assert_cmpint(status, == ,-EFAULT);
g_assert_cmpint(status, == , GBINDER_STATUS_FAILED);

gbinder_local_request_unref(req);
gbinder_ipc_unref(ipc);
Expand Down

0 comments on commit 5e8e7df

Please sign in to comment.