From d52c1e2ba61ad55c7e3d094533a77e656b6344e3 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Sun, 27 Mar 2022 22:07:25 -0700 Subject: [PATCH] usb-gadget: access external symbol using dlsym(), not extern keyword The variable declared as extern storage class must be resolved when the symbol is loaded onto memory regardless of lazy binding. Therefore if a symbol doesn't exist on being loaded, the whole library loading will fail. To avoid this, explicitly load a symbol using dlsym(), which is able to handle undefined symbol error. This is mainly because the device-common shared library contains both of udev and usb-gadget, making them always be loaded onto memory together even if a caller only wants to use udev, not usb-gadget. This structure should be revamped later. Change-Id: Ia2bd7801123c812976ce79f0e0b880e6f1e67463 Signed-off-by: Youngjae Cho (cherry picked from commit 8634169cbcf0ddbe90adbf7babf0ff37745d72d5) --- CMakeLists.txt | 1 + src/usb_gadget/usb_gadget.h | 29 ---------------------- src/usb_gadget/usb_gadget_common.c | 50 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d24f59..2a9ed4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ ENDFOREACH(flag) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +ADD_DEFINITIONS("-D_GNU_SOURCE") ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) IF(ENABLE_DLOG STREQUAL on) diff --git a/src/usb_gadget/usb_gadget.h b/src/usb_gadget/usb_gadget.h index 1f66457..466753f 100644 --- a/src/usb_gadget/usb_gadget.h +++ b/src/usb_gadget/usb_gadget.h @@ -17,35 +17,6 @@ #ifndef __HW_USB_GADGET_H__ #define __HW_USB_GADGET_H__ -/************************************** - * Those symbols must be initialized first in deviced - * - * The usb-gadget source code have been scattered throughout the deviced and device-common. - * Because of this, it might have been implemented that totally same data structure on the - * both side. To avoid this inefficiency, define/initialize the data structure on the - * deviced first, and device-common refer it through extern keyword. The deviced must have - * cflag -rdynamic or ldflag --export-dynamic so that the dlopen-ed device-common can refer - * those variables with extern keyword. - * - * Accessing symbol in this way would be removed when the usb-gadget of the device-common - * is integrated into the deviced. - */ -#include -#include - -struct _usb_mode_mapping_table { - int mode_v; /* Integer defined by vconf */ - unsigned int mode; /* Bitmap of usb function combination */ - struct usb_gadget_attrs attrs; -}; -extern GList *usb_mode_mapping_table_custom; - -struct service_config { - char name[128]; - int remain_after_disable; -}; -extern GList *service_config_list; -/**************************************/ struct usb_function *find_usb_function_by_id(int id); struct usb_function *find_usb_function_by_name(const char *name); diff --git a/src/usb_gadget/usb_gadget_common.c b/src/usb_gadget/usb_gadget_common.c index 3233604..02a92ed 100644 --- a/src/usb_gadget/usb_gadget_common.c +++ b/src/usb_gadget/usb_gadget_common.c @@ -19,6 +19,8 @@ #include #include +#include + #include #include #include @@ -28,6 +30,36 @@ static struct usb_function *_available_funcs[]; +/************************************** + * Those symbols must be initialized first in deviced + * + * The usb-gadget source code have been scattered throughout the deviced and device-common. + * Because of this, it might have been implemented that totally same data structure on the + * both side. To avoid this inefficiency, define/initialize the data structure on the + * deviced first, and device-common refer it through dlsym(). The deviced must have + * cflag -rdynamic or ldflag --export-dynamic so that the dlopen-ed device-common can refer + * those variables with dlsym(). + * + * Accessing symbol in this way would be removed when the usb-gadget of the device-common + * is integrated into the deviced. + */ +#include +#include + +struct _usb_mode_mapping_table { + int mode_v; /* Integer defined by vconf */ + unsigned int mode; /* Bitmap of usb function combination */ + struct usb_gadget_attrs attrs; +}; +static GList *usb_mode_mapping_table_custom; + +struct service_config { + char name[128]; + int remain_after_disable; +}; +static GList *service_config_list; +/**************************************/ + struct usb_function *find_usb_function_by_id(int id); static void simple_cleanup_config(struct usb_configuration *config) @@ -382,9 +414,27 @@ static void set_service_config(gpointer data, gpointer udata) EXPORT int simple_translator_open(hal_backend_usb_gadget_funcs *usb_gadget_funcs) { + char *dlerr; + if (!usb_gadget_funcs) return -EINVAL; + dlerror(); // clear any existing dl error + + usb_mode_mapping_table_custom = *(GList **) dlsym(RTLD_DEFAULT, "usb_mode_mapping_table_custom"); + dlerr = dlerror(); + if (dlerr) { + _E("%s", dlerr); + return -ENOTSUP; + } + + service_config_list = *(GList **) dlsym(RTLD_DEFAULT, "service_config_list"); + dlerr = dlerror(); + if (dlerr) { + _E("%s", dlerror()); + return -ENOTSUP; + } + /* e.g. * /hal/etc/deviced/usb_gadget.conf * -- 2.7.4