Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mingw-w64 support #8488

Closed
wants to merge 9 commits into from
Closed

Mingw-w64 support #8488

wants to merge 9 commits into from

Conversation

klutzy
Copy link
Contributor

@klutzy klutzy commented Aug 13, 2013

This patchset enables rustc to cross-build mingw-w64 outputs.
Tested on mingw + mingw-w64 (mingw-builds, win64/seh/win32-threads/gcc-4.8.1).

I also patched llvm to support Win64 stack unwinding.
klutzy/llvm@ebe22bd

I cross-built test/run-pass/smallest-hello-world.rs and confirmed it works.
However, I also found something went wrong if I don't have custom #[start] routine.

@huonw
Copy link
Member

huonw commented Aug 13, 2013

What was the error message(s)/type of crash if there wasn't a custom #[start]?

@alexcrichton
Copy link
Member

If we need LLVM patches for stack unwinding, I could throw those in with #8328. I don't think I'm going to find the rusti fixes soon, but we don't want to change LLVM too often.

@graydon
Copy link
Contributor

graydon commented Aug 13, 2013

Wow, this is great! Thanks so much.

@klutzy
Copy link
Contributor Author

klutzy commented Aug 13, 2013

@huonw segfault from non-main thread.
Some more investigation: it seems to work well with std::rt::start_on_main_thread. At least this code works:

#[start]
fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
    do std::rt::start_on_main_thread(argc, argv, crate_map) {
        println("start_on_main_thread");
        do spawn {
            println("spawn");
        }
    };
    return 0;
}

But if I change start_on_main_thread to start, it segfaults (at non-main thread) in msvcrt.dll when it calls _write to print.
(Same symptom if I use MessageBoxA instead of println.)

@klutzy
Copy link
Contributor Author

klutzy commented Aug 14, 2013

With one more llvm patch (needed to build llvm on mingw-w64/SEH),
I cross-built rustc.dll and rustc.exe (with custom #[start] as above).

$ /d/usr/rust-64/bin/rustc.exe  --version
d:\usr\rust-64\bin\rustc.exe 0.8-pre
host: x86_64-w64-mingw32

However, touch empty.rs && rustc empty.rs failed with following message:

task <unnamed> failed at 'borrowed', D:\stone\rust\src\librustc\middle\resolve.rs:608

I don't know yet what it means.

@@ -247,4 +248,15 @@ mod dl {
fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
fn FreeLibrary(handle: *libc::c_void);
}

#[cfg(target_arch = "x86_64")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm probably missing something, but this code looks like it's exactly the same as the x86 code; is it required to be duplicated like this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extern "stdcall" { ... } vs extern { ... }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, omitting "stdcall" (see also #8509), although for subtle reason.
If extern "stdcall" is given, rustc produces llvm's function declaration with callconv=X86StdcallCallConv, even if win64 does not have such convention.
Then llvm makes it worse: it mangles function name e.g. "MessageBoxA" -> "_MessageBox@16" but win64 only has "MessageBoxA", so link fails.
I think llvm is wrong (it should ignore wrong callconv), but don't know rustc is wrong or not.

@huonw
Copy link
Member

huonw commented Aug 21, 2013

This needs a rebase (also, #8328 has now landed, if this was blocked on it).

klutzy added 9 commits August 26, 2013 22:14
Win64 convention does not use underscore.
Uses ArbitraryUserPointer area at gs:0x28.
Some extern blobs are duplicated without "stdcall" abi,
since Win64 does not use any calling convention.
(Giving any abi to them causes llvm producing wrong bytecode.)
This patch saves and restores win64's nonvolatile registers.
This patch also saves stack information of thread environment
block (TEB), which is at %gs:0x08 and %gs:0x10.
@klutzy
Copy link
Contributor Author

klutzy commented Aug 26, 2013

rebased; fixed the segfault issue mentioned above (std::rt::start issue), which was due to incomplete context switching.

bors added a commit that referenced this pull request Aug 26, 2013
This patchset enables rustc to cross-build mingw-w64 outputs.
Tested on mingw + mingw-w64 (mingw-builds, win64/seh/win32-threads/gcc-4.8.1).

I also patched llvm to support Win64 stack unwinding.
klutzy/llvm@ebe22bd

I cross-built test/run-pass/smallest-hello-world.rs and confirmed it works.
However, I also found something went wrong if I don't have custom `#[start]` routine.
@bors bors closed this Aug 26, 2013
@klutzy
Copy link
Contributor Author

klutzy commented Aug 27, 2013

Forgot to say llvm patches mentioned above: rebased on current master llvm head. klutzy/llvm@072c759 (let llvm emit segmented stacks on win64) and klutzy/llvm@7efe293 (to build llvm itself on mingw-w64+seh)

@alexcrichton
Copy link
Member

Those patches still need to be merged, right? It doesn't look like they were included in this.

@klutzy
Copy link
Contributor Author

klutzy commented Aug 27, 2013

yes, llvm patches are not merged to current llvm therefore still needed.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Aug 29, 2013
bors added a commit that referenced this pull request Aug 29, 2013
The LLVM update includes patches from #8488 by @klutzy to build llvm on mingw-64 and also to enable segmented stacks on that platform.

The libuv patch is a rebase on the now-current joyent/master in order to fix #8829
@klutzy klutzy mentioned this pull request Sep 4, 2013
flip1995 pushed a commit to flip1995/rust that referenced this pull request Mar 14, 2022
Move testing of cargo dev new_lint to cargo dev workflow

This should be placed there. No need to run this in PR CI, if clippy_dev
isn't touched. (It will be run by bors anyway)

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants