Name: Make module_frob_arch_sections more powerful Author: Rusty Russell Status: Experimental D: IA64 wants to resize SHF_ALLOC sections in module_frob_arch_sections. D: Allow them to realloc it by changing interface. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/alpha/kernel/module.c .22818-linux-2.5.66.updated/arch/alpha/kernel/module.c --- .22818-linux-2.5.66/arch/alpha/kernel/module.c 2003-02-07 19:21:51.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/alpha/kernel/module.c 2003-03-25 15:24:41.000000000 +1100 @@ -86,7 +86,7 @@ process_reloc_for_got(Elf64_Rela *rela, rela->r_info |= g->got_offset << 8; } -int +Elf64_Ehdr * module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs, char *secstrings, struct module *me) { @@ -111,11 +111,11 @@ module_frob_arch_sections(Elf64_Ehdr *hd if (!symtab) { printk(KERN_ERR "module %s: no symbol table\n", me->name); - return -ENOEXEC; + return ERR_PTR(-ENOEXEC); } if (!got) { printk(KERN_ERR "module %s: no got section\n", me->name); - return -ENOEXEC; + return ERR_PTR(-ENOEXEC); } nsyms = symtab->sh_size / sizeof(Elf64_Sym); @@ -147,7 +147,7 @@ module_frob_arch_sections(Elf64_Ehdr *hd } kfree(chains); - return 0; + return hdr; } int diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/arm/kernel/module.c .22818-linux-2.5.66.updated/arch/arm/kernel/module.c --- .22818-linux-2.5.66/arch/arm/kernel/module.c 2003-02-07 19:21:51.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/arm/kernel/module.c 2003-03-25 15:24:58.000000000 +1100 @@ -67,12 +67,12 @@ void module_free(struct module *module, vfree(region); } -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) +Elf_Ehdr *module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) { - return 0; + return hdr; } int diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/i386/kernel/module.c .22818-linux-2.5.66.updated/arch/i386/kernel/module.c --- .22818-linux-2.5.66/arch/i386/kernel/module.c 2003-02-07 19:21:51.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/i386/kernel/module.c 2003-03-25 15:25:16.000000000 +1100 @@ -45,12 +45,12 @@ void module_free(struct module *mod, voi } /* We don't need anything special. */ -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) +Elf_Ehdr *module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) { - return 0; + return hdr; } int apply_relocate(Elf32_Shdr *sechdrs, diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/parisc/kernel/module.c .22818-linux-2.5.66.updated/arch/parisc/kernel/module.c --- .22818-linux-2.5.66/arch/parisc/kernel/module.c 2003-03-25 12:16:58.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/parisc/kernel/module.c 2003-03-25 15:25:52.000000000 +1100 @@ -206,10 +206,10 @@ void module_free(struct module *mod, voi } #define CONST -int module_frob_arch_sections(CONST Elf_Ehdr *hdr, - CONST Elf_Shdr *sechdrs, - CONST char *secstrings, - struct module *me) +CONST Elf_Ehdr *module_frob_arch_sections(CONST Elf_Ehdr *hdr, + CONST Elf_Shdr *sechdrs, + CONST char *secstrings, + struct module *me) { unsigned long gots = 0, fdescs = 0, stubs = 0; unsigned int i; @@ -244,7 +244,7 @@ int module_frob_arch_sections(CONST Elf_ me->arch.stub_offset = me->core_size; me->core_size += stubs * sizeof(struct stub_entry); - return 0; + return hdr; } static Elf_Addr get_got(struct module *me, unsigned long value, long addend) diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/ppc/kernel/module.c .22818-linux-2.5.66.updated/arch/ppc/kernel/module.c --- .22818-linux-2.5.66/arch/ppc/kernel/module.c 2003-02-07 19:21:52.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/ppc/kernel/module.c 2003-03-25 15:26:16.000000000 +1100 @@ -101,10 +101,10 @@ static unsigned long get_plt_size(const return ret; } -int module_frob_arch_sections(Elf32_Ehdr *hdr, - Elf32_Shdr *sechdrs, - char *secstrings, - struct module *me) +Elf32_Ehdr *module_frob_arch_sections(Elf32_Ehdr *hdr, + Elf32_Shdr *sechdrs, + char *secstrings, + struct module *me) { unsigned int i; @@ -117,7 +117,7 @@ int module_frob_arch_sections(Elf32_Ehdr } if (!me->arch.core_plt_section || !me->arch.init_plt_section) { printk("Module doesn't contain .plt or .init.plt sections.\n"); - return -ENOEXEC; + return ERR_PTR(-ENOEXEC); } /* Override their sizes */ @@ -125,7 +125,7 @@ int module_frob_arch_sections(Elf32_Ehdr = get_plt_size(hdr, sechdrs, secstrings, 0); sechdrs[me->arch.init_plt_section].sh_size = get_plt_size(hdr, sechdrs, secstrings, 1); - return 0; + return hdr; } int apply_relocate(Elf32_Shdr *sechdrs, diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/ppc64/kernel/module.c .22818-linux-2.5.66.updated/arch/ppc64/kernel/module.c --- .22818-linux-2.5.66/arch/ppc64/kernel/module.c 2003-02-11 14:25:58.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/ppc64/kernel/module.c 2003-03-25 15:26:39.000000000 +1100 @@ -150,10 +150,10 @@ static void dedotify(Elf64_Sym *syms, un } } -int module_frob_arch_sections(Elf64_Ehdr *hdr, - Elf64_Shdr *sechdrs, - char *secstrings, - struct module *me) +Elf64_Ehdr *module_frob_arch_sections(Elf64_Ehdr *hdr, + Elf64_Shdr *sechdrs, + char *secstrings, + struct module *me) { unsigned int i; @@ -177,12 +177,12 @@ int module_frob_arch_sections(Elf64_Ehdr } if (!me->arch.stubs_section || !me->arch.toc_section) { printk("%s: doesn't contain .toc or .stubs.\n", me->name); - return -ENOEXEC; + return ERR_PTR(-ENOEXEC); } /* Override the stubs size */ sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs); - return 0; + return hdr; } int apply_relocate(Elf64_Shdr *sechdrs, diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/s390/kernel/module.c .22818-linux-2.5.66.updated/arch/s390/kernel/module.c --- .22818-linux-2.5.66/arch/s390/kernel/module.c 2003-02-25 10:10:51.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/s390/kernel/module.c 2003-03-25 15:27:43.000000000 +1100 @@ -99,7 +99,7 @@ check_rela(Elf32_Rela *rela, struct modu * Account for GOT and PLT relocations. We can't add sections for * got and plt but we can increase the core module size. */ -int +Elf32_EHdr * module_frob_arch_sections(Elf32_Ehdr *hdr, Elf32_Shdr *sechdrs, char *secstrings, struct module *me) { @@ -119,7 +119,7 @@ module_frob_arch_sections(Elf32_Ehdr *hd } if (!symtab) { printk(KERN_ERR "module %s: no symbol table\n", me->name); - return -ENOEXEC; + return ERR_PTR(-ENOEXEC); } /* Allocate one syminfo structure per symbol. */ @@ -128,7 +128,7 @@ module_frob_arch_sections(Elf32_Ehdr *hd sizeof(struct mod_arch_syminfo), GFP_KERNEL); if (!me->arch.syminfo) - return -ENOMEM; + return ERR_PTR(-ENOMEM); symbols = (void *) hdr + symtab->sh_offset; strings = (void *) hdr + sechdrs[symtab->sh_link].sh_offset; for (i = 0; i < me->arch.nsyms; i++) { @@ -161,7 +161,7 @@ module_frob_arch_sections(Elf32_Ehdr *hd me->core_size += me->arch.got_size; me->arch.plt_offset = me->core_size; me->core_size += me->arch.plt_size; - return 0; + return hdr; } int diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/s390x/kernel/module.c .22818-linux-2.5.66.updated/arch/s390x/kernel/module.c --- .22818-linux-2.5.66/arch/s390x/kernel/module.c 2003-02-25 10:10:51.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/s390x/kernel/module.c 2003-03-25 15:30:49.000000000 +1100 @@ -103,7 +103,7 @@ check_rela(Elf64_Rela *rela, struct modu * Account for GOT and PLT relocations. We can't add sections for * got and plt but we can increase the core module size. */ -int +Elf64_Ehdr * module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs, char *secstrings, struct module *me) { @@ -123,7 +123,7 @@ module_frob_arch_sections(Elf64_Ehdr *hd } if (!symtab) { printk(KERN_ERR "module %s: no symbol table\n", me->name); - return -ENOEXEC; + return ERR_PTR(-ENOEXEC); } /* Allocate one syminfo structure per symbol. */ @@ -165,7 +165,7 @@ module_frob_arch_sections(Elf64_Ehdr *hd me->core_size += me->arch.got_size; me->arch.plt_offset = me->core_size; me->core_size += me->arch.plt_size; - return 0; + return hdr; } int diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/sparc/kernel/module.c .22818-linux-2.5.66.updated/arch/sparc/kernel/module.c --- .22818-linux-2.5.66/arch/sparc/kernel/module.c 2003-02-07 19:21:52.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/sparc/kernel/module.c 2003-03-25 15:31:04.000000000 +1100 @@ -37,12 +37,12 @@ void module_free(struct module *mod, voi } /* We don't need anything special. */ -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) +Elf_Ehdr *module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) { - return 0; + return hdr; } int apply_relocate(Elf32_Shdr *sechdrs, diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/sparc64/kernel/module.c .22818-linux-2.5.66.updated/arch/sparc64/kernel/module.c --- .22818-linux-2.5.66/arch/sparc64/kernel/module.c 2003-02-07 19:21:52.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/sparc64/kernel/module.c 2003-03-25 15:31:19.000000000 +1100 @@ -144,12 +144,12 @@ void module_free(struct module *mod, voi } /* We don't need anything special. */ -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) +Elf_Ehdr *module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) { - return 0; + return hdr; } int apply_relocate(Elf64_Shdr *sechdrs, diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/v850/kernel/module.c .22818-linux-2.5.66.updated/arch/v850/kernel/module.c --- .22818-linux-2.5.66/arch/v850/kernel/module.c 2003-02-07 19:21:52.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/v850/kernel/module.c 2003-03-25 15:31:42.000000000 +1100 @@ -100,10 +100,10 @@ static unsigned long get_plt_size(const return ret; } -int module_frob_arch_sections(Elf32_Ehdr *hdr, - Elf32_Shdr *sechdrs, - char *secstrings, - struct module *me) +Elf32_Ehdr *module_frob_arch_sections(Elf32_Ehdr *hdr, + Elf32_Shdr *sechdrs, + char *secstrings, + struct module *me) { unsigned int i; @@ -116,7 +116,7 @@ int module_frob_arch_sections(Elf32_Ehdr } if (!me->arch.core_plt_section || !me->arch.init_plt_section) { printk("Module doesn't contain .plt or .plt.init sections.\n"); - return -ENOEXEC; + return ERR_PTR(-ENOEXEC)x; } /* Override their sizes */ @@ -124,7 +124,7 @@ int module_frob_arch_sections(Elf32_Ehdr = get_plt_size(hdr, sechdrs, secstrings, 0); sechdrs[me->arch.init_plt_section].sh_size = get_plt_size(hdr, sechdrs, secstrings, 1); - return 0; + return hdr; } int apply_relocate (Elf32_Shdr *sechdrs, const char *strtab, diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/arch/x86_64/kernel/module.c .22818-linux-2.5.66.updated/arch/x86_64/kernel/module.c --- .22818-linux-2.5.66/arch/x86_64/kernel/module.c 2003-02-17 11:37:44.000000000 +1100 +++ .22818-linux-2.5.66.updated/arch/x86_64/kernel/module.c 2003-03-25 15:32:00.000000000 +1100 @@ -137,12 +137,12 @@ fail: } /* We don't need anything special. */ -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) +Elf_Ehdr *module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) { - return 0; + return hdr; } int apply_relocate_add(Elf64_Shdr *sechdrs, diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/include/linux/moduleloader.h .22818-linux-2.5.66.updated/include/linux/moduleloader.h --- .22818-linux-2.5.66/include/linux/moduleloader.h 2003-02-07 19:21:54.000000000 +1100 +++ .22818-linux-2.5.66.updated/include/linux/moduleloader.h 2003-03-25 15:19:52.000000000 +1100 @@ -7,11 +7,11 @@ /* These must be implemented by the specific architecture */ -/* Adjust arch-specific sections. Return 0 on success. */ -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod); +/* Adjust arch-specific sections. Return hdr or -err.. */ +Elf_Ehdr *module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod); /* Allocator used for allocating struct module, core sections and init sections. Returns NULL on failure. */ diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .22818-linux-2.5.66/kernel/module.c .22818-linux-2.5.66.updated/kernel/module.c --- .22818-linux-2.5.66/kernel/module.c 2003-03-18 05:01:52.000000000 +1100 +++ .22818-linux-2.5.66.updated/kernel/module.c 2003-03-25 15:21:03.000000000 +1100 @@ -1044,7 +1044,7 @@ static struct module *load_module(void * unsigned long len, const char *uargs) { - Elf_Ehdr *hdr; + Elf_Ehdr *hdr, *newhdr; Elf_Shdr *sechdrs; char *secstrings, *args; unsigned int i, symindex, exportindex, strindex, setupindex, exindex, @@ -1172,9 +1172,15 @@ static struct module *load_module(void * mod->state = MODULE_STATE_COMING; /* Allow arches to frob section contents and sizes. */ - err = module_frob_arch_sections(hdr, sechdrs, secstrings, mod); - if (err < 0) + newhdr = module_frob_arch_sections(hdr, sechdrs, secstrings, mod); + if (IS_ERR(newhdr)) { + err = PTR_ERR(newhdr); goto free_mod; + } + hdr = newhdr; + sechdrs = (void *)hdr + hdr->e_shoff; + secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + mod = (void *)sechdrs[modindex].sh_addr; /* Determine total sizes, and put offsets in sh_entsize. For now this is done generically; there doesn't appear to be any