From 12fffb0724998ce194af47186bf52b80ee0f3a0d Mon Sep 17 00:00:00 2001 From: Mis012 Date: Thu, 24 Nov 2022 18:42:18 +0100 Subject: [PATCH] src/libandroid/looper.c: fix for aarch64 (TODO: just implement these as extern C straight in libutils?) --- src/libandroid/looper.c | 52 +++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/src/libandroid/looper.c b/src/libandroid/looper.c index 8fc1c590..7855f69f 100644 --- a/src/libandroid/looper.c +++ b/src/libandroid/looper.c @@ -4,22 +4,50 @@ typedef void ALooper; typedef int (*Looper_callbackFunc)(int fd, int events, void* data); -void _ZN7android6Looper12getForThreadEv(void **ret); // no clue why itanium ABI does this with return values -ALooper * ALooper_forThread() -{ - void *ret; - _ZN7android6Looper12getForThreadEv(&ret); - return ret; +/* macros for creating wrappers for methods which use C++ itanium ABI */ + +#ifdef __aarch64__ + +#define ITANIUM_OBJ_RET_WRAPPER_DEC(ret_type, wrapper_name, mangled_name, ...) \ +void mangled_name(__VA_ARGS__); /* r8 used instead of implicit parameter, fun innit */\ +ret_type * wrapper_name(__VA_ARGS__) + +#define ITANIUM_OBJ_RET_WRAPPER_BODY(ret_type, wrapper_name, mangled_name, ...) \ +{ \ + ret_type *ret; \ + register ret_type **addr_of_ret asm("r8"); /* arm wants to be special :( */\ + __asm__ ("" : : "" (addr_of_ret)); /* apparently __attribute__((used)) is not a thing */\ + addr_of_ret = &ret; \ + mangled_name(__VA_ARGS__); \ + return ret; \ } -void _ZN7android6Looper7prepareEi(void **ret, int opts); // no clue why itanium ABI does this with return values -ALooper * ALooper_prepare(int opts) -{ - void *ret; - _ZN7android6Looper7prepareEi(&ret, opts); - return ret; +#else + +#define ITANIUM_OBJ_RET_WRAPPER_DEC(ret_type, wrapper_name, mangled_name, ...) \ +void mangled_name(ret_type **ret, ##__VA_ARGS__); /* implicit first parameter used for return value */\ +ret_type * wrapper_name(__VA_ARGS__) + +#define ITANIUM_OBJ_RET_WRAPPER_BODY(ret_type, wrapper_name, mangled_name, ...) \ +{ \ + ret_type *ret; \ + mangled_name(&ret, ##__VA_ARGS__); \ + return ret; \ } +#endif + +#define ITANIUM_OBJ_RET_WRAPPER_NOARGS(ret_type, wrapper_name, mangled_name) \ +ITANIUM_OBJ_RET_WRAPPER_DEC(ret_type, wrapper_name, mangled_name) \ +ITANIUM_OBJ_RET_WRAPPER_BODY(ret_type, wrapper_name, mangled_name) + +// ALooper * ALooper_forThread() +ITANIUM_OBJ_RET_WRAPPER_NOARGS(ALooper, ALooper_forThread, _ZN7android6Looper12getForThreadEv) + +// ALooper * ALooper_prepare(int opts) +ITANIUM_OBJ_RET_WRAPPER_DEC(ALooper, ALooper_prepare, _ZN7android6Looper7prepareEi, int opts) +ITANIUM_OBJ_RET_WRAPPER_BODY(ALooper, ALooper_prepare, _ZN7android6Looper7prepareEi, opts) + int _ZN7android6Looper7pollAllEiPiS1_PPv(void *this, int timeoutMillis, int* outFd, int* outEvents, void** outData); int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {