I like the linux kernel module_init function very much, I would like to implement the same function for my user space applications.
I try to modify the linker script to do this:
1, copy a x86-64 standard ld script
2, add my customized section
.module.init :
{
PROVIDE_HIDDEN (__module_init_start = .);
*(.module_init*)
PROVIDE_HIDDEN (__module_init_end = .);
}
3, put the init function pointer into moudle_init section
#define app_module_init(x) __initcall(x);
#define __initcall(fn) \
static initcall_t __initcall_##fn \
__attribute__ ((__section__(".module_init"))) = fn
app_module_init(unit_test_1_init);
app_module_init(unit_test_2_init);
app_module_init(unit_test_3_init);
app_module_init(unit_test_4_init);
4, compile the app with a customized linker script(based on the standard one)
gcc -o "./module_init" -T module.lds ./module_init.o
5, Then I objdump the moudle_init, I found the section is generated:
Disassembly of section .module_init:
0000000000a01080 <__initcall_unit_test_1_init>:
a01080: ad lods %ds:(%rsi),%eax
a01081: 05 40 00 00 00 add $0x40,%eax
...
0000000000a01088 <__initcall_unit_test_2_init>:
a01088: c2 05 40 retq $0x4005
a0108b: 00 00 add %al,(%rax)
a0108d: 00 00 add %al,(%rax)
...
0000000000a01090 <__initcall_unit_test_3_init>:
a01090: d7 xlat %ds:(%rbx)
a01091: 05 40 00 00 00 add $0x40,%eax
...
0000000000a01098 <__initcall_unit_test_4_init>:
a01098: ec in (%dx),%al
a01099: 05 40 00 00 00 add $0x40,%eax
But the __module_init_start and __module_init_end variable is not the value I expected. In my case __module_init_start is 0x4005ad and __module_init_end is 0x400000003. This is very weird, because 0x4005ad is the address of __initcall_unit_test_1_init.
Anyone can give me an idea on how to make this user space module_init work?