Browse Source

[libc] add comments for libdl APIs.

ligr 7 months ago
parent
commit
f0934630c4

+ 1 - 1
components/libc/posix/libdl/arch/arm.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 1 - 1
components/libc/posix/libdl/arch/riscv.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 1 - 1
components/libc/posix/libdl/arch/x86.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 10 - 1
components/libc/posix/libdl/dlclose.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -13,6 +13,15 @@
 
 #include "dlmodule.h"
 
+/**
+ * @brief  close a dynamically loaded shared library.
+ *
+ * @param  handle the handle which identifies the shared library to be closed.
+ * @return int it returns RT_TRUE on success.
+ *
+ * @note   This function is an API of POSIX standard, which is designed to decrease the reference count (nref) for a dynamically loaded module
+ *         and destroy it if no references remain.
+ */
 int dlclose(void *handle)
 {
     struct rt_dlmodule *module;

+ 43 - 2
components/libc/posix/libdl/dlelf.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -14,8 +14,32 @@
 
 #define DBG_TAG    "DLMD"
 #define DBG_LVL    DBG_INFO
-#include <rtdbg.h>          // must after of DEBUG_ENABLE or some other options
+#include <rtdbg.h>          /* must after of DEBUG_ENABLE or some other options*/
 
+/**
+ * @brief Load a shared object file into memory.
+ *
+ * @param module A pointer to a rt_dlmodule object for holding the module's information.
+ * @param module_ptr A pointer to the raw memory of the ELF file (shared object) that is being loaded.
+ * @return rt_err_t On success, it returns RT_EOK. Otherwise, it returns the error code.
+ *
+ * @note This function loads a shared object (ELF file) into memory, broken down into steps:
+ *       1. Initialization and Validation: it begins by validating the module pointer
+ *          and checking if the ELF file has been linked by comparing its magic number (RTMMAG).
+ *          If matched, the module is considered linked.
+ *       2. Calculating the ELF Image Size: it iterates over the ELF program headers to compute the total size of the ELF image
+ *          by adding the sizes of loadable segments. It also ensures there are no overlaps or invalid addresses in the segments.
+ *       3. Allocating Memory for the Module: After determining the module size, the function allocates memory (module->mem_space) for the ELF image
+ *          and initializes it to zero. Then, it copies the relevant program segments from the ELF file into this allocated memory.
+ *       4. Setting the Module Entry Point: it sets the entry point address (module->entry_addr) based on the ELF entry point adjusted by the calculated base address.
+ *       5. Handling Relocation Sections: It processes each relocation section in the ELF file.
+ *          For each relocation entry, it either resolves the symbol from the module's own symbol table
+ *          or looks up the symbol in the kernel symbol table if it was not found locally.
+ *       6. Building the Module's Symbol Table: it looks for the .dynsym section to extract global function symbols.
+ *          It creates a symbol table (module->symtab) and populates it with the function names and addresses for all global symbols of type STT_FUNC.
+ *       7. Extracting Additional Parameters: It extracts additional parameters, such as thread priority (dlmodule_thread_priority) and stack size (dlmodule_thread_stacksize),
+ *          from the symbol table and assigns them to the module if valid.
+ */
 rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_ptr)
 {
     rt_bool_t linked   = RT_FALSE;
@@ -273,6 +297,23 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt
     return RT_EOK;
 }
 
