[libc] add comments for libdl APIs.
This commit is contained in:
parent
20263be180
commit
f0934630c4
|
@ -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,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,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,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;
|
||||
|
|
|
@ -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,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,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,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,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,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,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;
|
||||
|
|
|
@ -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,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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue