From 7d735c335492a84ca4219a886754ba1cde2f415a Mon Sep 17 00:00:00 2001 From: Stefan Bucur Date: Mon, 28 Jul 2008 21:33:14 -0700 Subject: Implemented the initialization system of an ELF module. --- com32/elflink/elf_module.c | 30 +++++++++++++++++++++++++- com32/elflink/elf_module.h | 7 +++++-- com32/elflink/test_com32.c | 52 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 77 insertions(+), 12 deletions(-) diff --git a/com32/elflink/elf_module.c b/com32/elflink/elf_module.c index fbd596e4..fedebf7f 100644 --- a/com32/elflink/elf_module.c +++ b/com32/elflink/elf_module.c @@ -778,6 +778,28 @@ static int check_symbols(struct elf_module *module) { return 0; } +static int extract_operations(struct elf_module *module) { + Elf32_Sym *init_sym = module_find_symbol(MODULE_ELF_INIT_PTR, module); + Elf32_Sym *exit_sym = module_find_symbol(MODULE_ELF_EXIT_PTR, module); + + if (init_sym == NULL) { + DBG_PRINT("Cannot find initialization routine.\n"); + return -1; + } + if (exit_sym == NULL) { + DBG_PRINT("Cannot find exit routine.\n"); + return -1; + } + + module->init_func = (module_init_func*)module_get_absolute( + init_sym->st_value, module); + + module->exit_func = (module_exit_func*)module_get_absolute( + exit_sym->st_value, module); + + return 0; +} + // Loads the module into the system int module_load(struct elf_module *module) { int res; @@ -806,16 +828,22 @@ int module_load(struct elf_module *module) { // Check the symbols for duplicates / missing definitions CHECKED(res, check_symbols(module), error); + // Obtain constructors and destructors + CHECKED(res, extract_operations(module), error); + // Add the module at the beginning of the module list list_add(&module->list, &modules); // Perform the relocations resolve_symbols(module); + + // The file image is no longer needed image_unload(module); - DBG_PRINT("MODULE %s LOADED SUCCESSFULLY\n", module->name); + DBG_PRINT("MODULE %s LOADED SUCCESSFULLY (&init@0x%08X, &exit@0x%08X)\n", + module->name, module->init_func, module->exit_func); return 0; diff --git a/com32/elflink/elf_module.h b/com32/elflink/elf_module.h index cdc2254f..5e6a3719 100644 --- a/com32/elflink/elf_module.h +++ b/com32/elflink/elf_module.h @@ -15,6 +15,9 @@ #define MODULE_ELF_TYPE ET_DYN #define MODULE_ELF_MACHINE EM_386 +#define MODULE_ELF_INIT_PTR "__module_init_ptr" +#define MODULE_ELF_EXIT_PTR "__module_exit_ptr" + typedef int (*module_init_func)(void); typedef void (*module_exit_func)(void); @@ -29,8 +32,8 @@ struct elf_module { struct list_head dependants; // Head of module dependants list struct list_head list; // The list entry in the module list - module_init_func init_func; // The initialization entry point - module_exit_func exit_func; // The module finalization code + module_init_func *init_func; // The initialization entry point + module_exit_func *exit_func; // The module finalization code void *module_addr; // The module location in the memory diff --git a/com32/elflink/test_com32.c b/com32/elflink/test_com32.c index 90643937..b9f20bd2 100644 --- a/com32/elflink/test_com32.c +++ b/com32/elflink/test_com32.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "elf_module.h" @@ -10,7 +11,6 @@ #define ELF_DIRECTORY "/dyn/" static struct elf_module *mod_root; -static struct elf_module *mod_klibc; int modules_com32_setup() { int res; @@ -39,26 +39,60 @@ int modules_com32_setup() { return 0; } +int modules_com32_load(char *name) { + char full_name[MODULE_NAME_SIZE]; + int res; + + strcpy(full_name, ELF_DIRECTORY); + strcat(full_name, name); + + struct elf_module *module = module_alloc(full_name); + + res = module_load(module); + + if (res != 0) + return res; + + if (*(module->init_func) != NULL) { + res = (*(module->init_func))(); + printf("Initialization function returned: %d\n", res); + } else { + printf("No initialization function present.\n"); + } + + return res; +} + +void print_usage() { + printf("Usage: test_com32 module ...\n"); + printf("Where:\n"); + printf("\tmodule\tThe name of an ELF module to load, eg. hello.dyn\n"); + printf("\n"); +} + void modules_com32_finalize() { modules_term(); } int main(int argc, char **argv) { - int res; + int res, i; // Open a standard r/w console openconsole(&dev_stdcon_r, &dev_stdcon_w); + argc--; + argv++; + + if (argc == 0) { + print_usage(); + return 1; + } + // Initializing the module subsystem res = modules_com32_setup(); - // Load klibc - mod_klibc = module_alloc(ELF_DIRECTORY KLIBC_NAME); - module_load(mod_klibc); - - if (res != 0) { - printf("ERROR: Could not fully initialize the module!\n"); - return res; + for (i = 0; i < argc; i++) { + modules_com32_load(argv[i]); } modules_com32_finalize(); -- cgit