我有两个目标文件,一个是由程序集生成的,另一个是由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
节,这会影响rip-relative寻址,导致我的程序无法正常工作。谁能告诉我如何进行修改以解决问题?
这是我的链接描述文件,我应该修改它吗?
ENTRY(start)
SECTIONS {
. = 0x00100000;
.boot :
{
*(.multiboot_header)
}
.text :
{
*(.text)
}
}
谢谢您的帮助!
最佳答案
我知道了。感谢Peter Cordes提供的提示。原因是我将rust代码编译为可执行文件而不是库文件。我应该将其编译到一个库(一个.a
文件)中,以便链接器可以计算链接时相对rip寻址的偏移量。如果将其编译为可执行文件,则偏移量已经计算出来,因此链接器无法重新计算它,并且会引起我提到的问题。请原谅我这是一个愚蠢的错误(您如何将可执行文件与其他文件链接),我之前从未认真研究过此类问题。
关于assembly - 如何在不影响rip相对寻址的情况下正确链接两个目标文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59474762/