diff -ru src.orig/include/linux/moduleparam.h src/include/linux/moduleparam.h --- src.orig/include/linux/moduleparam.h +++ src/include/linux/moduleparam.h @@ -85,6 +85,11 @@ unsigned num, int (*unknown)(char *param, char *val)); + +struct module; + +extern int parse_args_reloc(char ** args, struct module * me, int * core_size, int * init_size); + /* All the helper functions */ /* The macros to do compile-time type checking stolen from Jakub Jelinek, who IIRC came up with this idea for the 2.4 module init code. */ diff -ru src.orig/kernel/module.c src/kernel/module.c --- src.orig/kernel/module.c +++ src/kernel/module.c @@ -1429,6 +1429,8 @@ } #endif /* CONFIG_KALLSYMS */ + + /* Allocate and load the module: note that size of section 0 is always zero, and we rely on this for optional sections. */ static struct module *load_module(void __user *umod, @@ -1446,7 +1448,9 @@ long err = 0; void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ struct exception_table_entry *extable; - + int no_frob_arch_sections = 0; + int core_size=0, init_size=0; + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", umod, len, uargs); if (len < sizeof(*hdr)) @@ -1579,8 +1583,25 @@ mod->state = MODULE_STATE_COMING; - /* Allow arches to frob section contents and sizes. */ - err = module_frob_arch_sections(hdr, sechdrs, secstrings, mod); + if(strncmp("elf_plt_info=",args, strlen("elf_plt_info="))==0){ + if(parse_args_reloc(&args, mod, &core_size, &init_size)) { + /* Allow passing hard coded relocation sizes. */ + sechdrs[mod->arch.core_plt_section].sh_size = core_size; + sechdrs[mod->arch.init_plt_section].sh_size = init_size; + no_frob_arch_sections = 1; + } + } + + if(!no_frob_arch_sections) + { + /* Allow arches to frob section contents and sizes. */ + err = module_frob_arch_sections(hdr, sechdrs, secstrings, mod); + printk("init_module: consider \"insmod %s elf_plt_info=%d,%d,%d,%d %s\"\n", mod->name, + mod->arch.core_plt_section, mod->arch.init_plt_section, + sechdrs[mod->arch.core_plt_section].sh_size, sechdrs[mod->arch.init_plt_section].sh_size, args); + } + + if (err < 0) goto free_mod; diff -ru src.orig/kernel/params.c src/kernel/params.c --- src.orig/kernel/params.c +++ src/kernel/params.c @@ -164,6 +164,17 @@ return 0; } + +int parse_args_reloc(char ** args, struct module *me, int* core_size, int* init_size){ + char *param, *val; + int ret=0; + *args = next_arg(*args, ¶m, &val);//args pointing to next of elf_plt_info=x,y.z,v + ret = sscanf(val, "%d,%d,%d,%d", + &me->arch.core_plt_section, &me->arch.init_plt_section, core_size, init_size); + if(ret!=4) return 0; /* fail */ + return 1; /* success */ +} + /* Lazy bastard, eh? */ #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ int param_set_##name(const char *val, struct kernel_param *kp) \