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

ARM64裸机Payload移出全局const变量后.rodata地址异常求助

解决ARM64 Payload全局变量地址错位问题

核心问题根源

全局字符串存放在.rodata段,指针存放在.data段,默认链接脚本会将这些段分配到与.text间隔较大的地址区域,而你的Payload加载环境仅映射或默认从.text起始地址运行,导致代码访问的指针地址与实际字符串存储地址不匹配。


解决方案(按优先级排序)

1. 强制将全局变量嵌入.text段

直接用编译器属性把字符串和指针都放到.text段的自定义子段中,避免跨段地址偏移问题:

// 将字符串直接嵌入.text段,无需单独指针
const char txt[] __attribute__((section(".text.str"))) = "Hello, world!";

// 如果必须用指针(比如跨函数访问),同样把指针也塞进.text
const char* txt_ptr __attribute__((section(".text.ptr"))) = txt;

这样编译后,字符串和指针会和代码逻辑放在同一个.text段内,链接器不会将其拆分到其他高地址区域,加载后地址完全匹配。

2. 使用自定义链接脚本控制段顺序

如果需要保留.rodata/.data段,自定义极简链接脚本强制所有必要段紧跟.text,确保地址连续:

ENTRY(_start)
SECTIONS {
    . = 0x10000;  // 替换为你的Payload实际加载基址
    .text : {
        *(.text)          // 代码段
        *(.text.str)      // 自定义字符串子段(如果用了方案1)
        *(.text.ptr)      // 自定义指针子段(如果用了方案1)
    }
    .rodata : { *(.rodata) } > .text  // .rodata紧跟.text
    .data : { *(.data) } > .text     // .data紧跟.text
    /DISCARD/ : { *(.note*) *(.comment*) *(.eh_frame*) }  // 丢弃无用段
}

在Makefile中指定链接脚本:

LDFLAGS += -T payload.ld

3. 精简objcopy命令,剔除冗余段

之前二进制暴增是因为默认objcopy包含了大量无用段,现在只保留必要段:

arm-none-eabi-objcopy -O binary \
    --only-section=.text \
    --only-section=.rodata \
    --only-section=.data \
    payload.elf payload.bin

这样生成的二进制大小会被严格控制在29000字节以内。

4. 验证地址正确性

编译后用arm-none-eabi-objdump -d -s payload.elf查看,确认:

  • 代码中访问txt的指令(比如ldr x0, =txt)对应的地址,与字符串实际存储地址一致
  • 所有段的地址是连续的,没有出现大的间隔

内容的提问来源于stack exchange,提问作者kupper.m

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:50:21