assembly - 如何在不影响rip相对寻址的情况下正确链接两个目标文件?

标签 assembly rust linker ld instructions

我有两个目标文件,一个是由程序集生成的,另一个是由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/

相关文章:

assembly - 处理器是否可以同时进行存储和算术运算?

c++ - 如何在 Visual C++ 内联汇编程序中通过引用获取值?

testing - Rust:带有 lib 和二进制目标的 crate 中的属性 #[cfg(test)]

ios - YouTube API : clang: error: linker command failed with exit code 1 (use -v to see invocation)

c - 如何使用 header 将多个 c 文件链接在一起?

c++ - 为什么C++使用32位寄存器来存储8位值

c - 如何使用 Sublime Text 生成程序集输出?

python - Linux编译opencv python报错: ImportError: libjasper. so.1

rust - 如何在库中使用 pub(crate) 方法具有公共(public)特征?

macros - 在宏输出中转义逗号