Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write::write_fmt causes page fault on a bare metal

Tags:

rust

osdev

My experimental code crashes when running on bare x86_64-metal (page fault when IDT is not yet set), but works perfectly on aarch64.

By careful tracing I figured out that the cause of this page fault consists of corrupted address (much higher than 0x200_000, while only the first 2M page is yet mapped as 1:1) of function "f" passed as an argument to core::fmt::ArgumentV1::new() function:

#[doc(hidden)]
#[unstable(feature = "fmt_internals", reason = "internal to format_args!")]
pub fn new<'b, T>(x: &'b T,
                  f: fn(&T, &mut Formatter) -> Result) -> ArgumentV1<'b> {
    unsafe {
        ArgumentV1 {
            formatter: mem::transmute(f),
            value: mem::transmute(x)
        }
    }
} 

AFAIK this value is hard-coded by rustc compiler being result of compile-time processing of format_args! variadic arguments.

Maybe you have suggestions what's wrong with this case. Thanks.

like image 446
ababo Avatar asked Aug 06 '15 18:08

ababo


1 Answers

Quoted from the Rust project's RELEASES.md:

fn item types are zero sized, and each fn names a unique type. This will break code that transmutes fns, so calling transmute on a fn type will generate a warning for a few cycles, then will be converted to an error.

This is part of the release notes for Version 1.9.0 (2016-05-26) so if you are using this version it might be a bug in the std library, if you are on <1.9 you should probably try to copy your code into the playpen and let it generate the assembly so you see where the address actually comes from.

like image 156
benaryorg Avatar answered Oct 11 '22 18:10

benaryorg