aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Bucur <stefanb@zytor.com>2008-07-28 21:33:14 -0700
committerStefan Bucur <stefan@stefan-ubumac.(none)>2009-03-15 10:10:50 +0200
commit7d735c335492a84ca4219a886754ba1cde2f415a (patch)
tree9a40a2a4ab9ef602770b32311acc99dd0f0ba48f
parentaf4b1f6b2b5b19f5e622d51917fc334dd784c0d8 (diff)
downloadsyslinux-elf-7d735c335492a84ca4219a886754ba1cde2f415a.tar.gz
syslinux-elf-7d735c335492a84ca4219a886754ba1cde2f415a.tar.xz
syslinux-elf-7d735c335492a84ca4219a886754ba1cde2f415a.zip
Implemented the initialization system of an ELF module.
-rw-r--r--com32/elflink/elf_module.c30
-rw-r--r--com32/elflink/elf_module.h7
-rw-r--r--com32/elflink/test_com32.c52
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 <stdio.h>
#include <stdlib.h>
#include <console.h>
+#include <string.h>
#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();