GNU链接器问题:填充未用内存后目标文件缺失指定段代码
问题诊断与修复方案
嘿,我帮你梳理下链接脚本的问题,结合你的反汇编和hex输出情况,核心问题出在这几个地方:
1. 段名引用写错了!
你链接脚本里引用.s_region_1段的时候写的是*(s_region_1),但正确的段名引用必须带开头的点号,应该是*(.s_region_1)。链接器找不到匹配的段,直接跳过了这个区域的内容,这就是hex里完全看不到region_1机器码的直接原因。
2. 手动创建.fill段的方式不合理
你用自定义.fill段来填充空闲区域的做法,虽然地址计算上刚好到region_1的前一个字节,但这种方式会让链接器把这段空间当成一个独立的段,而且如果你的.s_region_1段没有标记为**可加载(LOAD)**属性,objcopy默认会忽略非加载段,不会把它放进hex文件里。
另外,其实链接器本身就支持自动填充段间空闲区域,不需要手动创建.fill段,这样更简洁也不容易出错。
修正后的链接脚本
把你的链接脚本改成下面这样,就能解决问题:
SECTIONS { . = 0xA0000000; .text : { *(.text) } /* 让链接器自动填充.text和.s_region_1之间的空闲区域 */ FILL(0xDEADC0DE); .s_region_1 : { *(.s_region_1) } .bss : { *(.bss) } _end = .; }
额外要注意的点
- 确保你的汇编代码里,
.s_region_1段被标记为可加载可执行,比如在汇编开头加上:
这里的.section .s_region_1,"ax"a表示段可分配,x表示可执行,这样objcopy才会把它包含到输出的hex里。 - 如果生成hex时还是有问题,可以显式指定要包含的段:
objcopy -O verilog --only-section=.text --only-section=.s_region_1 your_program.elf your_program.hex
验证步骤
修正后重新链接程序,先反汇编确认region_1的地址和指令都正确存在,再生成hex文件,检查里面是否包含0xa0000330地址对应的机器码(也就是00 40 0f 97、00 cf 8f 93这些字节,注意字节序)。
内容的提问来源于stack exchange,提问作者yildizabdullah
相关产品推荐
相关产品推荐

