Skip to contentSkip to conversation

Embed __this_module in module itself.

PATCH In review Rusty Russell 4 participants 8 messages Dec 27, 2002 – Jan 10, 2003 Module support

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Embed __this_module in module itself.

[ Oops, forgot to CC lkml on this to Linus, and people might want to see ]

Linus, please apply.

Rather than have the module loader the module structure and
resolve the symbols __this_module to it, make __this_module a real structure inside the module, using the linkonce trick we used for module names.

This saves us an allocation (saving a page per module on
archs which need the module structure close by), and means we don't have to fill in a few module fields.

Works fine here. Requires the previous "Overzealous permenant mark removed" patch, otherwise you'll get some rejects.

Thanks,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

Name: Embedded __this_module
Author: Rusty Russell
Status: Tested in 2.5.52
Depends: Module/module-noexit.patch.gz

D: This makes __this_module a real symbol for modules, rather than
D: allocating at load time. This makes things a little simpler, and
D: also saves about a page on architectures which have their own
D: module allocator (eg. Sparc64).

include/linux/init.h +2 -3
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .1411-2.5.53-embedded-thismodule.pre/include/linux/init.h .1411-2.5.53-embedded-thismodule/include/linux/init.h
@@ -147,14 +147,13 @@ struct obs_kernel_param {
 #define module_init(initfn)					\
 	static inline initcall_t __inittest(void)		\
 	{ return initfn; }					\
-	int __initfn(void) __attribute__((alias(#initfn)));
+	int init_module(void) __attribute__((alias(#initfn)));
 
 /* This is only required if you want to be unloadable. */
 #define module_exit(exitfn)					\
 	static inline exitcall_t __exittest(void)		\
 	{ return exitfn; }					\
-	void __exitfn(void) __attribute__((alias(#exitfn)));
-
+	void cleanup_module(void) __attribute__((alias(#exitfn)));
 
 #define __setup(str,func) /* nothing */
 #endif
include/linux/module.h +18 -16
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .1411-2.5.53-embedded-thismodule.pre/include/linux/module.h .1411-2.5.53-embedded-thismodule/include/linux/module.h
@@ -40,12 +40,11 @@ struct kernel_symbol
 	char name[MODULE_NAME_LEN];
 };
 
-#ifdef MODULE
+/* These are either module local, or the kernel's dummy ones. */
+extern int init_module(void);
+extern void cleanup_module(void);
 
-#ifdef KBUILD_MODNAME
-static const char __module_name[MODULE_NAME_LEN] __attribute__((section(".gnu.linkonce.modname"))) = \
-  __stringify(KBUILD_MODNAME);
-#endif
+#ifdef MODULE
 
 /* For replacement modutils, use an alias not a pointer. */
 #define MODULE_GENERIC_TABLE(gtype,name)			\
@@ -56,9 +55,6 @@ static const struct gtype##_id * __modul
 extern const struct gtype##_id __mod_##gtype##_table		\
   __attribute__ ((unused, alias(__stringify(name))))
 
-/* This is magically filled in by the linker, but THIS_MODULE must be
-   a constant so it works in initializers. */
-extern struct module __this_module;
 #define THIS_MODULE (&__this_module)
 
 #else  /* !MODULE */
@@ -176,7 +172,7 @@ struct module
 
 	/* The command line arguments (may be mangled).  People like
 	   keeping pointers to this stuff */
-	char args[0];
+	char *args;
 };
 
 /* FIXME: It'd be nice to isolate modules during init, too, so they
@@ -289,6 +285,19 @@ static inline const char *module_address
 }
 #endif /* CONFIG_MODULES */
 
+#if defined(MODULE) && defined(KBUILD_MODNAME)
+/* We make the linker do some of the work. */
+struct module __this_module
+__attribute__((section(".gnu.linkonce.this_module"))) = {
+	.name = __stringify(KBUILD_MODNAME),
+	.symbols = { .owner = &__this_module },
+	.init = init_module,
+#ifdef CONFIG_MODULE_UNLOAD
+	.exit = cleanup_module,
+#endif
+};
+#endif /* MODULE && KBUILD_MODNAME */
+
 /* For archs to search exception tables */
 extern struct list_head extables;
 extern spinlock_t modlist_lock;
@@ -342,13 +351,6 @@ extern int module_dummy_usage;
   && __mod_between((p),(n),(m)->module_init,(m)->init_size))	\
  || __mod_between((p),(n),(m)->module_core,(m)->core_size))
 
-/* Old-style "I'll just call it init_module and it'll be run at
-   insert".  Use module_init(myroutine) instead. */
-#ifdef MODULE
-#define init_module(voidarg) __initfn(void)
-#define cleanup_module(voidarg) __exitfn(void)
-#endif
-
 /*
  * The exception and symbol tables, and the lock
  * to protect them.
kernel/module.c +46 -57

237 lines not on this page · raw message

--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

#1 lore raw

When I try to build modules using 2.5.54, the resulting .ko files lack the .gnu.linkonce.* sections, which causes the kernel module loader to fail on them -- those sections _are_ present in the .o files, but the linker apparently removes them!

Any clues why it's doing this (I tried GNU ld versions 2.13.2.1 and 2.11.92.0.12.3, and both act the same)? Is there something arch-specific I need to do?

[The .ko file is produce by just doing `ld -r', e.g.:

v850e-elf-ld -r -o drivers/block/loop.ko drivers/block/loop.o

For instance, for the loop device, here's the output of `readelf -S loop.o':

---------------- begin ----------------
There are 25 section headers, starting at offset 0x1d99c:

Section Headers:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 00186c 00  AX  0   0  2
  [ 2] .rela.text        RELA            00000000 01ea40 0005c4 0c     23   1  4
  [ 3] .data             PROGBITS        00000000 0018a0 0000a4 00  WA  0   0  4
  [ 4] .rela.data        RELA            00000000 01f004 000078 0c     23   3  4
  [ 5] .bss              NOBITS          00000000 001944 000008 00  WA  0   0  4
  [ 6] .call_table_data  PROGBITS        00000000 001944 000000 00  WA  0   0  1
  [ 7] .call_table_text  PROGBITS        00000000 001944 000000 00  AX  0   0  1
  [ 8] .stab             PROGBITS        00000000 001944 008538 0c     10   0  4
  [ 9] .rela.stab        RELA            00000000 01f07c 000b10 0c     23   8  4
  [10] .stabstr          STRTAB          00000000 009e7c 013448 00      0   0  1
  [11] .plt              NOBITS          00000000 01d2c8 000000 00  AX  0   0  8
  [12] .init.plt         NOBITS          00000000 01d2c8 000000 00  AX  0   0  8
  [13] .gnu.linkonce.thi PROGBITS        00000000 01d2c8 0000b0 00  WA  0   0  4
  [14] .rela.gnu.linkonc RELA            00000000 01fb8c 000024 0c     23   d  4
  [15] .rodata           PROGBITS        00000000 01d378 0001bf 00   A  0   0  1
  [16] __obsparm         PROGBITS        00000000 01d538 000080 00  WA  0   0  4
  [17] __ksymtab         PROGBITS        00000000 01d5b8 000080 00   A  0   0  4
  [18] .rela__ksymtab    RELA            00000000 01fbb0 000018 0c     23  11  4
  [19] .init.text        PROGBITS        00000000 01d638 000220 00  AX  0   0  2
  [20] .rela.init.text   RELA            00000000 01fbc8 000138 0c     23  13  4
  [21] .comment          PROGBITS        00000000 01d858 00002d 00      0   0  1
  [22] .shstrtab         STRTAB          00000000 01d885 000115 00      0   0  1
  [23] .symtab           SYMTAB          00000000 01dd84 000710 10     24  34  4
  [24] .strtab           STRTAB          00000000 01e494 0005ab 00      0   0  1

Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
---------------- end ----------------

and here's the output of `readelf -S loop.ko'

---------------- begin ----------------
There are 23 section headers, starting at offset 0x1d938:

Section Headers:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .plt              NOBITS          00100000 000038 000000 00  AX  0   0  8
  [ 2] .text             PROGBITS        00100000 000038 00191c 00 WAX  0   0  4
  [ 3] .rela.text        RELA            00000000 01dcd0 0005e8 0c     21   2  4
  [ 4] .call_table_data  PROGBITS        0010191c 001954 000000 00  WA  0   0  1
  [ 5] .call_table_text  PROGBITS        0010191c 001954 000000 00  AX  0   0  1
  [ 6] .rodata           PROGBITS        0010191c 001954 0001bf 00   A  0   0  1
  [ 7] .data             PROGBITS        00101adc 001b14 0000a4 00  WA  0   0  4
  [ 8] .rela.data        RELA            00000000 01e2b8 000078 0c     21   7  4
  [ 9] .bss              NOBITS          00101b80 001bb8 000008 00  WA  0   0  4
  [10] .stab             PROGBITS        00000000 001bb8 008538 0c     12   0  4
  [11] .rela.stab        RELA            00000000 01e330 000b10 0c     21   a  4
  [12] .stabstr          STRTAB          00000000 00a0f0 013448 00      0   0  1
  [13] .comment          PROGBITS        00000000 01d538 00002d 00      0   0  1
  [14] .init.plt         NOBITS          00000030 01d568 000000 00  AX  0   0  8
  [15] __obsparm         PROGBITS        00000030 01d568 000080 00  WA  0   0  4
  [16] __ksymtab         PROGBITS        000000b0 01d5e8 000080 00   A  0   0  4
  [17] .rela__ksymtab    RELA            00000000 01ee40 000018 0c     21  10  4
  [18] .init.text        PROGBITS        00000130 01d668 000220 00  AX  0   0  2
  [19] .rela.init.text   RELA            00000000 01ee58 000138 0c     21  12  4
  [20] .shstrtab         STRTAB          00000000 01d888 0000b0 00      0   0  1
  [21] .symtab           SYMTAB          00000000 01ef90 000780 10     22  3b  4
  [22] .strtab           STRTAB          00000000 01f710 0005ab 00      0   0  1

Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
---------------- end ----------------

Thanks,

-Miles

Signature · 2 lines
Somebody has to do something, and it's just incredibly pathetic that it
has to be us.  -- Jerry Garcia
#2 lore raw
Quoted 4 lines · Miles Bader

When I try to build modules using 2.5.54, the resulting .ko files lack the .gnu.linkonce.* sections, which causes the kernel module loader to fail on them -- those sections _are_ present in the .o files, but the linker apparently removes them!

Ok, I found out why this is happening -- the v850 default linker scripts, for whatever reason, merge any section called `.gnu.linker.t*' with .text.

I can prevent this by adding the option `--unique=.gnu.linkonce.this_module' to the linker flags (specifically, to LDFLAGS_MODULE in the top-level Makefile). I suppose another way to do it would be to rename the section something that doesn't match `.gnu.linker.t*'.

What's the right way to handle this?

[from perusing the ld srcs, a few other archs seem to have the same feature,' though the only that I think has linux support is cris']

Thanks,

-Miles

Signature · 2 lines
The secret to creativity is knowing how to hide your sources.
  --Albert Einstein
#3 lore raw
Quoted 9 lines · Miles Bader
Quoted 4 lines · Miles Bader

When I try to build modules using 2.5.54, the resulting .ko files lack the .gnu.linkonce.* sections, which causes the kernel module loader to fail on them -- those sections _are_ present in the .o files, but the linker apparently removes them!

Ok, I found out why this is happening -- the v850 default linker scripts, for whatever reason, merge any section called `.gnu.linker.t*' with .text.

ld per default uses a default linker-scripts as you note. Could another solution be to provide a fixed linker script, used for all invocations of ld?

LDFLAGS += -T arch/v850/v850.lds

Not knowing much about v850, I wonder why you do not need to set the -m option. Most other architectures do this.

Sam

#4 lore raw
Quoted 2 lines · Sam Ravnborg

Not knowing much about v850, I wonder why you do not need to set the -m option. Most other architectures do this.

???

A far as I can see, no architecture does anything different than the default.

[Why on earth would -m be needed, anyway?]

-Miles

Signature · 1 line
Fast, small, soon; pick any 2.
#5 lore raw
Quoted 8 lines · Miles Bader
Quoted 2 lines · Sam Ravnborg

Not knowing much about v850, I wonder why you do not need to set the -m option. Most other architectures do this.

???

A far as I can see, no architecture does anything different than the default.

A little grepping gave the following result:

i386/Makefile:LDFLAGS := -m elf_i386
m68k/Makefile:LDFLAGS := -m m68kelf

mips/Makefile:LDFLAGS           := -G 0
ppc64/Makefile:LDFLAGS          := -m elf64ppc
s390/Makefile:LDFLAGS           := -m elf_s390
s390x/Makefile:LDFLAGS          := -m elf64_s390
sh/Makefile:LDFLAGS             := -EL
sh/Makefile:LDFLAGS             := -EB
sparc/Makefile:LDFLAGS          := -m elf32_sparc

sparc64/Makefile:LDFLAGS := -m elf64_sparc
x86_64/Makefile:LDFLAGS := -m elf_x86_64

Little less than half of the architectures defines their own LDFLAGS. Most of them set an emulation, most probarly inherited from i386.

Quoted 2 lines

[Why on earth would -m be needed, anyway?]

I do not know, but as can be seen above several architectures use it.

I have seen your proposed patch for gnu.linkonce.
I do prefer to have it in arch/v850/Makefile because this is a workaround for an architecture specific bug in ld.
Why not provide your own link script?

Sam

#6 lore raw
Quoted 33 lines · Sam Ravnborg
Quoted 8 lines · Miles Bader
Quoted 2 lines · Sam Ravnborg

Not knowing much about v850, I wonder why you do not need to set the -m option. Most other architectures do this.

???

A far as I can see, no architecture does anything different than the default.

A little grepping gave the following result:

i386/Makefile:LDFLAGS := -m elf_i386
m68k/Makefile:LDFLAGS := -m m68kelf

mips/Makefile:LDFLAGS           := -G 0
ppc64/Makefile:LDFLAGS          := -m elf64ppc
s390/Makefile:LDFLAGS           := -m elf_s390
s390x/Makefile:LDFLAGS          := -m elf64_s390
sh/Makefile:LDFLAGS             := -EL
sh/Makefile:LDFLAGS             := -EB
sparc/Makefile:LDFLAGS          := -m elf32_sparc

sparc64/Makefile:LDFLAGS := -m elf64_sparc
x86_64/Makefile:LDFLAGS := -m elf_x86_64

Little less than half of the architectures defines their own LDFLAGS. Most of them set an emulation, most probarly inherited from i386.

Quoted 2 lines

[Why on earth would -m be needed, anyway?]

I do not know, but as can be seen above several architectures use it.

Quoted 6 lines

I have seen your proposed patch for gnu.linkonce.
I do prefer to have it in arch/v850/Makefile because this is a workaround for an architecture specific bug in ld.
Why not provide your own link script?

Sam

The 'emulation' really defines the linker-script to use. The name is pretty much a misnomer. Different architectures require different linking parameters and you can force the linker to provide a a.out (ZMAGIC) output as well as ELF.

Execute ld -V and the linker script will be displayed. If you do ld -V -m x it will show the emulations provided, on ix86 machines, it's i386linux (for a.out) and elf_i386 (for ELF).

Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips). Why is the government concerned about the lunatic fringe? Think about it.

#7 lore raw
In reply to Miles Bader

In message <[email protected]> you write:

Quoted 9 lines
Quoted 4 lines · Miles Bader

When I try to build modules using 2.5.54, the resulting .ko files lack the .gnu.linkonce.* sections, which causes the kernel module loader to fail on them -- those sections _are_ present in the .o files, but the linker apparently removes them!

Ok, I found out why this is happening -- the v850 default linker scripts, for whatever reason, merge any section called `.gnu.linker.t*' with .text.

That's about as wierdass as it comes.

Quoted 4 lines

I can prevent this by adding the option `--unique=.gnu.linkonce.this_module' to the linker flags (specifically, to LDFLAGS_MODULE in the top-level Makefile). I suppose another way to do it would be to rename the section something that doesn't match `.gnu.linker.t*'.

Or you could add this flag in arch/v850/Makefile.

Quoted 4 lines

What's the right way to handle this?

[from perusing the ld srcs, a few other archs seem to have the same feature,' though the only that I think has linux support is cris']

I think:

	LDFLAGS_MODULE += -T arch/v850/module.lds

And include a linker script there which works.

Thanks for finding this...
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.