xiaoxiang781216 commented on code in PR #20492:
URL: https://github.com/apache/nuttx/pull/20492#discussion_r4250864451
##########
libs/libc/elf/elf_registry.c:
##########
@@ -46,13 +47,35 @@
* Private Data
****************************************************************************/
+/* One lock for every registry. g_mod_registry holds the kernel modules of
+ * insmod(); what dlopen() loads is on the registry of the task group.
+ */
+
static rmutex_t g_modlock = NXRMUTEX_INITIALIZER;
static FAR struct module_s *g_mod_registry;
/****************************************************************************
* Public Functions
****************************************************************************/
+/****************************************************************************
+ * Name: libelf_registry
+ ****************************************************************************/
+
+FAR struct module_s **libelf_registry(void)
+{
+ return &task_get_info()->ta_modules;
+}
+
+/****************************************************************************
+ * Name: libelf_registry_kernel
+ ****************************************************************************/
+
+FAR struct module_s **libelf_registry_kernel(void)
Review Comment:
move to module
##########
include/nuttx/lib/elf.h:
##########
@@ -175,6 +175,10 @@ struct fdpic_desc_s;
struct module_s
{
FAR struct module_s *flink; /* Supports a singly linked list */
+ FAR struct module_s **registry; /* The registry this module is on */
+ FAR struct module_s *libraries; /* exec(): its own registry, for
Review Comment:
why need add libraries/registry field? we just need a link list and hold the
head in tls
##########
libs/libc/elf/elf_bind.c:
##########
@@ -1040,7 +984,8 @@ static int libelf_relocatedyn(FAR struct module_s *modp,
return ret;
}
- handle = libelf_insertneeded((FAR const char *)loadinfo->iobuffer);
+ handle = libelf_insertneeded(modp->registry,
Review Comment:
why not insert to ta_modules
##########
libs/libc/elf/elf_registry.c:
##########
@@ -46,13 +47,35 @@
* Private Data
****************************************************************************/
+/* One lock for every registry. g_mod_registry holds the kernel modules of
+ * insmod(); what dlopen() loads is on the registry of the task group.
+ */
+
static rmutex_t g_modlock = NXRMUTEX_INITIALIZER;
static FAR struct module_s *g_mod_registry;
/****************************************************************************
* Public Functions
****************************************************************************/
+/****************************************************************************
+ * Name: libelf_registry
+ ****************************************************************************/
+
+FAR struct module_s **libelf_registry(void)
Review Comment:
move to dlfnc
##########
libs/libc/elf/elf_remove.c:
##########
@@ -289,3 +290,42 @@ int libelf_remove(FAR void *handle)
set_errno(-ret);
return ERROR;
}
+
+/****************************************************************************
+ * Name: libelf_closeall
+ *
+ * Description:
+ * Give back every reference that dlopen() took in a registry. A module
+ * that another one still depends on goes with its last dependent.
+ *
+ ****************************************************************************/
+
+void libelf_closeall(FAR struct module_s **registry)
Review Comment:
libelf_removeall
##########
Documentation/os/binfmt/kernel_modules_vs_shared_libraries.rst:
##########
@@ -139,40 +139,52 @@ FLAT build.
Opening a Library More Than Once
================================
-In the FLAT and PROTECTED builds, ``dlopen()`` of a library that is already
+In the FLAT and PROTECTED builds, each task group has its own list of
+loaded libraries. ``dlopen()`` of a library that the task group already
loaded does not load a second copy and does not fail. It returns a handle to
the library that is already loaded and takes an additional reference on it.
Each successful ``dlopen()`` must be matched by a ``dlclose()``; the library
is unloaded only when the last handle is closed. Up to 255 handles may be
outstanding on one library; beyond that ``dlopen()`` fails with ``EMFILE``.
+The libraries that a task group did not close are closed when it exits.
+In the PROTECTED build only ``exit()`` closes them, so a task group that
+ends in another way leaves them loaded.
Some consequences worth keeping in mind:
* A library is identified by the *basename* of the path passed to
``dlopen()``. Two files with the same basename in different directories
are treated as the same library, and the second ``dlopen()`` will return
the first one.
-* There is only one instance of the library's ``.data`` and ``.bss``. Global
- and static data are shared by every user of the library, and by every task
- group in the system.
-* Constructors in ``.init_array`` run once, when the library is first loaded,
- and destructors in ``.fini_array`` run once, when the last handle is
- closed. They do not run per ``dlopen()``/``dlclose()`` pair.
+* Each task group that opens a library loads its own copy. Global and static
+ data are shared by the threads of one task group, not between task groups.
+ Only an FDPIC library executed in place from xipfs shares its ``.text``
+ between task groups.
+* Constructors in ``.init_array`` run once per task group, when the library
+ is first loaded in it, and destructors in ``.fini_array`` run once, when
+ its last handle in the task group is closed. They do not run per
+ ``dlopen()``/``dlclose()`` pair.
+* The libraries that a program loaded by ``exec()`` names in ``DT_NEEDED``
+ belong to its task group in the FLAT build, so ``dlopen()`` of one of them
Review Comment:
does DT_NEEDED work in protected/kernel build now?
##########
libs/libc/elf/elf_remove.c:
##########
@@ -289,3 +290,42 @@ int libelf_remove(FAR void *handle)
set_errno(-ret);
return ERROR;
}
+
+/****************************************************************************
+ * Name: libelf_closeall
+ *
+ * Description:
+ * Give back every reference that dlopen() took in a registry. A module
+ * that another one still depends on goes with its last dependent.
+ *
+ ****************************************************************************/
+
+void libelf_closeall(FAR struct module_s **registry)
+{
+ FAR struct module_s *modp;
+
+ libelf_registry_lock();
Review Comment:
should use per task lock from tls
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]