From f22eaf92d19ef9ddbb384abf82380df81b4b169d Mon Sep 17 00:00:00 2001 From: Vinayak Katoch Date: Tue, 25 Feb 2025 16:11:29 +0530 Subject: [PATCH] Add new function remotectl_open_v2 This commit introduces a new function, remotectl_open_v2, which includes additional arguments buf and bufLen. Previously, the dlopen_ex function executed with buf and bufLen set to zero on the DSP side. With this update, the virtual address and file length are now sourced from the userspace side. Signed-off-by: Vinayak Katoch --- inc/fastrpc_internal.h | 2 +- inc/fastrpc_mem.h | 2 + inc/mod_table.h | 11 ++++ inc/remotectl.h | 1 + inc/remotectl1.h | 1 + src/fastrpc_apps_user.c | 141 ++++++++++++++++++++++++++++++++-------- src/fastrpc_mem.c | 16 +++++ src/fastrpc_perf.c | 2 +- src/listener_android.c | 6 +- src/mod_table.c | 11 +--- src/remotectl1_stub.c | 54 ++++++++++++--- src/remotectl_stub.c | 58 ++++++++++++++--- 12 files changed, 247 insertions(+), 58 deletions(-) diff --git a/inc/fastrpc_internal.h b/inc/fastrpc_internal.h index 3d67c7d3..9a217a53 100644 --- a/inc/fastrpc_internal.h +++ b/inc/fastrpc_internal.h @@ -535,7 +535,7 @@ remote_handle64 get_adsp_perf1_handle(int domain); * @returns: 0 on success, valid non-zero error code on failure * **/ -int fastrpc_update_module_list(uint32_t req, int domain, remote_handle64 handle, remote_handle64 *local, const char *name); +int fastrpc_update_module_list(uint32_t req, int domain, remote_handle64 handle, remote_handle64 *local, const char *name, int fd); /** * @brief functions to wrap ioctl syscalls for downstream and upstream kernel diff --git a/inc/fastrpc_mem.h b/inc/fastrpc_mem.h index 06a9f989..f218cdb7 100644 --- a/inc/fastrpc_mem.h +++ b/inc/fastrpc_mem.h @@ -56,3 +56,5 @@ int remote_mmap64_internal(int fd, uint32_t flags, uint64_t vaddrin, int64_t siz int fastrpc_buffer_ref(int domain, int fd, int ref, void **va, size_t *size); #endif //FASTRPC_MEM_H + +void* get_source_vaddr(int fd, int domain); \ No newline at end of file diff --git a/inc/mod_table.h b/inc/mod_table.h index c3ad413b..1db0280a 100644 --- a/inc/mod_table.h +++ b/inc/mod_table.h @@ -105,6 +105,17 @@ int mod_table_register_const_handle(remote_handle handle, const char* in_name, i */ int mod_table_register_const_handle1(remote_handle remote, remote_handle64 local, const char* uri, int (*pfn)(remote_handle64 h, uint32 sc, remote_arg* pra)); +struct parsed_uri { + const char *file; + const char *sym; + const char *ver; + int filelen; + int symlen; + int verlen; +}; + +int parse_uri(const char *uri, int urilen, struct parsed_uri *out); + #ifdef __cplusplus } #endif diff --git a/inc/remotectl.h b/inc/remotectl.h index 4afc7c84..ef5edb6d 100644 --- a/inc/remotectl.h +++ b/inc/remotectl.h @@ -46,6 +46,7 @@ __QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_open)(const char* name, int* ha __QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_close)(int handle, char* dlerror, int dlerrorLen, int* nErr) __QAIC_HEADER_ATTRIBUTE; __QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_grow_heap)(uint32 phyAddr, uint32 nSize) __QAIC_HEADER_ATTRIBUTE; __QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_set_param)(int reqID, const uint32* params, int paramsLen) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_open_v2)(const char* name, const char* buf, int bufLen, int* handle, char* dlerror, int dlerrorLen, int* nErr) __QAIC_HEADER_ATTRIBUTE; #ifdef __cplusplus } #endif diff --git a/inc/remotectl1.h b/inc/remotectl1.h index 97234906..9c27c75b 100644 --- a/inc/remotectl1.h +++ b/inc/remotectl1.h @@ -264,6 +264,7 @@ __QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl1_open1)(remote_handle64 _h, con __QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl1_close1)(remote_handle64 _h, int handle, char* dlerror, int dlerrorLen, int* nErr) __QAIC_HEADER_ATTRIBUTE; __QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl1_grow_heap)(remote_handle64 _h, uint32 phyAddr, uint32 nSize) __QAIC_HEADER_ATTRIBUTE; __QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl1_set_param)(remote_handle64 _h, int reqID, const uint32* params, int paramsLen) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl1_open1_v2)(remote_handle64 _h, const char* name, const char* buf, int bufLen, int* handle, char* dlerror, int dlerrorLen, int* nErr) __QAIC_HEADER_ATTRIBUTE; #ifndef remotectl1_URI #define remotectl1_URI "file:///libremotectl1_skel.so?remotectl1_skel_handle_invoke&_modver=1.0" #endif /*remotectl1_URI*/ diff --git a/src/fastrpc_apps_user.c b/src/fastrpc_apps_user.c index f9c6fd73..b02a7bea 100644 --- a/src/fastrpc_apps_user.c +++ b/src/fastrpc_apps_user.c @@ -78,6 +78,7 @@ #endif #include "fastrpc_process_attributes.h" #include "fastrpc_trace.h" +#include "mod_table.h" #ifndef ENABLE_UPSTREAM_DRIVER_INTERFACE #define DSP_MOUNT_LOCATION "/dsp/" @@ -289,6 +290,7 @@ struct handle_info { remote_handle64 local; remote_handle64 remote; char *name; + int fd; }; // Fastrpc client notification request node to be queued to @@ -645,7 +647,7 @@ int fastrpc_set_remote_uthread_params(int domain) { "Warning 0x%x: %s: remotectl1 domains not supported for domain %d\n", nErr, __func__, domain); fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, - _const_remotectl1_handle, NULL, NULL); + _const_remotectl1_handle, NULL, NULL, -1); // Set remotectlhandle to INVALID_HANDLE, so that all subsequent calls are // non-domain calls @@ -883,7 +885,7 @@ static char* get_lib_name(const char *uri) { } static int fastrpc_alloc_handle(int domain, QList *me, remote_handle64 remote, - remote_handle64 *local, const char *name) { + remote_handle64 *local, const char *name, int fd) { struct handle_info *hinfo = {0}; int nErr = 0; char *libname = NULL; @@ -895,6 +897,7 @@ static int fastrpc_alloc_handle(int domain, QList *me, remote_handle64 remote, hinfo->name = libname; hinfo->hlist = &hlist[domain]; *local = hinfo->local; + hinfo->fd = fd; QNode_CtorZ(&hinfo->qn); pthread_mutex_lock(&hlist[domain].lmut); @@ -910,6 +913,22 @@ static int fastrpc_alloc_handle(int domain, QList *me, remote_handle64 remote, return nErr; } +static int get_fd_for_handle(int domain, QList *me, remote_handle64 remote, int* fd) { + pthread_mutex_lock(&hlist[domain].lmut); + if (!QList_IsEmpty(me)) { + QNode *pn = NULL, *pnn = NULL; + QLIST_NEXTSAFE_FOR_ALL(me, pn, pnn) { + struct handle_info *hi = STD_RECOVER_REC(struct handle_info, qn, pn); + if (hi->remote == remote) { + *fd = hi->fd; + break; + } + } + } + pthread_mutex_unlock(&hlist[domain].lmut); + return 0; +} + static int fastrpc_free_handle(int domain, QList *me, remote_handle64 remote) { pthread_mutex_lock(&hlist[domain].lmut); if (!QList_IsEmpty(me)) { @@ -931,13 +950,13 @@ static int fastrpc_free_handle(int domain, QList *me, remote_handle64 remote) { } int fastrpc_update_module_list(uint32_t req, int domain, remote_handle64 h, - remote_handle64 *local, const char *name) { + remote_handle64 *local, const char *name, int fd) { int nErr = AEE_SUCCESS; switch (req) { case DOMAIN_LIST_PREPEND: { VERIFY(AEE_SUCCESS == - (nErr = fastrpc_alloc_handle(domain, &hlist[domain].ql, h, local, name))); + (nErr = fastrpc_alloc_handle(domain, &hlist[domain].ql, h, local, name, fd))); if(IS_CONST_HANDLE(h)) { pthread_mutex_lock(&hlist[domain].lmut); hlist[domain].constCount++; @@ -965,7 +984,7 @@ int fastrpc_update_module_list(uint32_t req, int domain, remote_handle64 h, } case NON_DOMAIN_LIST_PREPEND: { VERIFY(AEE_SUCCESS == - (nErr = fastrpc_alloc_handle(domain, &hlist[domain].nql, h, local, name))); + (nErr = fastrpc_alloc_handle(domain, &hlist[domain].nql, h, local, name, fd))); pthread_mutex_lock(&hlist[domain].lmut); hlist[domain].nondomainsCount++; pthread_mutex_unlock(&hlist[domain].lmut); @@ -981,7 +1000,7 @@ int fastrpc_update_module_list(uint32_t req, int domain, remote_handle64 h, } case REVERSE_HANDLE_LIST_PREPEND: { VERIFY(AEE_SUCCESS == - (nErr = fastrpc_alloc_handle(domain, &hlist[domain].rql, h, local, name))); + (nErr = fastrpc_alloc_handle(domain, &hlist[domain].rql, h, local, name, fd))); pthread_mutex_lock(&hlist[domain].lmut); hlist[domain].reverseCount++; pthread_mutex_unlock(&hlist[domain].lmut); @@ -1612,13 +1631,21 @@ int remote_handle64_invoke_async(remote_handle64 local, } int listener_android_geteventfd(int domain, int *fd); -int remote_handle_open_domain(int domain, const char *name, remote_handle *ph, +int remote_handle_open_domain(int domain, const char *name, remote_handle *ph, int *fd, uint64_t *t_spawn, uint64_t *t_load) { char dlerrstr[255]; int dlerr = 0, nErr = AEE_SUCCESS; int dev = -1; char *pdname_uri = NULL; int name_len = 0; + + name_len = strlen(name); + int filelen = 0; + int tmplen = name_len * 2 + sizeof("file:///lib_skel.so?_skel_handle_invoke&_modver=1.0") + 1; + char *tmp = 0; + struct parsed_uri *out = (struct parsed_uri *)malloc(sizeof(struct parsed_uri)); + void *source_vaddr = NULL; + remote_handle64 handle = INVALID_HANDLE; FASTRPC_ATRACE_BEGIN_L("%s called with domain %d, name %s, handle 0x%x", @@ -1700,11 +1727,37 @@ int remote_handle_open_domain(int domain, const char *name, remote_handle *ph, PROFILE_ALWAYS(t_spawn, VERIFY(AEE_SUCCESS == (nErr = domain_init(domain, &dev))); VERIFYM(-1 != dev, AEE_ERPC, "open dev failed\n");); + + VERIFYC(NULL != (tmp = calloc(1, tmplen)), AEE_ENOMEMORY); + // FARF(ALWAYS, "===== calling parse_uri ====="); + (void)parse_uri(name, name_len, out); + // FARF(ALWAYS, "===== done calling parse_uri ====="); + // FARF(ALWAYS, "===== vals %d %d %d =====", out->filelen, out->symlen, out->verlen); + if (out->filelen) { + int rv = std_snprintf(tmp, tmplen, "%.*s", out->filelen, out->file); + VERIFYC((rv > 0) && (tmplen >= rv), AEE_EBADPARM); + } else { + int rv; + rv = std_snprintf(tmp, tmplen, "lib%s_skel.so", name); + VERIFYC((rv > 0) && (tmplen >= rv), AEE_EBADPARM); + } + + nErr = apps_std_fopen_with_env_fd(ADSP_LIBRARY_PATH, ";", tmp, "r", fd, &filelen); + // if(nErr == AEE_SUCCESS) { + // FARF(ALWAYS,"===== file Open with env fd successfull - filelen %d, path %s ,fd (%d) =====\n", filelen, tmp, *fd); + // } + if(tmp) { + free(tmp); + tmp = NULL; + } + source_vaddr = get_source_vaddr(*fd, domain); + + // added remotectl_open_v2 PROFILE_ALWAYS( t_load, if ((handle = get_remotectl1_handle(domain)) != INVALID_HANDLE) { - nErr = remotectl1_open1(handle, name, (int *)ph, dlerrstr, - sizeof(dlerrstr), &dlerr); + nErr = remotectl1_open1_v2(handle, name, (const char*)source_vaddr, + filelen, (int *)ph, dlerrstr, sizeof(dlerrstr), &dlerr); if ((nErr == DSP_AEE_EOFFSET + AEE_ERPC) || nErr == DSP_AEE_EOFFSET + AEE_ENOSUCHMOD) { FARF(ALWAYS, @@ -1712,19 +1765,19 @@ int remote_handle_open_domain(int domain, const char *name, remote_handle *ph, "%d\n", nErr, __func__, domain); fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, - _const_remotectl1_handle, NULL, NULL); + _const_remotectl1_handle, NULL, NULL, -1); // Set remotectlhandle to INVALID_HANDLE, so that all subsequent calls // are non-domain calls hlist[domain].remotectlhandle = INVALID_HANDLE; VERIFY(AEE_SUCCESS == - (nErr = remotectl_open(name, (int *)ph, dlerrstr, - sizeof(dlerrstr), &dlerr))); + (nErr = remotectl_open_v2(name, (const char*)source_vaddr, + filelen, (int *)ph, dlerrstr, sizeof(dlerrstr), &dlerr))); } } else { VERIFY(AEE_SUCCESS == - (nErr = remotectl_open(name, (int *)ph, dlerrstr, - sizeof(dlerrstr), &dlerr))); + (nErr = remotectl_open_v2(name, (const char*)source_vaddr, + filelen, (int *)ph, dlerrstr, sizeof(dlerrstr), &dlerr))); } VERIFY(AEE_SUCCESS == (nErr = dlerr));); bail: if (dlerr != 0) { @@ -1752,6 +1805,7 @@ int remote_handle_open(const char *name, remote_handle *ph) { int nErr = 0, domain = -1, ref = 0; uint64_t t_spawn = 0, t_load = 0; remote_handle64 local; + int fd = -1; VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once())); @@ -1766,9 +1820,9 @@ int remote_handle_open(const char *name, remote_handle *ph) { domain = get_current_domain(); FASTRPC_GET_REF(domain); - VERIFY(AEE_SUCCESS == (nErr = remote_handle_open_domain(domain, name, ph, + VERIFY(AEE_SUCCESS == (nErr = remote_handle_open_domain(domain, name, ph, &fd, &t_spawn, &t_load))); - fastrpc_update_module_list(NON_DOMAIN_LIST_PREPEND, domain, *ph, &local, name); + fastrpc_update_module_list(NON_DOMAIN_LIST_PREPEND, domain, *ph, &local, name, fd); bail: if (nErr) { if (*ph) { @@ -1795,6 +1849,9 @@ int remote_handle64_open(const char *name, remote_handle64 *ph) { remote_handle64 remote = 0, local; int domain = -1, nErr = 0, ref = 0; uint64_t t_spawn = 0, t_load = 0; + int fd = -1; + clock_t st, et; + double time_used; VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once())); FARF(RUNTIME_RPC_HIGH, "Entering %s, name %s\n", __func__, name); @@ -1808,8 +1865,14 @@ int remote_handle64_open(const char *name, remote_handle64 *ph) { domain = get_domain_from_name(name, DOMAIN_NAME_IN_URI); VERIFYC(domain >= 0, AEE_EBADPARM); FASTRPC_GET_REF(domain); - VERIFY(AEE_SUCCESS == (nErr = remote_handle_open_domain(domain, name, &h, + + st = clock(); + VERIFY(AEE_SUCCESS == (nErr = remote_handle_open_domain(domain, name, &h, &fd, &t_spawn, &t_load))); + et = clock(); + time_used = ((double) (et - st)) / CLOCKS_PER_SEC * 1000 * 1000; + FARF(ALWAYS, "Time took by modified function: %f ms", time_used); + /* Returning local handle to "geteventd" call causes bad fd error when daemon polls on it, hence return remote handle (which is the actual fd) for "geteventd" call*/ @@ -1818,7 +1881,7 @@ int remote_handle64_open(const char *name, remote_handle64 *ph) { IS_STATICPD_HANDLE(h)) { *ph = h; } else { - fastrpc_update_module_list(DOMAIN_LIST_PREPEND, domain, h, &local, name); + fastrpc_update_module_list(DOMAIN_LIST_PREPEND, domain, h, &local, name, fd); get_handle_remote(local, &remote); *ph = local; } @@ -1851,6 +1914,10 @@ int remote_handle_close_domain(int domain, remote_handle h) { uint64_t t_close = 0; remote_handle64 handle = INVALID_HANDLE; + int fd = -1; + get_fd_for_handle(domain, &hlist[domain].ql, h, &fd); + // FARF(ALWAYS, " ===== fd(%d) with handle 0x%x =====", fd, h); + FASTRPC_ATRACE_BEGIN_L("%s called with handle 0x%x", __func__, (int)h); VERIFYC(h != (remote_handle)-1, AEE_EINVHANDLE); VERIFYC(NULL != (dlerrstr = (char *)calloc(1, err_str_len)), AEE_ENOMEMORY); @@ -1865,7 +1932,7 @@ int remote_handle_close_domain(int domain, remote_handle h) { "%d\n", nErr, __func__, domain); fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, - _const_remotectl1_handle, NULL, NULL); + _const_remotectl1_handle, NULL, NULL, -1); // Set remotectlhandle to INVALID_HANDLE, so that all subsequent calls // are non-domain calls @@ -1877,6 +1944,12 @@ int remote_handle_close_domain(int domain, remote_handle h) { VERIFY(AEE_SUCCESS == (nErr = remotectl_close(h, dlerrstr, err_str_len, &dlerr))); } VERIFY(AEE_SUCCESS == (nErr = dlerr));); + + nErr = apps_std_fclose_fd(fd); + if(nErr == AEE_SUCCESS) { + FARF(ALWAYS, "===== Successfully file closed using fd(%d) =====", fd); + } + bail: if (nErr != AEE_SUCCESS) { if (0 == check_rpc_error(nErr)) { @@ -1907,7 +1980,7 @@ int remote_handle_close(remote_handle h) { PRINT_WARN_USE_DOMAINS(); VERIFY(AEE_SUCCESS == (nErr = remote_handle_close_domain(domain, h))); FASTRPC_PUT_REF(domain); - fastrpc_update_module_list(NON_DOMAIN_LIST_DEQUEUE, domain, h, NULL, NULL); + fastrpc_update_module_list(NON_DOMAIN_LIST_DEQUEUE, domain, h, NULL, NULL, -1); bail: if (nErr != AEE_SUCCESS) { if (is_process_exiting(domain)) { @@ -1948,6 +2021,20 @@ int remote_handle64_close(remote_handle64 handle) { */ if (hlist[domain].domainsCount <= 1 && !hlist[domain].nondomainsCount) start_deinit = true; + + // ------------------------------------------------------------------------------- + // FARF(ALWAYS, "domainsCount : %u, nondomainsCount : %u", hlist[domain].domainsCount, + // hlist[domain].nondomainsCount); + // if(!start_deinit) { + // FARF(ALWAYS, "===== start_deinit : false ====="); + // } + // if(remote) { + // FARF(ALWAYS, "remote handle 0x%" PRIx64, remote); + // } + // ------------------------------------------------------------------------------- + + // not all fds are closed because of start_deinit = true for domainsCount <= 1; + /* * If session termination is not initiated and the remote handle is valid, * then close the remote handle on DSP. @@ -1959,7 +2046,7 @@ int remote_handle64_close(remote_handle64 handle) { FARF(ALWAYS, "%s: closed module %s with handle 0x%" PRIx64 " remote handle 0x%" PRIx64 ", num of open handles: %u", __func__, hi->name, handle, remote, hlist[domain].domainsCount - 1); - fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, handle, NULL, NULL); + fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, handle, NULL, NULL, -1); FASTRPC_PUT_REF(domain); bail: if (nErr != AEE_EINVHANDLE && IS_VALID_EFFECTIVE_DOMAIN_ID(domain)) { @@ -2008,7 +2095,7 @@ static int manage_adaptive_qos(int domain, uint32_t enable) { "%d\n", nErr, __func__, domain); fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, - _const_remotectl1_handle, NULL, NULL); + _const_remotectl1_handle, NULL, NULL, -1); // Set remotectlhandle to INVALID_HANDLE, so that all subsequent calls // are non-domain calls @@ -3906,7 +3993,7 @@ remote_handle64 get_adsp_current_process1_handle(int domain) { } VERIFY(AEE_SUCCESS == (nErr = fastrpc_update_module_list( DOMAIN_LIST_PREPEND, domain, - _const_adsp_current_process1_handle, &local, NULL))); + _const_adsp_current_process1_handle, &local, NULL, -1))); hlist[domain].cphandle = local; return hlist[domain].cphandle; bail: @@ -3928,7 +4015,7 @@ remote_handle64 get_adspmsgd_adsp1_handle(int domain) { } VERIFY(AEE_SUCCESS == (nErr = fastrpc_update_module_list( DOMAIN_LIST_PREPEND, domain, - _const_adspmsgd_adsp1_handle, &local, NULL))); + _const_adspmsgd_adsp1_handle, &local, NULL, -1))); hlist[domain].msghandle = local; return hlist[domain].msghandle; bail: @@ -3949,7 +4036,7 @@ remote_handle64 get_adsp_listener1_handle(int domain) { } VERIFY(AEE_SUCCESS == (nErr = fastrpc_update_module_list( DOMAIN_LIST_PREPEND, domain, - _const_adsp_listener1_handle, &local, NULL))); + _const_adsp_listener1_handle, &local, NULL, -1))); hlist[domain].listenerhandle = local; return hlist[domain].listenerhandle; bail: @@ -3971,7 +4058,7 @@ remote_handle64 get_remotectl1_handle(int domain) { } VERIFY(AEE_SUCCESS == (nErr = fastrpc_update_module_list(DOMAIN_LIST_PREPEND, domain, - _const_remotectl1_handle, &local, NULL))); + _const_remotectl1_handle, &local, NULL, -1))); hlist[domain].remotectlhandle = local; return hlist[domain].remotectlhandle; bail: @@ -3991,7 +4078,7 @@ remote_handle64 get_adsp_perf1_handle(int domain) { } VERIFY(AEE_SUCCESS == (nErr = fastrpc_update_module_list(DOMAIN_LIST_PREPEND, domain, - _const_adsp_perf1_handle, &local, NULL))); + _const_adsp_perf1_handle, &local, NULL, -1))); hlist[domain].adspperfhandle = local; return hlist[domain].adspperfhandle; bail: diff --git a/src/fastrpc_mem.c b/src/fastrpc_mem.c index 99594270..ee8ed117 100644 --- a/src/fastrpc_mem.c +++ b/src/fastrpc_mem.c @@ -440,6 +440,22 @@ int fdlist_fd_from_buf(void *buf, int bufLen, int *nova, void **base, int *attr, return 0; } +void* get_source_vaddr(int fd, int domain) { + struct static_map *tNode = NULL; + QNode *pn, *pnn; + /* Search for mapping in current session static map list */ + pthread_mutex_lock(&smaplst[domain].mut); + QLIST_NEXTSAFE_FOR_ALL(&smaplst[domain].ql, pn, pnn) { + tNode = STD_RECOVER_REC(struct static_map, qn, pn); + if (tNode->map.fd == fd) { + break; + } + } + pthread_mutex_unlock(&smaplst[domain].mut); + + return (void*)tNode->map.vaddrin; +} + int fastrpc_mmap(int domain, int fd, void *vaddr, int offset, size_t length, enum fastrpc_map_flags flags) { struct fastrpc_map map = {0}; diff --git a/src/fastrpc_perf.c b/src/fastrpc_perf.c index 87d897fc..5e14e014 100644 --- a/src/fastrpc_perf.c +++ b/src/fastrpc_perf.c @@ -249,7 +249,7 @@ static int perf_dsp_enable(int domain) { FARF(ALWAYS, "Warning 0x%x: %s: adsp_perf1 domains not supported for domain %d\n", nErr, __func__, domain); - fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, _const_adsp_perf1_handle, NULL, NULL); + fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, _const_adsp_perf1_handle, NULL, NULL, -1); gperf.adsp_perf_handle = INVALID_HANDLE; VERIFY(0 == (nErr = adsp_perf_get_keys(keys, PERF_KEY_STR_MAX, &maxLen, &numKeys))); diff --git a/src/listener_android.c b/src/listener_android.c index 077fa2cf..36f6ec12 100644 --- a/src/listener_android.c +++ b/src/listener_android.c @@ -59,7 +59,7 @@ __QAIC_IMPL(apps_remotectl_open)(const char *name, uint32 *handle, char *dlStr, (nErr = mod_table_open(name, handle, dlStr, dlerrorLen, dlErr))); VERIFY(AEE_SUCCESS == (nErr = fastrpc_update_module_list( - REVERSE_HANDLE_LIST_PREPEND, domain, (remote_handle)*handle, &local, NULL))); + REVERSE_HANDLE_LIST_PREPEND, domain, (remote_handle)*handle, &local, NULL, -1))); bail: return nErr; } @@ -81,7 +81,7 @@ __QAIC_IMPL(apps_remotectl_close)(uint32 handle, char *errStr, int errStrLen, } VERIFY(AEE_SUCCESS == (nErr = fastrpc_update_module_list( - REVERSE_HANDLE_LIST_DEQUEUE, domain, (remote_handle)handle, NULL, NULL))); + REVERSE_HANDLE_LIST_DEQUEUE, domain, (remote_handle)handle, NULL, NULL, -1))); bail: return nErr; } @@ -350,7 +350,7 @@ static void *listener_start_thread(void *arg) { nErr == DSP_AEE_EOFFSET + AEE_ENOSUCHMOD) { FARF(ERROR, "Error 0x%x: %s domains support not available in listener", nErr, __func__); - fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, _const_adsp_listener1_handle, NULL, NULL); + fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, _const_adsp_listener1_handle, NULL, NULL, -1); adsp_listener1_handle = INVALID_HANDLE; VERIFY(AEE_SUCCESS == (nErr = __QAIC_HEADER(adsp_listener_init2)())); } else if (nErr == AEE_SUCCESS) { diff --git a/src/mod_table.c b/src/mod_table.c index 54009eea..16698276 100644 --- a/src/mod_table.c +++ b/src/mod_table.c @@ -123,15 +123,6 @@ struct const_mod { char uri[1]; }; -struct parsed_uri { - const char *file; - const char *sym; - const char *ver; - int filelen; - int symlen; - int verlen; -}; - struct open_mod { void *dlhandle; invoke_fn invoke; @@ -359,7 +350,7 @@ static int notqmark(struct sbuf *buf) { return sbuf_notchar(buf, '?'); } static int notandoreq(struct sbuf *buf) { return sbuf_notchars(buf, "&="); } static int notand(struct sbuf *buf) { return sbuf_notchar(buf, '&'); } -static int parse_uri(const char *uri, int urilen, struct parsed_uri *out) { +int parse_uri(const char *uri, int urilen, struct parsed_uri *out) { // "file:///librhtest_skel.so?rhtest_skel_handle_invoke&_modver=1.0" int nErr = 0; char *name, *value; diff --git a/src/remotectl1_stub.c b/src/remotectl1_stub.c index 0a5ca6c9..e692452d 100644 --- a/src/remotectl1_stub.c +++ b/src/remotectl1_stub.c @@ -277,14 +277,14 @@ struct Interface { static const Type types[2]; static const Type types[2] = {{0x1,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x1},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4}}; -static const Parameter parameters[8] = {{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)0x0,0}}, 4,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x4,0x8),{{(const uintptr_t)0xdeadc0de,(const uintptr_t)0}}, 0,SLIM_IFPTR32(0x4,0x8),3,0},{SLIM_IFPTR32(0x4,0x8),{{(const uintptr_t)0xdeadc0de,(const uintptr_t)0}}, 0,SLIM_IFPTR32(0x4,0x8),0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,3,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),3,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[1]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),0,0}}; -static const Parameter* const parameterArrays[14] = {(&(parameters[0])),(&(parameters[3])),(&(parameters[4])),(&(parameters[3])),(&(parameters[5])),(&(parameters[4])),(&(parameters[3])),(&(parameters[5])),(&(parameters[7])),(&(parameters[6])),(&(parameters[6])),(&(parameters[0])),(&(parameters[1])),(&(parameters[2]))}; -static const Method methods[6] = {{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x1),0x4,0x0,2,2,(&(parameterArrays[11])),0x4,0x1},{REMOTE_SCALARS_MAKEX(0,0,0x0,0x0,0x1,0x0),0x0,0x0,1,1,(&(parameterArrays[13])),0x1,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x2,0x2,0x0,0x0),0x8,0x8,6,4,(&(parameterArrays[0])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x2,0x0,0x0),0x8,0x4,5,3,(&(parameterArrays[4])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x0,0x0,0x0),0x8,0x0,2,2,(&(parameterArrays[9])),0x4,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x0),0x8,0x0,3,2,(&(parameterArrays[7])),0x4,0x0}}; -static const Method* const methodArrays[6] = {&(methods[0]),&(methods[1]),&(methods[2]),&(methods[3]),&(methods[4]),&(methods[5])}; -static const char strings[103] = "set_param\0grow_heap\0phyAddr\0dlerror\0params\0close1\0handle\0reqID\0nSize\0open1\0close\0nErr\0name\0open\0uri\0h\0"; -static const uint16_t methodStrings[20] = {69,86,50,28,81,43,50,28,81,0,57,36,10,20,63,91,96,100,75,100}; -static const uint16_t methodStringsArrays[6] = {15,18,0,5,12,9}; -__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(remotectl1_slim) = {6,&(methodArrays[0]),0,0,&(methodStringsArrays [0]),methodStrings,strings}; +static const Parameter parameters[9] = {{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)0x0,0}}, 4,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x4,0x8),{{(const uintptr_t)0xdeadc0de,(const uintptr_t)0}}, 0,SLIM_IFPTR32(0x4,0x8),3,0},{SLIM_IFPTR32(0x4,0x8),{{(const uintptr_t)0xdeadc0de,(const uintptr_t)0}}, 0,SLIM_IFPTR32(0x4,0x8),0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,3,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),3,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[1]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),0,0}}; +static const Parameter* const parameterArrays[19] = {(&(parameters[0])),(&(parameters[8])),(&(parameters[3])),(&(parameters[4])),(&(parameters[3])),(&(parameters[0])),(&(parameters[3])),(&(parameters[4])),(&(parameters[3])),(&(parameters[5])),(&(parameters[4])),(&(parameters[3])),(&(parameters[5])),(&(parameters[7])),(&(parameters[6])),(&(parameters[6])),(&(parameters[0])),(&(parameters[1])),(&(parameters[2]))}; +static const Method methods[7] = {{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x1),0x4,0x0,2,2,(&(parameterArrays[16])),0x4,0x1},{REMOTE_SCALARS_MAKEX(0,0,0x0,0x0,0x1,0x0),0x0,0x0,1,1,(&(parameterArrays[18])),0x1,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x2,0x2,0x0,0x0),0x8,0x8,6,4,(&(parameterArrays[5])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x2,0x0,0x0),0x8,0x4,5,3,(&(parameterArrays[9])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x0,0x0,0x0),0x8,0x0,2,2,(&(parameterArrays[14])),0x4,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x0),0x8,0x0,3,2,(&(parameterArrays[12])),0x4,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x3,0x2,0x0,0x0),0xc,0x8,8,5,(&(parameterArrays[0])),0x4,0x4}}; +static const Method* const methodArrays[7] = {&(methods[0]),&(methods[1]),&(methods[2]),&(methods[3]),&(methods[4]),&(methods[5]),&(methods[6])}; +static const char strings[116] = "set_param\0grow_heap\0open1_v2\0phyAddr\0dlerror\0params\0close1\0handle\0reqID\0nSize\0open1\0close\0nErr\0name\0open\0buf\0uri\0h\0"; +static const uint16_t methodStrings[26] = {20,95,105,59,37,90,78,95,59,37,90,52,59,37,90,0,66,45,10,29,72,100,109,113,84,113}; +static const uint16_t methodStringsArrays[7] = {21,24,6,11,18,15,0}; +__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(remotectl1_slim) = {7,&(methodArrays[0]),0,0,&(methodStringsArrays [0]),methodStrings,strings}; #endif //_REMOTECTL1_SLIM_H @@ -402,6 +402,44 @@ __QAIC_STUB_EXPORT int __QAIC_STUB(remotectl1_set_param)(remote_handle64 _handle uint32_t _mid = 5; return _stub_method_3(_handle, _mid, (uint32_t*)&reqID, (char**)¶ms, (uint32_t*)¶msLen); } +static __inline int _stub_method_4(remote_handle64 _handle, uint32_t _mid, char* _in0[1], char* _in1[1], uint32_t _in1Len[1], uint32_t _rout2[1], char* _rout3[1], uint32_t _rout3Len[1], uint32_t _rout4[1]) { + uint32_t _in0Len[1] = {0}; + int _numIn[1] = {0}; + remote_arg _pra[5] = {0}; + uint32_t _primIn[3]= {0}; + uint32_t _primROut[2]= {0}; + remote_arg* _praIn = 0; + remote_arg* _praROut = 0; + int _nErr = 0; + _numIn[0] = 2; + _pra[0].buf.pv = (void*)_primIn; + _pra[0].buf.nLen = sizeof(_primIn); + _pra[(_numIn[0] + 1)].buf.pv = (void*)_primROut; + _pra[(_numIn[0] + 1)].buf.nLen = sizeof(_primROut); + _in0Len[0] = (uint32_t)(1 + strlen(_in0[0])); + _COPY(_primIn, 0, _in0Len, 0, 4); + _praIn = (_pra + 1); + _praIn[0].buf.pv = (void*) _in0[0]; + _praIn[0].buf.nLen = (1 * _in0Len[0]); + _COPY(_primIn, 4, _in1Len, 0, 4); + _praIn[1].buf.pv = (void*) _in1[0]; + _praIn[1].buf.nLen = (1 * _in1Len[0]); + _COPY(_primIn, 8, _rout3Len, 0, 4); + _praROut = (_praIn + _numIn[0] + 1); + _praROut[0].buf.pv = _rout3[0]; + _praROut[0].buf.nLen = (1 * _rout3Len[0]); + _TRY_FARF(_nErr, __QAIC_REMOTE(remote_handle64_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 3, 2, 0, 0), _pra)); + _COPY(_rout2, 0, _primROut, 0, 4); + _COPY(_rout4, 0, _primROut, 4, 4); + _CATCH_FARF(_nErr) { + _QAIC_FARF(RUNTIME_ERROR, "ERROR 0x%x: handle=0x%"PRIx64", scalar=0x%x, method ID=%d: %s failed\n", _nErr , _handle, REMOTE_SCALARS_MAKEX(0, _mid, 3, 2, 0, 0), _mid, __func__); + } + return _nErr; +} +__QAIC_STUB_EXPORT int __QAIC_STUB(remotectl1_open1_v2)(remote_handle64 _handle, const char* name, const char* buf, int bufLen, int* handle, char* dlerror, int dlerrorLen, int* nErr) __QAIC_STUB_ATTRIBUTE { + uint32_t _mid = 6; + return _stub_method_4(_handle, _mid, (char**)&name, (char**)&buf, (uint32_t*)&bufLen, (uint32_t*)handle, (char**)&dlerror, (uint32_t*)&dlerrorLen, (uint32_t*)nErr); +} #ifdef __cplusplus } #endif diff --git a/src/remotectl_stub.c b/src/remotectl_stub.c index 8b55482c..d53cd358 100644 --- a/src/remotectl_stub.c +++ b/src/remotectl_stub.c @@ -436,14 +436,14 @@ struct Interface { static const Type types[2]; static const Type types[2] = {{0x1,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x1},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4}}; -static const Parameter parameters[6] = {{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)0x0,0}}, 4,SLIM_IFPTR32(0x4,0x8),0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,3,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),3,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[1]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),0,0}}; -static const Parameter* const parameterArrays[11] = {(&(parameters[0])),(&(parameters[1])),(&(parameters[2])),(&(parameters[1])),(&(parameters[3])),(&(parameters[2])),(&(parameters[1])),(&(parameters[3])),(&(parameters[5])),(&(parameters[4])),(&(parameters[4]))}; -static const Method methods[4] = {{REMOTE_SCALARS_MAKEX(0,0,0x2,0x2,0x0,0x0),0x8,0x8,6,4,(&(parameterArrays[0])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x2,0x0,0x0),0x8,0x4,5,3,(&(parameterArrays[4])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x0,0x0,0x0),0x8,0x0,2,2,(&(parameterArrays[9])),0x4,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x0),0x8,0x0,3,2,(&(parameterArrays[7])),0x4,0x0}}; -static const Method* const methodArrays[4] = {&(methods[0]),&(methods[1]),&(methods[2]),&(methods[3])}; -static const char strings[84] = "set_param\0grow_heap\0phyAddr\0dlerror\0params\0handle\0reqID\0nSize\0close\0nErr\0name\0open\0"; -static const uint16_t methodStrings[15] = {78,73,43,28,68,62,43,28,68,0,50,36,10,20,56}; -static const uint16_t methodStringsArrays[4] = {0,5,12,9}; -__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(remotectl_slim) = {4,&(methodArrays[0]),0,0,&(methodStringsArrays [0]),methodStrings,strings}; +static const Parameter parameters[7] = {{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)0x0,0}}, 4,SLIM_IFPTR32(0x4,0x8),0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,3,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),3,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{0x4,{{(const uintptr_t)0,(const uintptr_t)1}}, 2,0x4,0,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[1]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),0,0}}; +static const Parameter* const parameterArrays[16] = {(&(parameters[0])),(&(parameters[6])),(&(parameters[1])),(&(parameters[2])),(&(parameters[1])),(&(parameters[0])),(&(parameters[1])),(&(parameters[2])),(&(parameters[1])),(&(parameters[3])),(&(parameters[2])),(&(parameters[1])),(&(parameters[3])),(&(parameters[5])),(&(parameters[4])),(&(parameters[4]))}; +static const Method methods[5] = {{REMOTE_SCALARS_MAKEX(0,0,0x2,0x2,0x0,0x0),0x8,0x8,6,4,(&(parameterArrays[5])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x2,0x0,0x0),0x8,0x4,5,3,(&(parameterArrays[9])),0x4,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x1,0x0,0x0,0x0),0x8,0x0,2,2,(&(parameterArrays[14])),0x4,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x2,0x0,0x0,0x0),0x8,0x0,3,2,(&(parameterArrays[12])),0x4,0x0},{REMOTE_SCALARS_MAKEX(0,0,0x3,0x2,0x0,0x0),0xc,0x8,8,5,(&(parameterArrays[0])),0x4,0x4}}; +static const Method* const methodArrays[5] = {&(methods[0]),&(methods[1]),&(methods[2]),&(methods[3]),&(methods[4])}; +static const char strings[96] = "set_param\0grow_heap\0open_v2\0phyAddr\0dlerror\0params\0handle\0reqID\0nSize\0close\0nErr\0name\0open\0buf\0"; +static const uint16_t methodStrings[21] = {20,81,91,51,36,76,86,81,51,36,76,70,51,36,76,0,58,44,10,28,64}; +static const uint16_t methodStringsArrays[5] = {6,11,18,15,0}; +__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(remotectl_slim) = {5,&(methodArrays[0]),0,0,&(methodStringsArrays [0]),methodStrings,strings}; #endif //_REMOTECTL_SLIM_H #ifdef __cplusplus extern "C" { @@ -668,6 +668,48 @@ __QAIC_STUB_EXPORT int __QAIC_STUB(remotectl_set_param)(int reqID, const uint32* return AEE_EINVHANDLE; } } +static __inline int _stub_method_4(remote_handle _handle, uint32_t _mid, char* _in0[1], char* _in1[1], uint32_t _in1Len[1], uint32_t _rout2[1], char* _rout3[1], uint32_t _rout3Len[1], uint32_t _rout4[1]) { + uint32_t _in0Len[1] = {0}; + int _numIn[1] = {0}; + remote_arg _pra[5] = {0}; + uint32_t _primIn[3]= {0}; + uint32_t _primROut[2]= {0}; + remote_arg* _praIn = 0; + remote_arg* _praROut = 0; + int _nErr = 0; + _numIn[0] = 2; + _pra[0].buf.pv = (void*)_primIn; + _pra[0].buf.nLen = sizeof(_primIn); + _pra[(_numIn[0] + 1)].buf.pv = (void*)_primROut; + _pra[(_numIn[0] + 1)].buf.nLen = sizeof(_primROut); + _in0Len[0] = (uint32_t)(1 + strlen(_in0[0])); + _COPY(_primIn, 0, _in0Len, 0, 4); + _praIn = (_pra + 1); + _praIn[0].buf.pv = (void*) _in0[0]; + _praIn[0].buf.nLen = (1 * _in0Len[0]); + _COPY(_primIn, 4, _in1Len, 0, 4); + _praIn[1].buf.pv = (void*) _in1[0]; + _praIn[1].buf.nLen = (1 * _in1Len[0]); + _COPY(_primIn, 8, _rout3Len, 0, 4); + _praROut = (_praIn + _numIn[0] + 1); + _praROut[0].buf.pv = _rout3[0]; + _praROut[0].buf.nLen = (1 * _rout3Len[0]); + _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 3, 2, 0, 0), _pra)); + _COPY(_rout2, 0, _primROut, 0, 4); + _COPY(_rout4, 0, _primROut, 4, 4); + _CATCH(_nErr) {} + return _nErr; +} +__QAIC_STUB_EXPORT int __QAIC_STUB(remotectl_open_v2)(const char* name, const char* buf, int bufLen, int* handle, char* dlerror, int dlerrorLen, int* nErr) __QAIC_STUB_ATTRIBUTE { + uint32_t _mid = 4; + remote_handle _handle = _remotectl_handle(); + if (_handle != (remote_handle)-1){ + return _stub_method_4(_handle, _mid, (char**)&name, (char**)&buf, (uint32_t*)&bufLen, (uint32_t*)handle, (char**)&dlerror, (uint32_t*)&dlerrorLen, (uint32_t*)nErr); + } + else { + return AEE_EINVHANDLE; + } +} #ifdef __cplusplus } #endif