From e7047887b040da7035f11d0fe48d76bd67381c9c Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Thu, 11 Dec 2003 01:42:13 +0000 Subject: Update modutils with 2.6 module support --- modutils/insmod.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 111 insertions(+), 16 deletions(-) (limited to 'modutils/insmod.c') diff --git a/modutils/insmod.c b/modutils/insmod.c index e2ca64169..979c41f78 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c @@ -80,8 +80,24 @@ #include #include "busybox.h" -#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE -# undef CONFIG_FEATURE_OLD_MODULE_INTERFACE +#if !defined(CONFIG_FEATURE_2_4_MODULES) && \ + !defined(CONFIG_FEATURE_2_2_MODULES) && \ + !defined(CONFIG_FEATURE_2_6_MODULES) +#define CONFIG_FEATURE_2_4_MODULES +#endif + +#if !defined(CONFIG_FEATURE_2_4_MODULES) && !defined(CONFIG_FEATURE_2_2_MODULES) +#define insmod_ng_main insmod_main +#endif + +#if defined(CONFIG_FEATURE_2_4_MODULES) || defined(CONFIG_FEATURE_2_2_MODULES) + +#if defined(CONFIG_FEATURE_2_6_MODULES) +extern int insmod_ng_main( int argc, char **argv); +#endif + +#ifdef CONFIG_FEATURE_2_4_MODULES +# undef CONFIG_FEATURE_2_2_MODULES # define new_sys_init_module init_module #else # define old_sys_init_module init_module @@ -266,7 +282,7 @@ #ifndef MODUTILS_MODULE_H static const int MODUTILS_MODULE_H = 1; -#ident "$Id: insmod.c,v 1.106 2003/12/04 15:02:57 mjn3 Exp $" +#ident "$Id: insmod.c,v 1.107 2003/12/11 01:42:13 andersen Exp $" /* This file contains the structures used by the 2.0 and 2.1 kernels. We do not use the kernel headers directly because we do not wish @@ -399,7 +415,7 @@ struct new_module unsigned tgt_long persist_end; unsigned tgt_long can_unload; unsigned tgt_long runsize; -#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_4_MODULES const char *kallsyms_start; /* All symbols for kernel debugging */ const char *kallsyms_end; const char *archdata_start; /* arch specific data for module */ @@ -487,7 +503,7 @@ int delete_module(const char *); #ifndef MODUTILS_OBJ_H static const int MODUTILS_OBJ_H = 1; -#ident "$Id: insmod.c,v 1.106 2003/12/04 15:02:57 mjn3 Exp $" +#ident "$Id: insmod.c,v 1.107 2003/12/11 01:42:13 andersen Exp $" /* The relocatable object is manipulated using elfin types. */ @@ -630,7 +646,7 @@ static void *obj_extend_section (struct obj_section *sec, unsigned long more); static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, const char *string); -#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_4_MODULES static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, struct obj_symbol *sym); #endif @@ -665,7 +681,7 @@ static void arch_create_got (struct obj_file *f); static int obj_gpl_license(struct obj_file *f, const char **license); -#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_4_MODULES static int arch_init_module (struct obj_file *f, struct new_module *); #endif @@ -1626,7 +1642,7 @@ static void arch_create_got(struct obj_file *f) #endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */ } -#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_4_MODULES static int arch_init_module(struct obj_file *f, struct new_module *mod) { return 1; @@ -2224,7 +2240,7 @@ old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ -#ifdef CONFIG_FEATURE_OLD_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_2_MODULES /* Fetch all the symbols and divvy them up as appropriate for the modules. */ @@ -2434,7 +2450,7 @@ old_init_module(const char *m_name, struct obj_file *f, #define old_create_mod_use_count(x) TRUE #define old_init_module(x, y, z) TRUE -#endif /* CONFIG_FEATURE_OLD_MODULE_INTERFACE */ +#endif /* CONFIG_FEATURE_2_2_MODULES */ @@ -2720,7 +2736,7 @@ new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ -#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_4_MODULES /* Fetch the loaded modules, and all currently exported symbols. */ @@ -3041,7 +3057,7 @@ new_init_module(const char *m_name, struct obj_file *f, #define new_create_module_ksymtab(x) #define query_module(v, w, x, y, z) -1 -#endif /* CONFIG_FEATURE_NEW_MODULE_INTERFACE */ +#endif /* CONFIG_FEATURE_2_4_MODULES */ /*======================================================================*/ @@ -3075,7 +3091,7 @@ obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, return 1; } -#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_4_MODULES static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, struct obj_symbol *sym) @@ -4161,7 +4177,7 @@ extern int insmod_main( int argc, char **argv) printf("Using %s\n", m_filename); -#ifdef CONFIG_FEATURE_REALLY_NEW_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_6_MODULES if (create_module(NULL, 0) < 0 && errno == ENOSYS) { optind--; argv[optind] = m_filename; @@ -4214,7 +4230,7 @@ extern int insmod_main( int argc, char **argv) k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL); if (k_new_syscalls) { -#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_4_MODULES if (!new_get_kernel_symbols()) goto out; k_crcs = new_is_kernel_checksummed(); @@ -4223,7 +4239,7 @@ extern int insmod_main( int argc, char **argv) goto out; #endif } else { -#ifdef CONFIG_FEATURE_OLD_MODULE_INTERFACE +#ifdef CONFIG_FEATURE_2_2_MODULES if (!old_get_kernel_symbols(m_name)) goto out; k_crcs = old_is_kernel_checksummed(); @@ -4345,3 +4361,82 @@ out: #endif return(exit_status); } + + +#endif + + +#ifdef CONFIG_FEATURE_2_6_MODULES + +#include +#include +#include + +/* We use error numbers in a loose translation... */ +static const char *moderror(int err) +{ + switch (err) { + case ENOEXEC: + return "Invalid module format"; + case ENOENT: + return "Unknown symbol in module"; + case ESRCH: + return "Module has wrong symbol version"; + case EINVAL: + return "Invalid parameters"; + default: + return strerror(err); + } +} + +extern int insmod_ng_main( int argc, char **argv) +{ + int i; + int fd; + long int ret; + struct stat st; + unsigned long len; + void *map; + char *filename, *options = bb_xstrdup(""); + + filename = argv[1]; + if (!filename) { + bb_show_usage(); + return -1; + } + + /* Rest is options */ + for (i = 2; i < argc; i++) { + options = xrealloc(options, strlen(options) + 2 + strlen(argv[i]) + 2); + /* Spaces handled by "" pairs, but no way of escaping quotes */ + if (strchr(argv[i], ' ')) { + strcat(options, "\""); + strcat(options, argv[i]); + strcat(options, "\""); + } else { + strcat(options, argv[i]); + } + strcat(options, " "); + } + + if ((fd = open(filename, O_RDONLY, 0)) < 0) { + bb_perror_msg_and_die("cannot open module `%s'", filename); + } + + fstat(fd, &st); + len = st.st_size; + map = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { + bb_perror_msg_and_die("cannot mmap `%s'", filename); + } + + ret = syscall(__NR_init_module, map, len, options); + if (ret != 0) { + bb_perror_msg_and_die("cannot insert `%s': %s (%li)", + filename, moderror(errno), ret); + } + + return 0; +} + +#endif -- cgit v1.2.3