实现一个类似 module_init 的 Linux 内核,但是在 ld 脚本中遇到了一些麻烦

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

我非常喜欢 linux 内核 module_init 功能,我想为我的用户 space 应用程序实现相同的功能。

我尝试修改链接器脚本来执行此操作:

1、复制一个x86-64标准的ld脚本

2、添加我的自定义栏目

  .module.init         :
    {
     PROVIDE_HIDDEN (__module_init_start = .);
     *(.module_init*)
     PROVIDE_HIDDEN (__module_init_end = .);
    }

3、将init函数指针放入moudle_init段

#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、使用自定义链接描述文件(基于标准链接描述文件)编译应用程序

gcc  -o "./module_init" -T module.lds ./module_init.o

5,然后我objdump moudle_init,我发现生成的部分是:

Disassembly of section .module_init:

0000000000a01080 <__initcall_unit_test_1_init>:
  a01080:   ad                      lods   %ds:(%rsi),%eax
  a01081:   05 40 00 00 00          add    [=15=]x40,%eax
    ...

0000000000a01088 <__initcall_unit_test_2_init>:
  a01088:   c2 05 40                retq   [=15=]x4005
  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    [=15=]x40,%eax
    ...

0000000000a01098 <__initcall_unit_test_4_init>:
  a01098:   ec                      in     (%dx),%al
  a01099:   05 40 00 00 00          add    [=15=]x40,%eax

但是 __module_init_start 和 __module_init_end 变量不是我期望的值。在我的例子中,__module_init_start 是 0x4005ad,__module_init_end 是 0x400000003。 这很奇怪,因为0x4005ad是__initcall_unit_test_1_init.

的地址

谁能告诉我如何让这个用户 space module_init 工作?

链接描述文件只能设置变量的地址。使用 &__module_init_start 获取指向节开头的指针,使用 &__module_init_end 获取指向结尾的指针。