Causes conflict when used in a staticlib
Closed this issue · 12 comments
When using limine-rs in a staticlib, and linking that into an executable using ld.lld, the IDs inside the statics somehow get duplicated and cause conflicts:
Source with staticlib changes to reproduce: https://github.com/xdevs23/limine-rust-barebones/tree/staticlib-issue
When using binwalk on the staticlib file, we can see that there are two findings:
$ binwalk -R "\x75\xdd\x81\xd8\xdc\x27\x58\x9d\x1b" kernel/target/x86_64-unknown-none/debug/liblimine_rust_barebones.a
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
155068 0x25DBC Raw signature (\x75\xdd\x81\xd8\xdc\x27\x58\x9d\x1b)
206148 0x32544 Raw signature (\x75\xdd\x81\xd8\xdc\x27\x58\x9d\x1b)
But when the same command is run on the executable (without my changes), only one occurrence is found:
$ binwalk -R "\x75\xdd\x81\xd8\xdc\x27\x58\x9d\x1b" kernel/target/x86_64-unknown-none/debug/limine-rust-barebones
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
9320 0x2468 Raw signature (\x75\xdd\x81\xd8\xdc\x27\x58\x9d\x1b)
I tried to define the structs myself in a more simple manner:
xdevs23/limine-rust-barebones@55f3376
If you build this branch, it works: https://github.com/xdevs23/limine-rust-barebones/tree/staticlib-issue-workaround
On the branch I mentioned, the limine crate is not used and instead, the limine_def
module contains simpler structs.
Here's the binwalk output:
$ binwalk -R "\x75\xdd\x81\xd8\xdc\x27\x58\x9d\x1b" kernel/target/x86_64-unknown-none/debug/liblimine_rust_barebones.a
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
136288 0x21460 Raw signature (\x75\xdd\x81\xd8\xdc\x27\x58\x9d\x1b)
And a screenshot:
I created a modified version of limine-rs which seemed to have fixed the issue, but now, whenever I use the response, there's a conflict again:
This is really weird and I'm starting to think that the rust compiler is redundantly placing the ID of the request somewhere in the data.
Why are you compiling as a static library and then turning it into an executable? Compiling it normally works fine.
In my actual kernel project, I'm linking object files written in other languages together with the rust staticlib to form the final executable.
I heard that I can also use #[limine_tag]
. I'm currently trying that instead.
Using #[limine_tag]
and having a .limine_reqs
section solves the issue.
use limine::{LimineBootInfoRequest, limine_tag};
#[limine_tag]
static BOOT_INFO_REQUEST: LimineBootInfoRequest = LimineBootInfoRequest::new(0);
.limine_reqs ALIGN(0x1000) : AT (ADDR (.limine_reqs) - load_addr)
{
KEEP(*(.limine_reqs))
}
Binwalk still shows two occurrences for the statliclib, but when linked to a final executable, only one remains.
I think it is because of debug info. Try release @xdevs23.
I think it is because of debug info. Try release @xdevs23.
Release has the same result from what I have tested so far.
Are you sure you do not have debug information enabled? That is the only way I can think of right now that could produce a duplicate tag.
@Andy-Python-Programmer I think so. I built it as release:
Hi @xdevs23,
Could you please clone the crate and apply the following patch:
diff --git a/src/lib.rs b/src/lib.rs
index 7b69a87..32b90d8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -190,11 +190,11 @@ macro_rules! make_struct {
// XXX: The request ID is composed of 4 64-bit wide unsigned integers but the first
// two remain constant. This is refered as `_COMMON_MAGIC` in the protocol
// header.
- pub const ID: [u64; 4] = [0xc7b1dd30df4c8b88, 0x0a82e883a194f07b, $id1, $id2];
+ // pub const ID: [u64; 4] = [0xc7b1dd30df4c8b88, 0x0a82e883a194f07b, $id1, $id2];
pub const fn new(revision: u64) -> Self {
Self {
- id: Self::ID,
+ id: [0xc7b1dd30df4c8b88, 0x0a82e883a194f07b, $id1, $id2],
revision,
response: UnsafeCell::new(Ptr::DEFAULT),
Then make use of the patched crate to build it and see if it makes a difference.
@Andy-Python-Programmer
That works!
Had to also change something in the barebones code:
diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock
index b1c66b8..3292858 100644
--- a/kernel/Cargo.lock
+++ b/kernel/Cargo.lock
@@ -11,8 +11,6 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "limine"
version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e9d0c951056ac044f0e6b09448b9d702f8fb1001db89cffd2bc467bd1c25307"
[[package]]
name = "limine-rust-barebones"
diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml
index d17de80..73f57a5 100644
--- a/kernel/Cargo.toml
+++ b/kernel/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-limine = "0.1"
+limine = { path = "limine-rs" }
spin = "0.9"
[profile.dev]
diff --git a/kernel/lib.rs b/kernel/lib.rs
index 504b736..cd01cb6 100644
--- a/kernel/lib.rs
+++ b/kernel/lib.rs
@@ -3,9 +3,9 @@
use core::arch::asm;
-use limine::LimineFramebufferRequest;
+use limine::FramebufferRequest;
-static FRAMEBUFFER_REQUEST: LimineFramebufferRequest = LimineFramebufferRequest::new(0);
+static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new(0);
#[no_mangle]
unsafe extern "C" fn _start() -> ! {
Thank you!
np :^)