[Half Solved]Cross-compiling fails with an error "Calling a function with bad signature!"


#1

First of all, I am sorry for a long post in my poor English.

When I compiled the following code for Linux target on Linux, it succeeded.
But when I compiled it for Windows target on Linux, it failed with an error like

rustc: /checkout/src/llvm/lib/IR/Instructions.cpp:258: void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, const llvm::Twine&): Assertion `(Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"' failed.
error: Could not compile `test`.

How can I fix this error, or am I something wrong?

environment
Linux(ArchLinux)
rustc 1.18.0-nightly
mingw 6.3.1

Cargo.toml

[package]
name = "test"
version = "0.1.0"
authors = ["user <user@example.com>"]
[dependencies]
libc = { version = "", default-features = false }

.cargo/config

[target.x86_64-pc-windows-gnu]
linker = "/usr/bin/x86_64-w64-mingw32-gcc"

main.rs

#![feature(lang_items, core_intrinsics)]
#![feature(start)]
#![no_std]
#![no_main]
use core::intrinsics;

extern crate libc;

#[no_mangle]
pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {

    let s = "test" ;
    for c in s.chars() {
        //do something
    }
    0
}

#[lang = "eh_personality"]
#[no_mangle]
pub extern fn rust_eh_personality() {
}

#[lang = "eh_unwind_resume"]
#[no_mangle]
pub extern fn rust_eh_unwind_resume() {
}

#[lang = "panic_fmt"]
#[no_mangle]
pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
                            _file: &'static str,
                            _line: u32) -> ! {
    unsafe { intrinsics::abort() }
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn _Unwind_Resume() -> ! {
    loop {}
}

command to compile

$ cargo build --target=x86_64-pc-windows-gnu

details
My final goal is to write an efi application on Linux.
So firstly I wrote a simple no_std application(just return 0.) for Linux target according to the page of rust book “no-stdlib.html” and it succeeded to build and run.

But it failed to build for Windows target with an error related to gcc.
So I added .cargo/config according to this blog enty and it succeeded to building for both targets.

Then I tried to add something to main function like this.

let s = "test" ;
for c in s.chars() {
    //do something
}

This time, it failed with an error “undefined reference to _Unwind_Resume”.
So according to this article, I added the function like below and it succeeded to build and run on Linux.

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn _Unwind_Resume() -> ! {
    loop {}
}

Finally, I tried to build it for Windows target but it failed with the error I wrote at the beginning of this post.


#2

I found this bug report.
So I changed rust_eh_unwind_resume() to rust_eh_unwind_resume(a : * mut u8), and finally it succeed to build and run!

But if I changed it to rust_eh_unwind_resume(a : * mut u64), it also succeed to build and run…

Now I am confusing that what is the correct argument for the function rust_eh_unwind_resume…