diff options
Diffstat (limited to 'common/module.c')
-rw-r--r-- | common/module.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/common/module.c b/common/module.c index 829c120007..b669ec09c9 100644 --- a/common/module.c +++ b/common/module.c @@ -1,17 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2002 Richard Henderson * Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -176,6 +166,42 @@ static void layout_sections( struct module *mod, debug("core_size: %ld\n", mod->core_size); } +int __weak module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) +{ + return 0; +} + +static void register_module_cmds(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex) +{ + Elf32_Sym *sym; + unsigned int numsyms; + unsigned int i; + struct command * const *cmd_start = NULL; + struct command * const *cmd_end = NULL; + struct command * const *cmd; + + numsyms = sechdrs[symindex].sh_size / sizeof(Elf32_Sym); + sym = (void *)sechdrs[symindex].sh_addr; + + for (i = 0; i < numsyms; i++) { + if (strcmp(strtab + sym[i].st_name, MODULE_SYMBOL_PREFIX "__barebox_cmd_start") == 0) + cmd_start = (struct command * const *)sym[i].st_value; + + if (strcmp(strtab + sym[i].st_name, MODULE_SYMBOL_PREFIX "__barebox_cmd_end") == 0) + cmd_end = (struct command * const *)sym[i].st_value; + } + + if (cmd_start && cmd_end) { + debug("found __barebox_cmd_start at 0x%08x\n", (uint32_t)cmd_start); + for (cmd = cmd_start; cmd != cmd_end; cmd++) { + register_command(*cmd); + } + } +} + LIST_HEAD(module_list); struct module * load_module(void *mod_image, unsigned long len) @@ -183,8 +209,6 @@ struct module * load_module(void *mod_image, unsigned long len) struct module *module = NULL; Elf32_Ehdr *ehdr; /* Elf header structure pointer */ Elf32_Shdr *sechdrs; /* Section header structure pointer */ - Elf32_Sym *sym; - unsigned int numsyms; char *strtab = 0; /* String table pointer */ int i; /* Loop counter */ unsigned int strindex = 0; @@ -193,7 +217,6 @@ struct module * load_module(void *mod_image, unsigned long len) char *secstrings; void *ptr = NULL; int err; - int cmdindex; if (len < sizeof(*ehdr)) return NULL; @@ -246,6 +269,12 @@ struct module * load_module(void *mod_image, unsigned long len) goto cleanup; } + /* Allow arches to frob section contents and sizes. */ + err = module_frob_arch_sections(ehdr, sechdrs, + secstrings, module); + if (err < 0) + goto cleanup; + /* Determine total sizes, and put offsets in sh_entsize. For now this is done generically; there doesn't appear to be any special cases for the architectures. */ @@ -285,25 +314,10 @@ struct module * load_module(void *mod_image, unsigned long len) apply_relocate_add(sechdrs, strtab, symindex, i, module); } - numsyms = sechdrs[symindex].sh_size / sizeof(Elf32_Sym); - sym = (void *)sechdrs[symindex].sh_addr; - - cmdindex = find_sec(ehdr, sechdrs, secstrings, ".barebox_cmd"); - if (cmdindex) { - struct command *cmd =(struct command *)sechdrs[cmdindex].sh_addr; - for (i = 0; i < sechdrs[cmdindex].sh_size / sizeof(struct command); i++) { - register_command(cmd); - cmd++; - } - } - - for (i = 0; i < numsyms; i++) { - if (!strcmp(strtab + sym[i].st_name, MODULE_SYMBOL_PREFIX "init_module")) { - printf("found init_module() at 0x%08x\n", sym[i].st_value); - module->init = (void *)sym[i].st_value; - } - } + register_module_cmds(sechdrs, strtab, symindex); + /* Module has been moved */ + module = (void *)sechdrs[modindex].sh_addr; list_add_tail(&module->list, &module_list); return module; @@ -311,8 +325,6 @@ struct module * load_module(void *mod_image, unsigned long len) cleanup: if (ptr) free(ptr); - if (module) - free(module); return NULL; } |