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

自定义链接二进制含RWX权限LOAD段,如何修改linker script?

解决链接脚本中权限不同段合并为单一LOAD段的问题

你遇到的问题是链接器默认会把连续、权限兼容的段合并成一个LOAD程序头,导致.text、.rodata、.data、.bss被打包成了带RWX权限的LOAD段,既触发新版本GCC警告,也没法给内存页表设置正确的权限(比如.text不可写、.data不可执行)。要解决这个问题,需要用PHDRS显式定义不同权限的程序头,把每个段绑定到对应的LOAD段上,修改后的链接脚本如下:

ENTRY(kmain)
OUTPUT_FORMAT(elf64-x86-64)

// 显式定义各个权限的程序头,每个对应一个独立LOAD段
PHDRS {
    text PT_LOAD FLAGS(5);  // 5 = 读+执行(RX)权限
    rodata PT_LOAD FLAGS(4); // 4 = 只读(R)权限
    data PT_LOAD FLAGS(6);   // 6 = 读+写(RW)权限
    eh_frame PT_LOAD FLAGS(4); // .eh_frame 设为只读权限
}

SECTIONS {
    . = 0xFFFFFFFF80000000;

    // .text段绑定到text程序头,RX权限
    .text ALIGN(4K) : { *(.text) } :text

    // 强制跳过一页,避免链接器因地址连续尝试合并不同权限的段
    . += 4K;
    // .rodata段绑定到rodata程序头,R权限
    .rodata ALIGN(4K) : { *(.rodata) } :rodata

    . += 4K;
    // .data段绑定到data程序头,RW权限
    .data ALIGN(4K) : { *(.data) } :data

    // .bss和.data权限一致,绑定到同一个data程序头
    .bss ALIGN(4K) : { *(.bss) } :data

    . += 4K;
    // .eh_frame绑定到独立的eh_frame程序头,R权限
    .eh_frame ALIGN(4K) : { *(.eh_frame) } :eh_frame
}

关键修改说明

  • PHDRS定义:用PHDRS块声明每个LOAD段的类型和权限,FLAGS参数对应ELF的权限位:5代表RX、4代表R、6代表RW,明确区分不同权限的LOAD段。
  • 段与程序头绑定:每个section定义末尾加上:<程序头名称>,把该段关联到对应的LOAD段,告诉链接器不要把它和其他权限的段合并。
  • 强制地址间隔:在不同权限的段之间加上. += 4K;,让段地址不连续,避免部分链接器因地址连续而错误合并不同权限的LOAD段。
  • 同权限段合并:.bss和.data都是RW权限,绑定到同一个data程序头,这样它们会被合并到同一个RW权限的LOAD段,符合内存权限规划。

修改完成后,你可以用readelf -l <你的二进制文件>查看程序头,应该能看到四个独立的LOAD段,分别对应RX、R、RW、R权限,每个段对应正确的代码/数据段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:25:27