+/**
+ * @brief Load a relocatable file into memory.
+ *
+ * @param module A pointer to a rt_dlmodule object for holding the module's information.
+ * @param module_ptr A pointer to the raw memory of the ELF file (relocatable file) that is being loaded.
+ * @return rt_err_t On success, it returns RT_EOK. Otherwise, it returns the error code.
+ *
+ * @note This function loads a relocatable file (ELF file) into memory, broken down step by step:
+ *       1. Calculate Module Size: iterates over the ELF sections (text, data, rodata, and bss) to calculate the total size of the module
+ *          and identifies the start address for each section.
+ *       2. Allocate Memory: It allocates memory for the module based on the calculated size. If allocation fails, an error is returned.
+ *       3. Load Sections into Memory: The function loads the text, rodata, data, and BSS sections into the allocated memory.
+ *          The BSS section is zeroed out, while the others are copied from the ELF image.
+ *       4. Set Entry Point: The entry point of the module is set by calculating the address relative to the start of the allocated memory.
+ *       5. Handle Relocation: It processes the relocation entries, resolving symbol addresses and relocating them as needed.
+ *          This includes functions, sections (rodata, bss, data), and external symbols from the kernel symbol table.
+ */
 rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module_ptr)
 {
     rt_ubase_t index, rodata_addr = 0, bss_addr = 0, data_addr = 0;

+ 1 - 1
components/libc/posix/libdl/dlelf.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 8 - 1
components/libc/posix/libdl/dlerror.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -11,6 +11,13 @@
 #include <rtthread.h>
 #include <rtm.h>
 
+/**
+ * @brief  retrieve a string describing the last error that occurred from a dynamic linking operation.
+ *
+ * @return const char* a string containing an error message describing the last error.
+ *
+ * @note   This function is an API of POSIX standard, which is still remaining TBD.
+ */
 const char *dlerror(void)
 {
     return "TODO";

+ 1 - 1
components/libc/posix/libdl/dlfcn.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 59 - 3
components/libc/posix/libdl/dlmodule.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -24,7 +24,7 @@
 
 #define DBG_TAG    "DLMD"
 #define DBG_LVL    DBG_INFO
-#include <rtdbg.h>          // must after of DEBUG_ENABLE or some other options
+#include <rtdbg.h>          /* must after of DEBUG_ENABLE or some other options*/
 
 static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL;
 static struct rt_module_symtab *_rt_module_symtab_end   = RT_NULL;
@@ -176,6 +176,11 @@ __exit:
     return ;
 }
 
+/**
+ * @brief create a dynamic module object and initialize it.
+ *
+ * @return struct rt_dlmodule* If module create successfully, return the pointer to its rt_dlmodule structure.
+ */
 struct rt_dlmodule *dlmodule_create(void)
 {
     struct rt_dlmodule *module = RT_NULL;
@@ -233,6 +238,12 @@ void dlmodule_destroy_subthread(struct rt_dlmodule *module, rt_thread_t thread)
 #endif
 }
 
+/**
+ * @brief destroy dynamic module and cleanup all kernel objects inside it.
+ *
+ * @param module Pointer to the module to be destroyed.
+ * @return rt_err_t  On success, it returns RT_EOK. Otherwise, it returns the error code.
+ */
 rt_err_t dlmodule_destroy(struct rt_dlmodule* module)
 {
     int i;
@@ -255,7 +266,7 @@ rt_err_t dlmodule_destroy(struct rt_dlmodule* module)
         rt_exit_critical();
     }
 
-    // list_object(&(module->object_list));
+    /* list_object(&(module->object_list));*/
 
     /* cleanup for all kernel objects inside module*/
     {
@@ -393,6 +404,11 @@ rt_err_t dlmodule_destroy(struct rt_dlmodule* module)
     return RT_EOK;
 }
 
+/**
+ * @brief retrieve the dynamically loaded module that the current thread belongs to.
+ *
+ * @return struct rt_dlmodule* On success, it returns a pointer to the module. otherwise, it returns RT_NULL.
+ */
 struct rt_dlmodule *dlmodule_self(void)
 {
     rt_thread_t tid;
@@ -415,6 +431,20 @@ struct rt_dlmodule *rt_module_self(void)
     return dlmodule_self();
 }
 
+/**
+ * @brief load an ELF module to memory.
+ *
+ * @param filename the path to the module to load.
+ * @return struct rt_dlmodule* On success, it returns a pointer to the module object. otherwise, RT_NULL is returned.
+ *
+ * @note the function is used to load an ELF (Executable and Linkable Format) module from a file, validate it,
+ *       and initialize it as a dynamically loaded module. what it implements are as follows:
+ *       1. Load and Validate ELF: It loads an ELF file, checks its validity, and identifies it as either a relocatable or shared object.
+ *       2. Memory Allocation and Cleanup: Uses rt_malloc and rt_free to allocate and free memory for module data.
+ *          Error handling ensures all resources are released if an error occurs.
+ *       3. Symbol Resolution and Initialization: Sets up init function and cleanup function, and calls the module_init function if it is present.
+ *       4. Cache Management: Optionally (when RT_USING_CACHE defined) flushes data and invalidates instruction caches to ensure the module is correctly loaded into memory.
+ */
 struct rt_dlmodule* dlmodule_load(const char* filename)
 {
 #ifdef RT_USING_POSIX_FS
@@ -525,6 +555,14 @@ __exit:
     return RT_NULL;
 }
 
+/**
+ * @brief load a dynamic module, and create a thread to excute the module main function.
+ *
+ * @param pgname path of the module to be loaded.
+ * @param cmd the command string (with commandline options) for startup module.
+ * @param cmd_size the command's length.
+ * @return struct rt_dlmodule* On success, it returns a pointer to the module object. otherwise, RT_NULL is returned.
+ */
 struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_size)
 {
     struct rt_dlmodule *module = RT_NULL;
@@ -742,6 +780,17 @@ struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, in
 }
 #endif
 
