From: Matt Fleming Date: Fri, 8 Apr 2011 12:21:51 +0000 (+0100) Subject: elflink: Move more code from core/ into ldlinux X-Git-Tag: syslinux-5.00-pre1~65 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=43d7cbaa55806ecb33b0cc5aa56e97b0f8027c45;p=platform%2Fupstream%2Fsyslinux.git elflink: Move more code from core/ into ldlinux ldlinux now contains all the code necessary to load and execute modules, none is contained in the core. This change also allows us to change the spawn_load() prototype and to push the job of processing arguments to executable functions (e.g. the contents of char *argv[] as passed to a module's main function) into ldlinux/execute.c instead of doing it in spawn_load(). Moving it into ldlinux/ makes sense because the only core user of spawn_load() is load_env32() and we don't require any sort of argument processing in that path. Signed-off-by: Matt Fleming --- diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile index 6fbe1b1..09aa4af 100644 --- a/com32/elflink/ldlinux/Makefile +++ b/com32/elflink/ldlinux/Makefile @@ -19,7 +19,7 @@ CFLAGS += -I../modules -I$(topdir)/core/elflink -I$(topdir)/core/include all: ldlinux.c32 ldlinux.c32 : ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o \ - adv.o ipappend.o + adv.o ipappend.o execute.o kernel.o $(LD) $(LDFLAGS) -o $@ $^ tidy dist: diff --git a/core/elflink/execute.c b/com32/elflink/ldlinux/execute.c similarity index 73% rename from core/elflink/execute.c rename to com32/elflink/ldlinux/execute.c index 7e70323..f67d707 100644 --- a/core/elflink/execute.c +++ b/com32/elflink/ldlinux/execute.c @@ -43,13 +43,10 @@ static inline int my_isspace(char c) void execute(const char *cmdline, enum kernel_type type) { - com32sys_t ireg; const char *p, *const *pp; - char *q; const char *kernel, *args; - - /* work around for spawn_load parameter */ - char *spawn_load_param[2] = { NULL, NULL}; + com32sys_t ireg; + char *q; memset(&ireg, 0, sizeof ireg); @@ -87,18 +84,70 @@ void execute(const char *cmdline, enum kernel_type type) if (type == KT_COM32) { /* new entry for elf format c32 */ - spawn_load_param[0] = args; + char **argv; + int i, argc; + + q = args; + for (argc = 0; *q; q++) { + argc++; + + /* Find the end of this arg */ + while(*q && !my_isspace(*q)) + q++; + + /* + * Now skip all whitespace between arguments. + */ + while (*q && my_isspace(*q)) + q++; + } + + /* + * Generate a copy of argv on the stack as this is + * traditionally where process arguments go. + * + * argv[0] must be the command name, so bump argc to + * include argv[0]. + */ + argc += 1; + argv = alloca(argc * sizeof(char *)); + argv[0] = kernel; + + for (q = args, i = 1; i < argc - 1; i++) { + char *start; + int len = 0; + + start = q; + + /* Find the end of this arg */ + while(*q && !my_isspace(*q)) { + q++; + len++; + } + + argv[i] = malloc(len + 1); + strncpy(argv[i], start, len); + argv[i][len] = '\0'; + + /* + * Now skip all whitespace between arguments. + */ + while (*q && my_isspace(*q)) + q++; + } + + argv[argc] = NULL; module_load_dependencies(kernel, "modules.dep"); - spawn_load(kernel, spawn_load_param); + spawn_load(kernel, argc, argv); } else if (type <= KT_KERNEL) { /* Need add one item for kernel load, as we don't use * the assembly runkernel.inc any more */ new_linux_kernel(kernel, cmdline); } else if (type == KT_CONFIG) { /* kernel contains the config file name */ - spawn_load_param[0] = args; + char *spawn_load_param[2] = { args, NULL }; module_load_dependencies("ui.c32", "modules.dep"); - spawn_load(kernel, spawn_load_param); + spawn_load(kernel, 1, spawn_load_param); } else { /* process the image need int 22 support */ if (type == KT_LOCALBOOT) { diff --git a/core/elflink/kernel.c b/com32/elflink/ldlinux/kernel.c similarity index 100% rename from core/elflink/kernel.c rename to com32/elflink/ldlinux/kernel.c diff --git a/com32/include/sys/exec.h b/com32/include/sys/exec.h index 31b62be..656f8e2 100644 --- a/com32/include/sys/exec.h +++ b/com32/include/sys/exec.h @@ -33,6 +33,7 @@ * spawn_load - Load a library module or executes an executable one * @name the name of the library/executable to use, including the extension * (e.g. 'sort.c32') + * @argc: the number of string arguments in @argv * @argv: a NULL-terminated vector of string arguments, starting with * the program name. * @@ -40,7 +41,7 @@ * kind of module it is ( executable or library ), after which is performs the * appropriate action, either spawning or simply loading the module into memory. */ -extern int spawn_load(const char *name,const char **argv); +extern int spawn_load(const char *name, int argc, char **argv); extern int module_load_dependencies(const char*name,const char*dep_file); diff --git a/com32/lib/sys/module/exec.c b/com32/lib/sys/module/exec.c index 78df72e..1ed3263 100644 --- a/com32/lib/sys/module/exec.c +++ b/com32/lib/sys/module/exec.c @@ -220,12 +220,25 @@ int spawnl(const char *name, const char *arg, ...) struct elf_module *cur_module; -int spawn_load(const char *name,const char **argv) +/* + * Load a module and runs its start function. + * + * For library modules the start function is module->init_func and for + * executable modules its module->main_func. + * + * "name" is the name of the module to load. + * + * "argv" and "argc" are only passed to module->main_func, for library + * modules these arguments can be NULL and 0, respectively. + * + * "argv" is an array of arguments to pass to module->main_func. + * argv[0] must be a pointer to "name" and argv[argc] must be NULL. + * + * "argc" is the number of arguments in "argv". + */ +int spawn_load(const char *name, int argc, char **argv) { int res, ret_val = 0; - const char **arg; - int argc; - char **argp, **args; struct elf_module *previous; //malloc_tag_t prev_mem_tag; struct elf_module *module = module_alloc(name); @@ -238,6 +251,11 @@ int spawn_load(const char *name,const char **argv) if (module == NULL) return -1; + if (get_module_type(module) == EXEC_MODULE) { + if (!argc || !argv || strcmp(argv[0], name)) + return -1; + } + if (!strcmp(cur_module->name, module->name)) { dprintf("We is running this module %s already!", module->name); @@ -295,21 +313,6 @@ int spawn_load(const char *name,const char **argv) __syslinux_current = module; //__mem_set_tag_global((malloc_tag_t)module); - // Generate a new process copy of argv (on the stack) - argc = 0; - for (arg = argv; *arg; arg++) - argc++; - - args = alloca((argc+1) * sizeof(char *)); - - for (arg = argv, argp = args; *arg; arg++, argp++) { - size_t l = strlen(*arg)+1; - *argp = alloca(l); - memcpy(*argp, *arg, l); - } - - *args = NULL; - // Execute the program ret_val = setjmp(module->u.x.process_exit); @@ -318,7 +321,7 @@ int spawn_load(const char *name,const char **argv) else if (!module->main_func) ret_val = -1; else - exit((module->main_func)(argc, args)); /* Actually run! */ + exit((module->main_func)(argc, argv)); /* Actually run! */ // Clean up the allocation context @@ -468,13 +471,13 @@ int module_load_dependencies(const char *name,const char *dep_file) i++; /* skip a space */ if (strlen(temp_name)) { - char *argv[2] = { NULL, NULL }; + char *argv[2] = { temp_name, NULL }; int ret; ret = module_load_dependencies(temp_name, MODULES_DEP); if (!ret) { - if (spawn_load(temp_name, argv) < 0) + if (spawn_load(temp_name, 1, argv) < 0) continue; } } diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c index 501f267..8a71634 100644 --- a/core/elflink/load_env32.c +++ b/core/elflink/load_env32.c @@ -18,6 +18,8 @@ #include "menu.h" #include "core-elf.h" +#define LDLINUX "ldlinux.c32" + typedef void (*constructor_t) (void); constructor_t __ctors_start[], __ctors_end[]; @@ -68,10 +70,13 @@ static void call_constr(void) /* note to self: do _*NOT*_ use static key word on this function */ void load_env32(com32sys_t * regs) { + char *argv[] = { LDLINUX, NULL }; + dprintf("Starting 32 bit elf module subsystem...\n"); call_constr(); init_module_subsystem(&core_module); - execute("ldlinux.c32", KT_COM32); + module_load_dependencies(LDLINUX, "modules.dep"); + spawn_load(LDLINUX, 1, argv); }