diff options
Diffstat (limited to 'com32/lib/sys/module')
| -rw-r--r-- | com32/lib/sys/module/common.c | 8 | ||||
| -rw-r--r-- | com32/lib/sys/module/elf_module.c | 19 | ||||
| -rw-r--r-- | com32/lib/sys/module/exec.c | 24 | ||||
| -rw-r--r-- | com32/lib/sys/module/i386/elf_module.c | 21 | ||||
| -rw-r--r-- | com32/lib/sys/module/x86_64/elf_module.c | 21 |
5 files changed, 71 insertions, 22 deletions
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c index 50b8a9f6..5b0d9ee8 100644 --- a/com32/lib/sys/module/common.c +++ b/com32/lib/sys/module/common.c @@ -71,15 +71,19 @@ FILE *findpath(char *name) p = PATH; again: i = 0; - while (*p && *p != ':' && i < FILENAME_MAX) { + while (*p && *p != ':' && i < FILENAME_MAX - 1) { path[i++] = *p++; } if (*p == ':') p++; + /* Ensure we have a '/' separator */ + if (path[i] != '/' && i < FILENAME_MAX - 1) + path[i++] = '/'; + n = name; - while (*n && i < FILENAME_MAX) + while (*n && i < FILENAME_MAX - 1) path[i++] = *n++; path[i] = '\0'; diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c index 4ee296c4..0d27c92b 100644 --- a/com32/lib/sys/module/elf_module.c +++ b/com32/lib/sys/module/elf_module.c @@ -98,13 +98,6 @@ static int prepare_dynlinking(struct elf_module *module) { dyn_entry++; } - // Now compute the number of symbols in the symbol table - if (module->ghash_table != NULL) { - module->symtable_size = module->ghash_table[1]; - } else { - module->symtable_size = module->hash_table[1]; - } - return 0; } @@ -191,6 +184,7 @@ int module_load(struct elf_module *module) { Elf_Sym *main_sym; Elf_Ehdr elf_hdr; module_ctor_t *ctor; + struct elf_module *head = NULL; // Do not allow duplicate modules if (module_find(module->name) != NULL) { @@ -224,6 +218,8 @@ int module_load(struct elf_module *module) { CHECKED(res, prepare_dynlinking(module), error); //printf("check... 4\n"); + head = list_entry((&modules_head)->next, typeof(*head), list); + /* Find modules we need to load as dependencies */ if (module->str_table) { int i; @@ -249,7 +245,11 @@ int module_load(struct elf_module *module) { p = dep; argv[0] = p; - spawn_load(p, 1, argv); + res = spawn_load(p, 1, argv); + if (res < 0) { + printf("Failed to load %s\n", p); + goto error; + } } } @@ -294,6 +294,9 @@ int module_load(struct elf_module *module) { return 0; error: + if (head) + unload_modules_since(head->name); + // Remove the module from the module list (if applicable) list_del_init(&module->list); diff --git a/com32/lib/sys/module/exec.c b/com32/lib/sys/module/exec.c index 29d0a2fd..559bafc7 100644 --- a/com32/lib/sys/module/exec.c +++ b/com32/lib/sys/module/exec.c @@ -194,8 +194,10 @@ int spawn_load(const char *name, int argc, char **argv) return -1; if (get_module_type(module) == EXEC_MODULE) { - if (!argc || !argv || strcmp(argv[0], name)) - return -1; + if (!argc || !argv || strcmp(argv[0], name)) { + res = -1; + goto out; + } } if (!strcmp(cur_module->name, module->name)) { @@ -218,10 +220,8 @@ int spawn_load(const char *name, int argc, char **argv) } res = module_load(module); - if (res != 0) { - _module_unload(module); - return res; - } + if (res != 0) + goto out; type = get_module_type(module); prev_module = cur_module; @@ -259,14 +259,14 @@ int spawn_load(const char *name, int argc, char **argv) cur_module = prev_module; res = module_unload(module); - if (res != 0) { - return res; - } - - return ((unsigned int)ret_val & 0xFF); + if (res != 0) + goto out; } - return 0; +out: + if (res) + _module_unload(module); + return res; } void exec_term(void) diff --git a/com32/lib/sys/module/i386/elf_module.c b/com32/lib/sys/module/i386/elf_module.c index d0eb1a8e..a3792554 100644 --- a/com32/lib/sys/module/i386/elf_module.c +++ b/com32/lib/sys/module/i386/elf_module.c @@ -30,7 +30,9 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) { int i; int res = 0; char *pht = NULL; + char *sht = NULL; Elf32_Phdr *cr_pht; + Elf32_Shdr *cr_sht; Elf32_Addr min_addr = 0x00000000; // Min. ELF vaddr Elf32_Addr max_addr = 0x00000000; // Max. ELF vaddr @@ -142,6 +144,25 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) { } } + // Get to the SHT + image_seek(elf_hdr->e_shoff, module); + + // Load the SHT + sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize); + image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module); + + // Setup the symtable size + for (i = 0; i < elf_hdr->e_shnum; i++) { + cr_sht = (Elf32_Shdr*)(sht + i * elf_hdr->e_shentsize); + + if (cr_sht->sh_type == SHT_DYNSYM) { + module->symtable_size = cr_sht->sh_size; + break; + } + } + + free(sht); + // Setup dynamic segment location module->dyn_table = module_get_absolute(dyn_addr, module); diff --git a/com32/lib/sys/module/x86_64/elf_module.c b/com32/lib/sys/module/x86_64/elf_module.c index 9300f989..64404a17 100644 --- a/com32/lib/sys/module/x86_64/elf_module.c +++ b/com32/lib/sys/module/x86_64/elf_module.c @@ -30,7 +30,9 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) { int i; int res = 0; char *pht = NULL; + char *sht = NULL; Elf64_Phdr *cr_pht; + Elf64_Shdr *cr_sht; Elf64_Addr min_addr = 0x0000000000000000; // Min. ELF vaddr Elf64_Addr max_addr = 0x0000000000000000; // Max. ELF vaddr @@ -142,6 +144,25 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) { } } + // Get to the SHT + image_seek(elf_hdr->e_shoff, module); + + // Load the SHT + sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize); + image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module); + + // Setup the symtable size + for (i = 0; i < elf_hdr->e_shnum; i++) { + cr_sht = (Elf64_Shdr*)(sht + i * elf_hdr->e_shentsize); + + if (cr_sht->sh_type == SHT_DYNSYM) { + module->symtable_size = cr_sht->sh_size; + break; + } + } + + free(sht); + // Setup dynamic segment location module->dyn_table = module_get_absolute(dyn_addr, module); |
