Reputation: 91
I have two object files, one is generated from assembly and another is compiled from rust. From the assembly I call a function in the rust (as below) so I need to link them together.
//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!";
...
}
After compile I found there are a .rodata
section and a .text
section in the rust object file, and there are instructions that use rip-relative addressing to address the "hello world" string in the .rodata
section:
//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)
...
I also have .rodata
section and .text
section in the assembly. However, during linking the linker just merge the two .rodata
sections and two .text
sections into one .rodata
section and one .text
section, which affects the rip-relative addressing, causing my program not working working.
Can anybody tell me how should I make modifications to resolve the problem?
This is my linker script, Should I modify it?
ENTRY(start)
SECTIONS {
. = 0x00100000;
.boot :
{
*(.multiboot_header)
}
.text :
{
*(.text)
}
}
Thank you for your help!
Upvotes: 3
Views: 973
Reputation: 91
I figure it out. Thanks to the hints offered by Peter Cordes. The reason is that I compiled my rust code to an executable rather than a library. I should compile it into a library(a .a
file) so the linker can calculate the offset of rip-relative addressing during link-time. If it's compiled into an executable then the offset is already calculated so the linker can't recalculate it and the problem I mentioned will arouse. Please forgive me that this is a silly mistake(how could you link an executable with other), I haven't look into such things seriously before.
Upvotes: 4