下面是一个简单的例子:
lib.rs:
#![feature(lang_items)]
#![no_std]
extern crate rlibc;
extern crate libc;
use libc::{c_int, c_char};
#[no_mangle] // just for easier llvm-ir reading
fn foo(baz: &str) -> usize {
baz.len()
}
#[no_mangle]
pub extern fn main(_argc: c_int, _argv: *const *const c_char) -> c_int {
let gdb_wait = true; // for debugging with gdb
while unsafe { core::ptr::read_volatile(&gdb_wait) } {}
assert_eq!(foo(&"bar_fail"), 0);
assert_eq!(foo("bar_ok"), 6);
loop {}
}
// just some functions to run on bare metal.
#[lang = "panic_fmt"]
#[no_mangle]
pub extern fn rust_begin_panic(_msg: core::fmt::Arguments, _file: &'static str, _line: u32) -> ! {
loop {}
}
#[lang = "eh_personality"]
pub extern fn eh_personality() { loop {} }
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn _Unwind_Resume() -> ! { loop {} }
#[no_mangle]
pub extern fn fmod(_: f64, _: f64) {
loop { }
}
#[no_mangle]
pub extern fn fmodf(_: f32, _: f32) {
loop { }
}
asm在qemu-system-x86_64上以64bit-longmode模式调用Main函数
传递&&str
时第一次调用的GDB输出。这行不通:
(gdb) print baz
$1 = {data_ptr = 0x0, length = 0}
传递&str
时第二个调用的GDB输出。
(gdb) print baz
$2 = {data_ptr = 0xffffffff80133460 <str4498> "bar_oksrc/lib.rsassertion failed: `(left == right)` (left: ``, right: ``) 01gdb_load_rust_pretty_printers.py", length = 6}
这个问题可以通过编辑链接器脚本来解决。字符串被放置在内存中的bss段之后。所以multiboot用0填充。