diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2020-07-27 21:58:45 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-07-27 21:58:45 +0200 |
commit | 154bc2aa3cb51104bdf213463da4fef9866c5a7b (patch) | |
tree | 8bb9449a8ad35a3c72a0d3de481a2c1c3c01d257 /common | |
parent | 8b0bf1ee077715ceb0535fbda799038ea62baef8 (diff) | |
parent | c55d8cbfc9447f32cb0d880e23c42d4ad185fae5 (diff) | |
download | barebox-154bc2aa3cb51104bdf213463da4fef9866c5a7b.tar.gz barebox-154bc2aa3cb51104bdf213463da4fef9866c5a7b.tar.xz |
Merge branch 'for-next/module'
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 7 | ||||
-rw-r--r-- | common/module.c | 68 |
2 files changed, 52 insertions, 23 deletions
diff --git a/common/Kconfig b/common/Kconfig index 642ff15d32..658437f01c 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -332,6 +332,13 @@ config MODULES way to compile modules and the list of exported symbols to actually make use of modules is short to nonexistent +config HAVE_MOD_ARCH_SPECIFIC + bool + help + The arch uses struct mod_arch_specific to store data. Many arches + just need a simple module loader without arch specific data - those + should not enable this. + config KALLSYMS depends on HAS_KALLSYMS bool "kallsyms" diff --git a/common/module.c b/common/module.c index 829c120007..a79bc734bb 100644 --- a/common/module.c +++ b/common/module.c @@ -176,6 +176,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 +219,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 +227,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 +279,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 +324,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 +335,6 @@ struct module * load_module(void *mod_image, unsigned long len) cleanup: if (ptr) free(ptr); - if (module) - free(module); return NULL; } |