我有两个目标文件,一个是从程序集生成的,另一个是从rust编译的。从程序集中,我在rust中调用一个函数(如下所示),因此需要将它们链接在一起。
//boot.asm
section .text
...
extern _start
call _start
...
//main.rs
#![no_std]
#![no_main]
#[no_mangle]
pub extern fn _start() {
let hello = b"hello_world!";
...
}
[编译后,我发现rust对象文件中有一个.rodata
部分和一个.text
部分,并且有一些指令使用rip-relative寻址来在.rodata
部分中寻址“ hello world”字符串:
//section .text
...
let hello = b"hello world!";
2017e7: 48 8d 05 2e ea ff ff lea -0x15d2(%rip),%rax
2017ee: 48 89 44 24 30 mov %rax,0x30(%rsp)
...
我在程序集中也有.rodata
部分和.text
部分。但是,在链接程序链接期间,只需将两个.rodata
节和两个.text
节合并为一个.rodata
节和一个.text
节,这会影响相对引用寻址,导致我的程序无法正常工作。谁能告诉我如何进行修改以解决问题?这是我的链接脚本,我应该修改它吗?
ENTRY(start)
SECTIONS {
. = 0x00100000;
.boot :
{
*(.multiboot_header)
}
.text :
{
*(.text)
}
}
谢谢您的帮助!
我知道了。感谢Peter Cordes提供的提示。原因是我将rust代码编译为可执行文件而不是库。我应该将其编译到一个库(一个.a
文件)中,以便链接器可以计算链接时相对rip寻址的偏移量。如果将其编译为可执行文件,则偏移量已经计算出来,因此链接器无法重新计算它,而我提到的问题将会引起。请原谅我这是一个愚蠢的错误(您如何将可执行文件与其他文件链接),我以前从未认真研究过此类事情。