diff options
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/metadata.rs | 29 | ||||
| -rw-r--r-- | tests/run-make/issue-96498/Makefile | 8 | ||||
| -rw-r--r-- | tests/run-make/windows-safeseh/Makefile | 19 | ||||
| -rw-r--r-- | tests/run-make/windows-safeseh/bar.rs | 1 | ||||
| -rw-r--r-- | tests/run-make/windows-safeseh/baz.rs | 4 | ||||
| -rw-r--r-- | tests/run-make/windows-safeseh/foo.rs (renamed from tests/run-make/issue-96498/foo.rs) | 0 |
7 files changed, 55 insertions, 33 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index f16fe372a92..c0f6e7cb7b0 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1889,37 +1889,14 @@ fn add_linked_symbol_object( return; }; - // NOTE(nbdd0121): MSVC will hang if the input object file contains no sections, - // so add an empty section. if file.format() == object::BinaryFormat::Coff { + // NOTE(nbdd0121): MSVC will hang if the input object file contains no sections, + // so add an empty section. file.add_section(Vec::new(), ".text".into(), object::SectionKind::Text); // We handle the name decoration of COFF targets in `symbol_export.rs`, so disable the // default mangler in `object` crate. file.set_mangling(object::write::Mangling::None); - - // Add feature flags to the object file. On MSVC this is optional but LLD will complain if - // not present. - let mut feature = 0; - - if file.architecture() == object::Architecture::I386 { - // Indicate that all SEH handlers are registered in .sxdata section. - // We don't have generate any code, so we don't need .sxdata section but LLD still - // expects us to set this bit (see #96498). - // Reference: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format - feature |= 1; - } - - file.add_symbol(object::write::Symbol { - name: "@feat.00".into(), - value: feature, - size: 0, - kind: object::SymbolKind::Data, - scope: object::SymbolScope::Compilation, - weak: false, - section: object::write::SymbolSection::Absolute, - flags: object::SymbolFlags::None, - }); } for (sym, kind) in symbols.iter() { diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index c6f4bd35e29..cb60ed729c1 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -228,6 +228,35 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static if sess.target.is_like_osx { file.set_macho_build_version(macho_object_build_version_for_target(&sess.target)) } + if binary_format == BinaryFormat::Coff { + // Disable the default mangler to avoid mangling the special "@feat.00" symbol name. + let original_mangling = file.mangling(); + file.set_mangling(object::write::Mangling::None); + + let mut feature = 0; + + if file.architecture() == object::Architecture::I386 { + // When linking with /SAFESEH on x86, lld requires that all linker inputs be marked as + // safe exception handling compatible. Metadata files masquerade as regular COFF + // objects and are treated as linker inputs, despite containing no actual code. Thus, + // they still need to be marked as safe exception handling compatible. See #96498. + // Reference: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format + feature |= 1; + } + + file.add_symbol(object::write::Symbol { + name: "@feat.00".into(), + value: feature, + size: 0, + kind: object::SymbolKind::Data, + scope: object::SymbolScope::Compilation, + weak: false, + section: object::write::SymbolSection::Absolute, + flags: object::SymbolFlags::None, + }); + + file.set_mangling(original_mangling); + } let e_flags = match architecture { Architecture::Mips => { let arch = match sess.target.options.cpu.as_ref() { diff --git a/tests/run-make/issue-96498/Makefile b/tests/run-make/issue-96498/Makefile deleted file mode 100644 index efdd328c671..00000000000 --- a/tests/run-make/issue-96498/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# only-windows -# needs-rust-lld - -include ../tools.mk - -# Ensure that LLD can link -all: - $(RUSTC) -C linker=rust-lld foo.rs diff --git a/tests/run-make/windows-safeseh/Makefile b/tests/run-make/windows-safeseh/Makefile new file mode 100644 index 00000000000..d6a403961d7 --- /dev/null +++ b/tests/run-make/windows-safeseh/Makefile @@ -0,0 +1,19 @@ +# only-windows +# needs-rust-lld + +include ../tools.mk + +all: foo bar + +# Ensure that LLD can link when an .rlib contains a synthetic object +# file referencing exported or used symbols. +foo: + $(RUSTC) -C linker=rust-lld foo.rs + +# Ensure that LLD can link when /WHOLEARCHIVE: is used with an .rlib. +# Previously, lib.rmeta was not marked as (trivially) SAFESEH-aware. +bar: baz + $(RUSTC) -C linker=rust-lld -C link-arg=/WHOLEARCHIVE:libbaz.rlib bar.rs + +baz: + $(RUSTC) baz.rs diff --git a/tests/run-make/windows-safeseh/bar.rs b/tests/run-make/windows-safeseh/bar.rs new file mode 100644 index 00000000000..f328e4d9d04 --- /dev/null +++ b/tests/run-make/windows-safeseh/bar.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/run-make/windows-safeseh/baz.rs b/tests/run-make/windows-safeseh/baz.rs new file mode 100644 index 00000000000..8d5b9dc5aea --- /dev/null +++ b/tests/run-make/windows-safeseh/baz.rs @@ -0,0 +1,4 @@ +#![crate_type = "rlib"] + +#[no_mangle] +extern "C" fn baz() {} diff --git a/tests/run-make/issue-96498/foo.rs b/tests/run-make/windows-safeseh/foo.rs index 93ac3641b09..93ac3641b09 100644 --- a/tests/run-make/issue-96498/foo.rs +++ b/tests/run-make/windows-safeseh/foo.rs |