+/**
+ * @brief exit a dynamically loaded module.
+ *
+ * @param ret_code the return code for module exit.
+ *
+ * @note this function is responsible for gracefully exiting a dynamically loaded module, releasing resources associated with the module,
+ *       and handling cleanup operations. what it implements are as follows:
+ *       1. Thread and Resource Cleanup: The function safely exits a module by deleting its main thread and freeing resources associated with it.
+ *       2. Status Management: Checks and updates the module's state, setting a return code and calling _dlmodule_exit() to transition to a closing state.
+ *       3. Critical Sections: Critical sections ensure that the exit process is atomic and free from race conditions.
+ */
 void dlmodule_exit(int ret_code)
 {
     rt_thread_t thread;
@@ -784,6 +833,13 @@ void dlmodule_exit(int ret_code)
     rt_exit_critical();
 }
 
+/**
+ * @brief search for a symbol by its name in the kernel symbol table.
+ *
+ * @param sym_str the symbol name string.
+ * @return rt_uint32_t On success, it returns the address of the symbol.
+ *         Otherwise, it returns 0 (indicating the symbol was not found).
+ */
 rt_uint32_t dlmodule_symbol_find(const char *sym_str)
 {
     /* find in kernel symbol table */

+ 1 - 1
components/libc/posix/libdl/dlmodule.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 14 - 1
components/libc/posix/libdl/dlopen.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -16,6 +16,19 @@
 
 #define MODULE_ROOT_DIR     "/modules"
 
+/**
+ * @brief  dynamically load a shared library at runtime.
+ *
+ * @param  filename the path to the shared library to load, which shouldn't be set to NULL.
+ * @param  flags options for loading the shared library.
+ * @return void* on success, it returns a handle (a pointer) to the opened shared library, otherwise it returns NULL.
+ *
+ * @note   This function is an API of POSIX standard, which is used for dynamically loading shared libraries at runtime.
+ *         the function first tries to check if the module is already loaded, by finding module in module list.
+ *         If module is found in memory (RT_NULL check fails), the reference count (nref) is incremented.
+ *         Otherwise,  dlmodule_load() will be called to load the module into memory.
+ *         A handle (a pointer to the module) is returned at last, which can be used with other functions like dlsym().
+ */
 void* dlopen(const char *filename, int flags)
 {
     struct rt_dlmodule *module;

+ 12 - 1
components/libc/posix/libdl/dlsym.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -13,6 +13,17 @@
 
 #include "dlmodule.h"
 
+/**
+ * @brief  look up the address of a symbol in a dynamically loaded shared library.
+ *
+ * @param  handle the handle returned by dlopen() when the library was previously loaded.
+ * @param  symbol A string containing the name of the symbol to locate.
+ * @return void* On success, it returns a pointer to the symbol. Otherwise, it returns RT_NULL.
+ *
+ * @note   This function is an API of POSIX standard, which is commonly used in conjunction with dlopen() to retrieve function pointers from shared libraries.
+ *         the input symbol name, which can be the name of a function or variable, is compared with each symbol
+ *         in the module symbol table. if the same symbol is found, return its address.
+ */
 void* dlsym(void *handle, const char* symbol)
 {
     int i;

+ 1 - 1
components/libc/posix/libdl/dlsyms.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *