使用GNU链接器生成可重定位模块并调用绝对地址的问题
解决MC68360平台GNU链接器生成可重定位模块调用ROM绝对地址函数的问题
问题描述
在MC68360平台使用GNU开发工具时,需要生成可重定位执行模块调用ROM内存中的绝对地址函数,但遇到以下问题:应用中函数调用位置为可重定位地址,提供的函数地址为绝对地址,最终生成的模块里调用地址仍为可重定位状态,加载时会被加载地址修改,导致无法正确调用目标函数。
当前操作流程
- 从ROM镜像提取全局函数生成
rom_functions.S文件,内容如下:
.text .globl sqrt .equ sqrt, 0x<abs addr>
- 使用
readelf检查rom_functions.o,确认所有符号均为绝对地址且无重定位表。 - 通过以下命令链接生成可重定位模块:
ld -d -r -Rrom_functions.o -uappl_start -Tmyscript @$objs -o appl.rel appl.o
原本预期-R选项可保留绝对地址,但实际效果不符合预期;尝试-R<rom.img>也得到类似结果。
可行解决方案
方案1:汇编实现绝对跳转桩
修改rom_functions.S,用汇编创建直接跳转至ROM绝对地址的函数桩,确保调用时不生成重定位项:
.text .globl sqrt sqrt: jmp 0x<abs addr> # 硬编码跳转至ROM中的目标绝对地址
编译该文件得到的rom_functions.o中,sqrt符号指向桩函数,桩内的跳转是固定绝对地址,链接后应用调用sqrt会直接跳转到ROM目标地址,无重定位。
方案2:链接时用--defsym绑定绝对符号
无需单独编写rom_functions.S,直接在链接命令中通过--defsym将符号强制绑定到绝对地址:
ld -d -r --defsym sqrt=0x<abs addr> -uappl_start -Tmyscript @$objs -o appl.rel appl.o
该选项会让链接器将sqrt标记为绝对符号,不会为其生成重定位项,应用中的调用直接指向指定的ROM地址。
方案3:链接脚本中定义绝对符号
在你的myscript链接脚本中,为ROM符号添加ABSOLUTE属性:
PROVIDE(sqrt = ABSOLUTE(0x<abs addr>));
链接时移除-R选项,直接使用该脚本,链接器会将sqrt视为绝对符号,避免生成重定位。
关键说明
-R选项的作用是将指定文件的符号加入链接器符号表用于解析,但在生成可重定位模块(-r参数)时,链接器仍会为这些符号生成重定位项——因为-r的核心是保留模块的可重定位能力。要实现调用绝对地址,必须让链接器将目标符号标记为绝对符号,上述三种方案均通过不同方式达成这一目标。
内容的提问来源于stack exchange,提问作者BenJ
相关产品推荐
相关产品推荐

