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

链接器脚本初始化数组中为何存在两个KEEP语句?

为什么链接器脚本中.init_array段的两个KEEP语句都是必要的?

嘿,这个问题问到点子上了——这两个KEEP语句各司其职,少了任何一个都可能导致程序初始化出问题,我来给你逐一拆解:

首先得明确.init_array段的作用:它是ELF格式中专门用来存放全局对象构造函数指针(以及其他需要在main函数前执行的初始化函数指针)的段。编译器会把不同优先级的初始化函数,分别放到带后缀的子段(比如.init_array.00000、.init_array.10000)和不带后缀的默认段里。

第一个KEEP (*(SORT(.init_array.*)))的作用

  • SORT(.init_array.*):所有带后缀的.init_array子段都是编译器根据初始化优先级生成的(后缀数值对应优先级,数值越小优先级越高),SORT会把这些子段按后缀数值从小到大排序,保证初始化函数严格按照优先级顺序执行。
  • KEEP:链接器默认会启用**垃圾回收(GC)**功能,把那些看起来“未被直接引用”的段删掉。但这些初始化函数是由运行时启动代码间接调用的,链接器识别不出它们的引用关系,所以必须用KEEP强制保留这些带优先级的子段,否则会导致高优先级的初始化函数被丢包,或者执行顺序彻底混乱。

第二个KEEP (*(.init_array))的作用

这个语句针对的是没有指定优先级的初始化函数指针所在的默认.init_array段。同样,因为这些函数也是由启动代码间接调用,链接器会误以为它们是未使用的冗余代码,所以需要KEEP来强制保留。如果漏掉这个语句,那些没有设置优先级的全局对象就不会被正确构造了。

为什么要分开写?

因为带后缀的.init_array.*需要排序来保证优先级顺序,而不带后缀的.init_array不需要额外排序(它的顺序是链接时的默认顺序),分开处理才能让排序逻辑只作用在需要的子段上,同时确保两类初始化函数都被完整保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:35:41