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

如何为树莓派GCC可执行文件添加RWX权限自定义段

树莓派GCC自定义RWX段解决方案

问题根源

你现有链接脚本仅定义了段的位置,但未显式指定RWX权限——默认情况下自定义段会继承插入位置(.text)的RX权限,导致写入操作触发内存保护错误,最终程序崩溃。

可行方案

1. 修改链接脚本,显式设置RWX权限

更新链接脚本,明确指定段的权限属性,同时添加符号标记段的范围方便代码访问:

SECTIONS
{
  .dictionary : ALIGN(4)
  {
    __dict_start = .;          // 段起始地址符号
    *(.dictionary)             // 收集所有.dictionary节
    . += 0x2000;               // 预分配8KB空间,可按需调整
    __dict_end = .;            // 段结束地址符号
  } : ATTRIBUTES((READ,WRITE,EXECUTE))
}
INSERT AFTER .text;
  • ALIGN(4):适配ARM架构的内存对齐要求
  • __dict_start/__dict_end:代码中可直接引用这两个符号获取段的地址范围
  • ATTRIBUTES((READ,WRITE,EXECUTE)):强制设置RWX权限,覆盖默认继承属性

2. 代码中访问自定义段

通过链接脚本定义的符号,或者直接声明属于该段的缓冲区,实现代码写入与执行:

// 声明链接脚本中的段范围符号
extern char __dict_start[], __dict_end[];

// 或者直接定义属于.dictionary段的缓冲区
__attribute__((section(".dictionary")))
uint8_t code_buffer[0x2000];

// 示例:写入ARM指令并执行
void execute_custom_code() {
    // 写入ARM架构的返回指令(BX LR)
    uint32_t return_instr = 0xE12FFF1E;
    memcpy(code_buffer, &return_instr, sizeof(return_instr));
    
    // 转换为函数指针并执行
    void (*custom_func)() = (void(*)())code_buffer;
    custom_func();
}

3. 编译链接命令

使用指定的链接脚本编译,无需-N或-zexecstack(除非你还需要栈上执行代码):

# 编译目标文件
gcc -c your_source.c -o your_source.o
# 链接生成可执行文件
gcc your_source.o -T your_script.ld -o your_program

4. 验证段权限

用readelf确认段权限是否正确:

readelf -l your_program | grep .dictionary

输出中需包含RWE标记,表明段已具备RWX权限。

注意事项

  • 树莓派ARM架构默认开启内存保护,确保系统未限制RWX段(树莓派官方系统默认允许)
  • 预分配空间大小需根据实际需求调整,避免内存溢出
  • 写入的代码必须符合ARM指令集格式,注意小端字节序的要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:45:32