[libc] add comments for libdl APIs.

This commit is contained in:
ligr 2024-11-12 15:38:28 +08:00 committed by Rbb666
parent 20263be180
commit f0934630c4
13 changed files with 153 additions and 16 deletions

View File

@ -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
*

View File

@ -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
*

View File

@ -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
*

View File

@ -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;

View File

@ -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;

View File

@ -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
*

View File

@ -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";

View File

@ -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
*

View File

@ -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 */

View File

@ -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
*

View File

@ -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;

View File

@ -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;

View File

@ -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
*