source: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/exec.c @ e16e8f2

Last change on this file since e16e8f2 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * exec.c
3 *
4 *  Created on: Aug 14, 2008
5 *      Author: Stefan Bucur <stefanb@zytor.com>
6 */
7
8#include <sys/module.h>
9#include <sys/exec.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <stdarg.h>
14#include <setjmp.h>
15#include <setjmp.h>
16#include <alloca.h>
17#include <dprintf.h>
18
19#define DBG_PRINT(fmt, args...) dprintf("[EXEC] " fmt, ##args)
20
21struct elf_module *__syslinux_current = NULL;
22
23int get_module_type(struct elf_module *module)
24{
25        if(module->main_func) return EXEC_MODULE;
26        return LIB_MODULE;
27}
28
29jmp_buf __process_exit_jmp;
30
31#if 0
32int spawnv(const char *name, const char **argv)
33{
34        int res, ret_val = 0;
35        const char **arg;
36        int argc;
37        char **argp, **args;
38        struct elf_module *previous;
39        malloc_tag_t prev_mem_tag;
40
41        struct elf_module *module = module_alloc(name);
42
43        if (module == NULL)
44                return -1;
45
46        res = module_load(module);
47        if (res != 0) {
48                module_unload(module);
49                return res;
50        }
51
52        if (module->main_func == NULL) {
53                // We can't execute without a main function
54                module_unload(module);
55                return -1;
56        }
57        /*if (module->main_func != NULL) {
58                const char **last_arg = argv;
59                void *old_tag;
60                while (*last_arg != NULL)
61                        last_arg++;
62
63                // Setup the memory allocation context
64                old_tag = __mem_get_tag_global();
65                __mem_set_tag_global(module);
66
67                // Execute the program
68                ret_val = (*(module->main_func))(last_arg - argv, argv);
69
70                // Clean up the allocation context
71                __free_tagged(module);
72                // Restore the allocation context
73                __mem_set_tag_global(old_tag);
74        } else {
75                // We can't execute without a main function
76                module_unload(module);
77                return -1;
78        }*/
79        // Set up the process context
80        previous = __syslinux_current;
81        prev_mem_tag = __mem_get_tag_global();
82
83        // Setup the new process context
84        __syslinux_current = module;
85        __mem_set_tag_global((malloc_tag_t)module);
86
87        // Generate a new process copy of argv (on the stack)
88        argc = 0;
89        for (arg = argv; *arg; arg++)
90                argc++;
91
92        args = alloca((argc+1) * sizeof(char *));
93
94        for (arg = argv, argp = args; *arg; arg++, argp++) {
95                size_t l = strlen(*arg)+1;
96                *argp = alloca(l);
97                memcpy(*argp, *arg, l);
98        }
99
100        *args = NULL;
101
102        // Execute the program
103        ret_val = setjmp(module->u.x.process_exit);
104
105        if (ret_val)
106                ret_val--;              /* Valid range is 0-255 */
107        else if (!module->main_func)
108                ret_val = -1;
109        else
110                exit((module->main_func)(argc, args)); /* Actually run! */
111
112        // Clean up the allocation context
113        __free_tagged(module);
114        // Restore the allocation context
115        __mem_set_tag_global(prev_mem_tag);
116        // Restore the process context
117        __syslinux_current = previous;
118
119        res = module_unload(module);
120
121        if (res != 0) {
122                return res;
123        }
124
125        return ((unsigned int)ret_val & 0xFF);
126}
127
128int spawnl(const char *name, const char *arg, ...)
129{
130        /*
131         * NOTE: We assume the standard ABI specification for the i386
132         * architecture. This code may not work if used in other
133         * circumstances, including non-variadic functions, different
134         * architectures and calling conventions.
135         */
136        return spawnv(name, &arg);
137}
138#endif
139
140/*
141 * Load a module and runs its start function.
142 *
143 * For library modules the start function is module->init_func and for
144 * executable modules its module->main_func.
145 *
146 * "name" is the name of the module to load.
147 *
148 * "argv" and "argc" are only passed to module->main_func, for library
149 * modules these arguments can be NULL and 0, respectively.
150 *
151 * "argv" is an array of arguments to pass to module->main_func.
152 * argv[0] must be a pointer to "name" and argv[argc] must be NULL.
153 *
154 * "argc" is the number of arguments in "argv".
155 */
156int spawn_load(const char *name, int argc, char **argv)
157{
158        int res, ret_val = 0;
159        struct elf_module *previous;
160        //malloc_tag_t prev_mem_tag;
161        struct elf_module *module = module_alloc(name);
162        struct elf_module *cur_module;
163        int type;
164
165        dprintf("enter: name = %s", name);
166
167        if (module == NULL)
168                return -1;
169
170        if (get_module_type(module) == EXEC_MODULE) {
171                if (!argc || !argv || strcmp(argv[0], name)) {
172                        dprintf("invalid args for %s\n", name);
173                        res = -1;
174                        goto out;
175                }
176        }
177
178        cur_module = module_current();
179        if (!strcmp(cur_module->name, module->name)) {
180                dprintf("We is running this module %s already!", module->name);
181
182                module_unload(cur_module);
183        }
184
185        res = module_load(module);
186        if (res != 0) {
187                dprintf("failed to load module %s\n", module->name);
188                goto out;
189        }
190
191        type = get_module_type(module);
192
193        dprintf("type = %d, prev = %s, cur = %s",
194                type, cur_module->name, module->name);
195
196        if(type==EXEC_MODULE)
197        {
198                previous = __syslinux_current;
199                //prev_mem_tag = __mem_get_tag_global();
200
201                // Setup the new process context
202                __syslinux_current = module;
203                //__mem_set_tag_global((malloc_tag_t)module);
204
205                // Execute the program
206                ret_val = setjmp(module->u.x.process_exit);
207
208                if (ret_val)
209                        ret_val--;              /* Valid range is 0-255 */
210                else if (!module->main_func)
211                        ret_val = -1;
212                else
213                        exit((module->main_func)(argc, argv)); /* Actually run! */
214
215                // Clean up the allocation context
216                //__free_tagged(module);
217                // Restore the allocation context
218                //__mem_set_tag_global(prev_mem_tag);
219                // Restore the process context
220                __syslinux_current = previous;
221
222                res = module_unload(module);
223
224                if (res != 0)
225                        goto out;
226        }
227
228out:
229        if (res)
230                _module_unload(module);
231        return res;
232}
233
234void exec_term(void)
235{
236        modules_term();
237}
Note: See TracBrowser for help on using the repository browser.