You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用于模拟Linux内核Initcall机制的自定义ld脚本工作原理是什么?

解决用户态模拟Linux内核Initcall机制时的链接器错误

Hey everyone, let me break down a common issue when trying to replicate the Linux kernel's Initcall mechanism in user space—something Trevor ran into recently while writing a test program to simulate init_module() calls.

The Problem

When Trevor tried compiling his user-space program, the linker threw an error complaining that __initcall_start and __initcall_end were undefined. No executable could be generated at all.

Why This Happens

The Linux kernel's Initcall system relies on two special symbols—__initcall_start and __initcall_end—that are defined in the kernel's custom link script. These symbols mark the start and end of the section where initialization functions are stored. But user-space programs use the default system linker script, which doesn't include these symbols. So the linker has no idea what they're supposed to point to.

The Fix

We need to create a custom linker script that adds these missing symbols. Here's how to do it step by step:

  1. Export the default linker script: Run ld --verbose in your terminal, and save the entire output to a file (let's call it my_initcall.ld). This gives you a base to modify.
  2. Add the initcall symbols: Open my_initcall.ld and find the section where the .text segment is defined. Right before that, add code to define our initcall symbols and map the relevant sections. For example:
    __initcall_start = .;
    *(SORT(.initcall*.init))
    __initcall_end = .;
    
    This tells the linker to set __initcall_start at the current address, include all sections matching .initcall*.init (matching the kernel's initcall naming convention), then mark __initcall_end at the end of those sections.
  3. Compile with the custom script: When compiling your program, add the -T my_initcall.ld flag to tell gcc (or ld) to use your modified linker script instead of the default one.

Proof It Works

After making these changes, the linker no longer throws errors. Here's a snippet from objdump -d on the working executable, showing the symbols are correctly placed:

0000000000401000 <__initcall_start>:
401000: 55 push %rbp
401001: 48 89 e5 mov %rsp,%rbp
401004: b8 00 00 00 00 mov $0x0,%eax
401009: 5d pop %rbp
40100a: c3 retq

000000000040100b <__initcall_end>:
40100b: e9 f0 ff ff ff jmpq 400ff0 <_start>

内容的提问来源于stack exchange,提问作者Baroudi Safwen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:07:14