Skip to content
Advertisement

Implement a similar module_init as Linux kernel, but meet some trouble in ld script

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?

Advertisement

Answer

The linker script can only set the addresses of variables. Use &__module_init_start to get a pointer to the start of the section, and &__module_init_end to get a pointer to the end.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement