Skip to content

Commit

Permalink
Auto merge of rust-lang#130808 - checkraisefold:fix-questionmark-link…
Browse files Browse the repository at this point in the history
…ing, r=<try>

Fix linking for symbols starting with ? on i686-pc-windows-msvc

When using the `export_name` attribute to specifically export a symbol beginning with a question mark on the `i686-pc-windows-msvc` target, that symbol will fail to link and throw a linker error 100% of the time.
[Issue writeup.](rust-lang#44282 (comment))

Closes rust-lang#44282

I'm not sure if this is a proper solution, but [LLVM does the same check](https://github.com/llvm/llvm-project/blob/main/llvm/lib/IR/Mangler.cpp#L48-L49) which causes this issue, and is applied to [all 32- and 64-bit Windows COFF objects](https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/DataLayout.h#L255-L257) (maybe the same patch should be applied for 64 bit windows as well then?). I am *more* unsure of whether this is the proper place for such a solution (and if the exact conditions of is_like_windows are proper for this usecase), or if the underscore should be stripped elsewhere, but it seems like the most correct place.

I'm also unsure if there are any backwards compatibility ramifications here. There shouldn't be, because binaries with exported symbols starting with `?` for this target failed to link because of this issue anyway, but still.

 try-job: i686-mingw
  • Loading branch information
bors committed Jan 25, 2025
2 parents f940188 + 9c3b53d commit e53ded5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
}

let prefix = match &target.arch[..] {
"x86" | "x86_64" if target.is_like_msvc && undecorated.starts_with("?") => {
return undecorated;
}
"x86" => Some('_'),
"x86_64" => None,
"arm64ec" => Some('#'),
Expand Down
25 changes: 25 additions & 0 deletions tests/ui/symbol-names/symbol-with-question-mark-links.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This test ensures functions with an exported name beginning with a question mark
// successfully compile and link.
//
// Regression test for <https://github.com/rust-lang/rust/issues/44282>

//@ build-pass
//@ only-windows
//@ only-x86
// Reason: This test regards a linker issue which only applies to Windows.
// Specifically, it only occurs due to Windows x86 name decoration, combined with
// a mismatch between LLVM's decoration logic and Rust's (for `lib.def` generation)

#![crate_type = "cdylib"]

#[no_mangle]
pub extern "C" fn decorated(a: i32, b: i32) -> i32 {
1
}

// This isn't just `?undecorated` because MSVC's linker fails if the decorated
// symbol is not valid.
#[export_name = "?undecorated@@YAXXZ"]
pub extern "C" fn undecorated(a: i32, b: i32) -> i32 {
2
}

0 comments on commit e53ded5

Please sign in to comment.