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

x86_64 Linux下如何将非.text的自定义节设置为可执行权限

自定义节丢失可执行权限的核心原因

链接器对输出节的权限赋值遵循节自身属性标记 > MEMORY区域默认属性的优先级规则。你之前遇到的所有权限异常,本质都是自定义节没有显式声明可执行属性,导致链接器按照内置的默认节名规则推断权限:

  • 节名匹配内置规则(如.text默认带可执行、.rodata默认只读、.data默认可读写)时,会自动赋予对应权限
  • 节名不匹配内置规则时,哪怕所在MEMORY区域标记了可执行属性,链接器也会默认给节分配只读、无执行的权限,最终导致程序加载时触发非执行页的段错误
正确配置方法

1. 给自定义可执行节显式添加权限标记

在链接脚本的SECTIONS规则中,给自定义节的声明行加上:rx属性标记,这是GNU ld原生支持的语法,可直接强制指定节的读、执行权限:

SECTIONS
{
  . = __linux_mmap_min_addr;
  # 给自定义的.my_section显式标记可读、可执行权限
  .my_section :rx
  {
    *(.my_section*)
  } > rom
  .rodata :r
  {
    *(.rodata*)
  } > rom
}

其中属性标记的含义:

  • r:节内容可读
  • w:节内容可写
  • x:节内容可执行

2. 解释你之前尝试迁移到.text节失败的原因

GNU ld的内置权限规则仅在你没有自定义该节的装载规则时生效。如果你在链接脚本里重写了.text节的装载逻辑,但没有显式给该节加:rx标记,内置的.text默认可执行规则就会失效——哪怕节名叫.text,最终也会被分配无执行权限。正确写法示例:

# 这种写法会丢失.text的默认可执行权限,和你之前遇到的旧问题一致
.text :
{
  *(.my_section*)
} > rom

# 正确写法:自定义.text节时也要显式加属性标记
.text :rx
{
  *(.my_section*)
} > rom
验证方法

修改完链接脚本后,执行以下命令确认权限正确:

  • 用readelf -S 输出程序名查看节表,确认.my_section的Flags列带有X标记(即标记为R X,而非仅R)
  • 用readelf -l 输出程序名查看程序头表,确认包含该节的程序段Flg列带有E(可执行)标记

注意:如果可执行节和只读数据节的加载地址没有按内存页边界对齐,链接器可能会把二者合并到同一个程序段里,此时段权限会以最先定义的节的属性为准,可能导致可执行权限被覆盖。建议在脚本中给可执行节和只读数据节之间加上页对齐规则,比如在节装载规则里加. = ALIGN(0x1000);确保边界对齐,让链接器生成独立的权限段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 21:45:02