>我有两个对象文件,一个是从汇编生成的,另一个是从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 相对寻址来解决.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)
}
}
感谢您的帮助!
我想通了。感谢彼得·科德斯提供的提示。原因是我将 rust 代码编译为可执行文件而不是库。我应该将其编译到一个库(一个.a
文件(中,以便链接器可以在链接时计算翻录相对寻址的偏移量。如果它被编译成可执行文件,那么偏移量已经计算出来,所以链接器无法重新计算它,我提到的问题就会引起。请原谅我这是一个愚蠢的错误(你怎么能将可执行文件与其他可执行文件链接(,我以前没有认真研究过这样的事情。