Modules 3/3: Sort sections
Subsystems (4)
PATCH 1/1 Modules 3/3: Sort sections
Linus, please apply.
RTH's final complaint (so far 8) was that we should sort the module
sections: archs which use GOT pointers (or equiv) might need those sections close by each other.
The code does this, and simplifies the arch interface: previously an arch could specify it wanted extra space, but not where that space would be. The new method (used only by PPC so far) is to allocate an empty section (in asm/module.h or by setting LDFLAGS_MODULE to use an arch specific linker script), and expand that to the desired size in "module_frob_arch_sections()".
x86 and PPC are tested, others are trivial.
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Name: Section Ordering Patch
Author: Richard Henderson
Status: Tested on 2.5.53
Depends: Module/nocommon.patch.gz Module/sh_addr.patch.gz
D: Some architectures require some sections to be adjacent, so they
D: can all be reached by a relative pointer (ie. GOT pointer). This
D: implements that reordering, and simplfies the module interface
D: for architectures as well.
arch/arm/kernel/module.c +5 -11
@@ -67,18 +67,12 @@ void module_free(struct module *module,vfree (region); } -long -module_core_size (const Elf32_Ehdr *hdr,const Elf32_Shdr *sechdrs, -const char *secstrings,struct module *module) -{ -return module->core_size; -} - -long -module_init_size (const Elf32_Ehdr *hdr,const Elf32_Shdr *sechdrs, -const char *secstrings,struct module *module) +int module_frob_arch_sections (const Elf_Ehdr *hdr, +const Elf_Shdr *sechdrs, +const char *secstrings, +struct module *mod) { -return module->init_size; +return 0 ; }int
arch/i386/kernel/module.c +5 -13
@@ -45,20 +45,12 @@ void module_free(struct module *mod, voi }/* We don't need anything special. */ -long module_core_size (const Elf32_Ehdr *hdr, -const Elf32_Shdr *sechdrs, -const char *secstrings, -struct module *module) -{ -return module->core_size; -} - -long module_init_size (const Elf32_Ehdr *hdr, -const Elf32_Shdr *sechdrs, -const char *secstrings, -struct module *module) +int module_frob_arch_sections (const Elf_Ehdr *hdr, +const Elf_Shdr *sechdrs, +const char *secstrings, +struct module *mod) { -return module->init_size; +return 0 ; } int apply_relocate(Elf32_Shdr *sechdrs,
arch/ppc/kernel/module.c +32 -21
80 lines not on this page · raw message
arch/s390/kernel/module.c +5 -16
@@ -51,26 +51,15 @@ void module_free(struct module *mod, voitable entries. */ } -/* s390/s390x needs additional memory for GOT/PLT sections. */ -long module_core_size (const Elf32_Ehdr *hdr, -const Elf32_Shdr *sechdrs, -const char *secstrings, -struct module *module) +int module_frob_arch_sections (const Elf_Ehdr *hdr, +const Elf_Shdr *sechdrs, +const char *secstrings, +struct module *mod) {// FIXME: add space needed for GOT/PLT -return module->core_size; -} - -long module_init_size (const Elf32_Ehdr *hdr, -const Elf32_Shdr *sechdrs, -const char *secstrings, -struct module *module) -{ -return module->init_size; +return 0 ; } - - int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex,
arch/s390x/kernel/module.c +5 -15
@@ -52,25 +52,15 @@ void module_free(struct module *mod, voi }/* s390/s390x needs additional memory for GOT/PLT sections. */ -long module_core_size (const Elf32_Ehdr *hdr, -const Elf32_Shdr *sechdrs, -const char *secstrings, -struct module *module) +int module_frob_arch_sections (const Elf_Ehdr *hdr, +const Elf_Shdr *sechdrs, +const char *secstrings, +struct module *mod) {// FIXME: add space needed for GOT/PLT -return module->core_size; -} - -long module_init_size (const Elf32_Ehdr *hdr, -const Elf32_Shdr *sechdrs, -const char *secstrings, -struct module *module) -{ -return module->init_size; +return 0 ; } - - int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex,
arch/sparc/kernel/module.c +5 -13
@@ -37,20 +37,12 @@ void module_free(struct module *mod, voi }/* We don't need anything special. */ -long module_core_size (const Elf32_Ehdr *hdr, -const Elf32_Shdr *sechdrs, -const char *secstrings, -struct module *module) -{ -return module->core_size; -} - -long module_init_size (const Elf32_Ehdr *hdr, -const Elf32_Shdr *sechdrs, -const char *secstrings, -struct module *module) +int module_frob_arch_sections (const Elf_Ehdr *hdr, +const Elf_Shdr *sechdrs, +const char *secstrings, +struct module *mod) { -return module->init_size; +return 0 ; } int apply_relocate(Elf32_Shdr *sechdrs,
arch/sparc64/kernel/module.c +5 -13
@@ -144,20 +144,12 @@ void module_free(struct module *mod, voi }/* We don't need anything special. */ -long module_core_size (const Elf64_Ehdr *hdr, -const Elf64_Shdr *sechdrs, -const char *secstrings, -struct module *module) -{ -return module->core_size; -} - -long module_init_size (const Elf64_Ehdr *hdr, -const Elf64_Shdr *sechdrs, -const char *secstrings, -struct module *module) +int module_frob_arch_sections (const Elf_Ehdr *hdr, +const Elf_Shdr *sechdrs, +const char *secstrings, +struct module *mod) { -return module->init_size; +return 0 ; } int apply_relocate(Elf64_Shdr *sechdrs,
arch/x86_64/kernel/module.c +5 -13
@@ -26,20 +26,12 @@ #define DEBUGP(fmt...)/* We don't need anything special. */ -long module_core_size (const Elf64_Ehdr *hdr, -const Elf64_Shdr *sechdrs, -const char *secstrings, -struct module *module) -{ -return module->core_size; -} - -long module_init_size (const Elf64_Ehdr *hdr, -const Elf64_Shdr *sechdrs, -const char *secstrings, -struct module *module) +int module_frob_arch_sections (const Elf_Ehdr *hdr, +const Elf_Shdr *sechdrs, +const char *secstrings, +struct module *mod) { -return module->init_size; +return 0 ; } int apply_relocate_add(Elf64_Shdr *sechdrs,
include/asm-ppc/module.h +7 -6
@@ -18,16 +18,17 @@ struct ppc_plt_entrystruct mod_arch_specific { -/* How much of the core is actually taken up with core (then -we know the rest is for the PLT */ -unsigned int core_plt_offset; - -/* Same for init */ -unsigned int init_plt_offset; +/* Indices of PLT sections within module. */ +unsigned int core_plt_section, init_plt_section; };#define Elf_Shdr Elf32_Shdr#define Elf_Sym Elf32_Sym#define Elf_Ehdr Elf32_Ehdr +/* Make empty sections for module_frob_arch_sections to expand. */ +#ifdef MODULE +asm(".section .plt,\"aws\",@nobits; .align 3; .previous" ); +asm(".section .plt.init,\"aws\",@nobits; .align 3; .previous" ); +#endif #endif /* _ASM_PPC_MODULE_H */
include/linux/moduleloader.h +5 -14
@@ -15,20 +15,11 @@ unsigned long find_symbol_internal(Elf_S/* These must be implemented by the specific architecture */ -/* Total size to allocate for the non-releasable code; return len or --error. mod->core_size is the current generic tally. */ -long module_core_size (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, -struct module *mod); - -/* Total size of (if any) sections to be freed after init. Return 0 -for none, len, or -error. mod->init_size is the current generic -tally. */ -long module_init_size (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, -struct module *mod); +/* Adjust arch-specific sections. Return 0 on success. */ +int module_frob_arch_sections (const Elf_Ehdr *hdr, +const Elf_Shdr *sechdrs, +const char *secstrings, +struct module *mod);/* Allocator used for allocating struct module, core sections and init sections. Returns NULL on failure. */
kernel/module.c +89 -97
249 lines not on this page · raw message
arch/ppc/kernel/module.c static unsigned long get_plt_size(const · line 111
Quoted 1 line · Rusty Russell
arch/ppc/kernel/module.c +1
-0+/* Find .plt and .pltinit sections */
Typo.
include/asm-ppc/module.h struct ppc_plt_entry · line 32
Quoted 4 lines
include/asm-ppc/module.h +4
-0+/* Make empty sections for module_frob_arch_sections to expand. */ +#ifdef MODULE +asm(".section .plt,\"aws\",@nobits; .align 3; .previous" ); +asm(".section .plt.init,\"aws\",@nobits; .align 3; .previous" );
Should use "ax", do make the plt sections executable, since the plt section contains code that branches. Additionally, this will place the .plt section next to .text, which improves icache usage, and minimizes the branch distance.
Incidentally, why do we do strstr(name, ".init") instead of strncmp(name, ".init", 5)? Is there any particular need for the .init to come at the end?
r~
From: Richard Henderson <[email protected]>
Date: Wed, 1 Jan 2003 20:54:04 -0800
Incidentally, why do we do strstr(name, ".init") instead of strncmp(name, ".init", 5)? Is there any particular need for the .init to come at the end?
I think this is to get .foo.init sections.
Quoted 5 lines · David S. Miller
Incidentally, why do we do
strstr(name, ".init")instead ofstrncmp(name, ".init", 5)? Is there any particular need for the .init to come at the end?I think this is to get .foo.init sections.
Obviously. Perhaps the question was worded badly. Instead read it as "Why don't we force this to be called .init.foo instead?"
r~
From: Richard Henderson <[email protected]>
Date: Wed, 1 Jan 2003 20:58:36 -0800
Quoted 1 line · David S. Miller
I think this is to get .foo.init sections.
Obviously. Perhaps the question was worded badly. Instead read it as "Why don't we force this to be called .init.foo instead?"
This new naming order was created recently, but I forget the reason. It used to be .init.foo
In message <[email protected]> you write:
Quoted 11 lines
From: Richard Henderson <[email protected]>
Date: Wed, 1 Jan 2003 20:58:36 -0800Quoted 1 line · David S. Miller
I think this is to get .foo.init sections.
Obviously. Perhaps the question was worded badly. Instead read it as "Why don't we force this to be called .init.foo instead?"
This new naming order was created recently, but I forget the reason. It used to be .init.foo
No, it used to be .foo.init, but -ffunction-sections calls its functions <funcname>.init, so it was changed to .init.foo.
Of course, the simpler prefix test should now be sufficient. Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Quoted 5 lines · David S. Miller
Obviously. Perhaps the question was worded badly. Instead read it as "Why don't we force this to be called .init.foo instead?"
This new naming order was created recently, but I forget the reason. It used to be .init.foo
Because of -ffunction-sections usage
Quoted 9 lines · Richard Henderson
Quoted 5 lines · David S. Miller
Incidentally, why do we do
strstr(name, ".init")instead ofstrncmp(name, ".init", 5)? Is there any particular need for the .init to come at the end?I think this is to get .foo.init sections.
Obviously. Perhaps the question was worded badly. Instead read it as "Why don't we force this to be called .init.foo instead?"
-ffunction-sections ?
Quoted 4 lines · Arjan van de Ven
Quoted 2 lines
Obviously. Perhaps the question was worded badly. Instead read it as "Why don't we force this to be called .init.foo instead?"
-ffunction-sections ?
You've lost me. What has this got to do with anything?
r~
In message <[email protected]> you write:
Quoted 5 lines · Rusty Russell
Review
Quoted 1 line
(quoted diff) +1
-0+ /* Find .plt and .pltinit sections */Typo.
Quoted 10 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+/* Make empty sections for module_frob_arch_sections to expand. */ +#ifdef MODULE +asm(".section .plt,\"aws\",@nobits; .align 3; .previous"); +asm(".section .plt.init,\"aws\",@nobits; .align 3; .previous");Should use "ax", do make the plt sections executable, since the plt section contains code that branches. Additionally, this will place the .plt section next to .text, which improves icache usage, and minimizes the branch distance.
OK, and I've renamed it to .init.plt, too.
Thanks!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
arch/ppc/kernel/module.c +3 -3
@@ -108,15 +108,15 @@ int module_frob_arch_sections(Elf32_Ehdr {unsigned int i; -/* Find .plt and .pltinit sections */ +/* Find .plt and .init.plt sections */ for (i =0 ; i < hdr->e_shnum; i++) { -if (strcmp (secstrings + sechdrs[i].sh_name,".plt.init" ) ==0 ) +if (strcmp (secstrings + sechdrs[i].sh_name,".init.plt" ) ==0 ) me->arch.init_plt_section = i;else if (strcmp (secstrings + sechdrs[i].sh_name,".plt" ) ==0 ) me->arch.core_plt_section = i; }if (!me->arch.core_plt_section || !me->arch.init_plt_section) { -printk ("Module doesn't contain .plt or .plt.init sections.\n" ); +printk ("Module doesn't contain .plt or .init.plt sections.\n" );return -ENOEXEC ; }
include/asm-ppc/module.h +2 -2
@@ -28,7 +28,7 @@ struct mod_arch_specific/* Make empty sections for module_frob_arch_sections to expand. */ #ifdef MODULE -asm(".section .plt,\"aws\",@nobits; .align 3; .previous" ); -asm(".section .plt.init,\"aws\",@nobits; .align 3; .previous" ); +asm(".section .plt,\"ax\",@nobits; .align 3; .previous" ); +asm(".section .init.plt,\"ax\",@nobits; .align 3; .previous" );#endif #endif /* _ASM_PPC_MODULE_H */
The declaration of `module_frob_arch_sections' in moduleloader.h (and the definitions in most of the module.c files) are inconsistent with the definition in the PPC's module.c -- in the latter the first two arguments are not declared `const', whereas everyplace else they are.
I copied the PPC version of module_frob_arch_sections for the v850, and couldn't compile without changing the type-signature to match. Making all args const to agree with the declaration results in these warnings:
arch/v850/kernel/module.c: In function `module_frob_arch_sections':
arch/v850/kernel/module.c:124: warning: assignment of read-only member sh_size'arch/v850/kernel/module.c:126: warning: assignment of read-only member sh_size'
Since the purpose of module_frob_arch_sections is to frob, perhaps it makes sense to have the frobable arguments be non-const (in this case only sechdrs needs it, I guess)... :-)
-Miles
Signature · 2 lines
"Whatever you do will be insignificant, but it is very important that you do it." Mahatma Ghandi
In message <[email protected]> you write:
Quoted 4 lines
The declaration of `module_frob_arch_sections' in
moduleloader.h(and the definitions in most of themodule.cfiles) are inconsistent with the definition in the PPC'smodule.c-- in the latter the first two arguments are not declared `const', whereas everyplace else they are.0
"constfrobbing considered harmful"
Linus, please apply.
Rusty.
PS. secstrings can be modded to: if an arch can't handle discarding
init, it simply renames the .init sections.
arch/arm/kernel/module.c +3 -3
@@ -67,9 +67,9 @@ void module_free(struct module *module,vfree (region); } -int module_frob_arch_sections (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, +int module_frob_arch_sections (Elf_Ehdr *hdr, +Elf_Shdr *sechdrs, +char *secstrings,struct module *mod) {return 0 ;
arch/i386/kernel/module.c +3 -3
@@ -45,9 +45,9 @@ void module_free(struct module *mod, voi }/* We don't need anything special. */ -int module_frob_arch_sections (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, +int module_frob_arch_sections (Elf_Ehdr *hdr, +Elf_Shdr *sechdrs, +char *secstrings,struct module *mod) {return 0 ;
arch/ppc/kernel/module.c +1 -1
@@ -103,7 +103,7 @@ static unsigned long get_plt_size(constint module_frob_arch_sections (Elf32_Ehdr *hdr,Elf32_Shdr *sechdrs, -const char *secstrings, +char *secstrings,struct module *me) {unsigned int i;
arch/s390/kernel/module.c +3 -3
@@ -51,9 +51,9 @@ void module_free(struct module *mod, voitable entries. */ } -int module_frob_arch_sections (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, +int module_frob_arch_sections (Elf_Ehdr *hdr, +Elf_Shdr *sechdrs, +char *secstrings,struct module *mod) {// FIXME: add space needed for GOT/PLT
arch/s390x/kernel/module.c +3 -3
@@ -52,9 +52,9 @@ void module_free(struct module *mod, voi }/* s390/s390x needs additional memory for GOT/PLT sections. */ -int module_frob_arch_sections (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, +int module_frob_arch_sections (Elf_Ehdr *hdr, +Elf_Shdr *sechdrs, +char *secstrings,struct module *mod) {// FIXME: add space needed for GOT/PLT
arch/sparc/kernel/module.c +3 -3
@@ -37,9 +37,9 @@ void module_free(struct module *mod, voi }/* We don't need anything special. */ -int module_frob_arch_sections (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, +int module_frob_arch_sections (Elf_Ehdr *hdr, +Elf_Shdr *sechdrs, +char *secstrings,struct module *mod) {return 0 ;
arch/sparc64/kernel/module.c +3 -3
@@ -144,9 +144,9 @@ void module_free(struct module *mod, voi }/* We don't need anything special. */ -int module_frob_arch_sections (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, +int module_frob_arch_sections (Elf_Ehdr *hdr, +Elf_Shdr *sechdrs, +char *secstrings,struct module *mod) {return 0 ;
arch/x86_64/kernel/module.c +3 -3
@@ -26,9 +26,9 @@ #define DEBUGP(fmt...)/* We don't need anything special. */ -int module_frob_arch_sections (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, +int module_frob_arch_sections (Elf_Ehdr *hdr, +Elf_Shdr *sechdrs, +char *secstrings,struct module *mod) {return 0 ;
include/linux/moduleloader.h +3 -3
@@ -16,9 +16,9 @@ unsigned long find_symbol_internal(Elf_S/* These must be implemented by the specific architecture */ /* Adjust arch-specific sections. Return 0 on success. */ -int module_frob_arch_sections (const Elf_Ehdr *hdr, -const Elf_Shdr *sechdrs, -const char *secstrings, +int 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
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.