From 014ec7b3c81d141b6c62f34c017aee06bbd29ebe Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 27 Nov 2019 04:59:56 +0000 Subject: [PATCH 1/5] Add XP target Adds explicit targets for Windows XP. --- .../spec/i686_xp_windows_msvc.rs | 31 +++++++++++++++++++ src/librustc_target/spec/mod.rs | 2 ++ .../spec/x86_64_xp_windows_msvc.rs | 22 +++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 src/librustc_target/spec/i686_xp_windows_msvc.rs create mode 100644 src/librustc_target/spec/x86_64_xp_windows_msvc.rs diff --git a/src/librustc_target/spec/i686_xp_windows_msvc.rs b/src/librustc_target/spec/i686_xp_windows_msvc.rs new file mode 100644 index 0000000000000..c8cc5bd38ad39 --- /dev/null +++ b/src/librustc_target/spec/i686_xp_windows_msvc.rs @@ -0,0 +1,31 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::windows_msvc_base::opts(); + base.cpu = "pentium4".to_string(); + base.max_atomic_width = Some(64); + + // Mark all dynamic libraries and executables as compatible with the larger 4GiB address + // space available to x86 Windows binaries on x86_64. + base.pre_link_args + .get_mut(&LinkerFlavor::Msvc).unwrap().push("/LARGEADDRESSAWARE".to_string()); + + // Ensure the linker will only produce an image if it can also produce a table of + // the image's safe exception handlers. + // https://msdn.microsoft.com/en-us/library/9a89h429.aspx + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/SAFESEH".to_string()); + + Ok(Target { + llvm_target: "i686-pc-windows-msvc".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(), + arch: "x86".to_string(), + target_os: "windows".to_string(), + target_env: "msvc".to_string(), + target_vendor: "xp".to_string(), + linker_flavor: LinkerFlavor::Msvc, + options: base, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index f08634cc770e0..6110659f85c0d 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -454,8 +454,10 @@ supported_targets! { ("aarch64-uwp-windows-msvc", aarch64_uwp_windows_msvc), ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc), ("x86_64-uwp-windows-msvc", x86_64_uwp_windows_msvc), + ("x86_64-xp-windows-msvc", x86_64_xp_windows_msvc), ("i686-pc-windows-msvc", i686_pc_windows_msvc), ("i686-uwp-windows-msvc", i686_uwp_windows_msvc), + ("i686-xp-windows-msvc", i686_xp_windows_msvc), ("i586-pc-windows-msvc", i586_pc_windows_msvc), ("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc), diff --git a/src/librustc_target/spec/x86_64_xp_windows_msvc.rs b/src/librustc_target/spec/x86_64_xp_windows_msvc.rs new file mode 100644 index 0000000000000..0a8a296df3a61 --- /dev/null +++ b/src/librustc_target/spec/x86_64_xp_windows_msvc.rs @@ -0,0 +1,22 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::windows_msvc_base::opts(); + base.cpu = "x86-64".to_string(); + base.max_atomic_width = Some(64); + base.has_elf_tls = true; + + Ok(Target { + llvm_target: "x86_64-pc-windows-msvc".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(), + arch: "x86_64".to_string(), + target_os: "windows".to_string(), + target_env: "msvc".to_string(), + target_vendor: "xp".to_string(), + linker_flavor: LinkerFlavor::Msvc, + options: base, + }) +} From 544b08ab3b450152bc863aa242efff1ae1d4f761 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 27 Nov 2019 08:34:11 +0000 Subject: [PATCH 2/5] Set XP subsystem version appropriately XP requires an older subsystem to be used than is the default. --- src/librustc_codegen_ssa/back/linker.rs | 2 +- src/librustc_codegen_ssa/back/write.rs | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index a3e60f861996a..081e1f3ceb258 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -743,7 +743,7 @@ impl<'a> Linker for MsvcLinker<'a> { // correctly. // // For more information see RFC #1665 - if subsystem == "windows" { + if subsystem.starts_with("windows") { self.cmd.arg("/ENTRY:mainCRTStartup"); } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index a5a90980c3a23..3b8399dc1dade 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -347,7 +347,21 @@ pub fn start_async_codegen( subsystem )); } - subsystem.to_string() + let t = &sess.target.target; + if t.target_vendor == "xp" { + // For Windows XP the subsystem version needs to be set appropriately. + let version = match t.arch.as_str() { + "x86" => "5.01", + "x86_64" => "5.02", + arch => tcx.sess.fatal(&format!("invalid Windows XP arch `{}`, only \ + `x86` and `x86_64` are supported", + arch)) + }; + format!("{},{}", subsystem, version) + } + else { + subsystem.to_string() + } }); let linker_info = LinkerInfo::new(tcx); From 37b1c0a572fa09e76e8fd7829f2886f28e69fa98 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 27 Nov 2019 08:38:28 +0000 Subject: [PATCH 3/5] Revert "Set XP subsystem version appropriately" This reverts commit 3f8c0da415824be941292981ea40f115a94f0d97. --- src/librustc_codegen_ssa/back/linker.rs | 2 +- src/librustc_codegen_ssa/back/write.rs | 16 +--------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 081e1f3ceb258..a3e60f861996a 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -743,7 +743,7 @@ impl<'a> Linker for MsvcLinker<'a> { // correctly. // // For more information see RFC #1665 - if subsystem.starts_with("windows") { + if subsystem == "windows" { self.cmd.arg("/ENTRY:mainCRTStartup"); } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 3b8399dc1dade..a5a90980c3a23 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -347,21 +347,7 @@ pub fn start_async_codegen( subsystem )); } - let t = &sess.target.target; - if t.target_vendor == "xp" { - // For Windows XP the subsystem version needs to be set appropriately. - let version = match t.arch.as_str() { - "x86" => "5.01", - "x86_64" => "5.02", - arch => tcx.sess.fatal(&format!("invalid Windows XP arch `{}`, only \ - `x86` and `x86_64` are supported", - arch)) - }; - format!("{},{}", subsystem, version) - } - else { - subsystem.to_string() - } + subsystem.to_string() }); let linker_info = LinkerInfo::new(tcx); From 37dc7baa55babfa2504baf8e69f3e8b6526033da Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 27 Nov 2019 12:32:58 +0000 Subject: [PATCH 4/5] Set XP subsystem version XP requires an older subsystem to be used than is the default. To support this, an optional version parameter has been added to the Linker `subsystem` function and a WindowsSubsystem struct to CodegenResults. --- src/librustc_codegen_ssa/back/link.rs | 3 +- src/librustc_codegen_ssa/back/linker.rs | 24 ++++++++++----- src/librustc_codegen_ssa/back/write.rs | 39 ++++++++++++++++++------- src/librustc_codegen_ssa/lib.rs | 8 ++++- 4 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index f3420f9a9f9fd..2d41279147ca6 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1109,7 +1109,8 @@ fn link_args<'a, B: ArchiveBuilder<'a>>( if crate_type == config::CrateType::Executable && sess.target.target.options.is_like_windows { if let Some(ref s) = codegen_results.windows_subsystem { - cmd.subsystem(s); + let version = s.version.as_ref().map(|v| &**v); + cmd.subsystem(&s.name, version); } } diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index a3e60f861996a..bb9dc285c5706 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -111,7 +111,7 @@ pub trait Linker { fn build_static_executable(&mut self); fn args(&mut self, args: &[String]); fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType); - fn subsystem(&mut self, subsystem: &str); + fn subsystem(&mut self, subsystem: &str, version: Option<&str>); fn group_start(&mut self); fn group_end(&mut self); fn linker_plugin_lto(&mut self); @@ -494,9 +494,13 @@ impl<'a> Linker for GccLinker<'a> { self.cmd.arg(arg); } - fn subsystem(&mut self, subsystem: &str) { + fn subsystem(&mut self, subsystem: &str, version: Option<&str>) { self.linker_arg("--subsystem"); - self.linker_arg(&subsystem); + if let Some(ver) = version { + self.linker_arg(&format!("{}:{}", subsystem, ver)); + } else { + self.linker_arg(&subsystem); + } } fn finalize(&mut self) -> Command { @@ -724,10 +728,14 @@ impl<'a> Linker for MsvcLinker<'a> { self.cmd.arg(&arg); } - fn subsystem(&mut self, subsystem: &str) { + fn subsystem(&mut self, subsystem: &str, version: Option<&str>) { // Note that previous passes of the compiler validated this subsystem, // so we just blindly pass it to the linker. - self.cmd.arg(&format!("/SUBSYSTEM:{}", subsystem)); + let arg = match version { + Some(ver) => format!("/SUBSYSTEM:{},{}", subsystem, ver), + None => format!("/SUBSYSTEM:{}", subsystem), + }; + self.cmd.arg(&arg); // Windows has two subsystems we're interested in right now, the console // and windows subsystems. These both implicitly have different entry @@ -910,7 +918,7 @@ impl<'a> Linker for EmLinker<'a> { self.cmd.arg(arg); } - fn subsystem(&mut self, _subsystem: &str) { + fn subsystem(&mut self, _subsystem: &str, _version: Option<&str>) { // noop } @@ -1076,7 +1084,7 @@ impl<'a> Linker for WasmLd<'a> { self.cmd.arg("--export=__data_end"); } - fn subsystem(&mut self, _subsystem: &str) {} + fn subsystem(&mut self, _subsystem: &str, _version: Option<&str>) {} fn no_position_independent_executable(&mut self) {} @@ -1237,7 +1245,7 @@ impl<'a> Linker for PtxLinker<'a> { fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) {} - fn subsystem(&mut self, _subsystem: &str) {} + fn subsystem(&mut self, _subsystem: &str, _version: Option<&str>) {} fn no_position_independent_executable(&mut self) {} diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index a5a90980c3a23..98443fba60076 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -5,7 +5,7 @@ use super::lto::{self, SerializedModule}; use super::symbol_export::ExportedSymbols; use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, - RLIB_BYTECODE_EXTENSION, + RLIB_BYTECODE_EXTENSION, WindowsSubsystem }; use crate::traits::*; @@ -339,16 +339,33 @@ pub fn start_async_codegen( let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, sym::no_builtins); let subsystem = attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs, sym::windows_subsystem); - let windows_subsystem = subsystem.map(|subsystem| { - if subsystem != sym::windows && subsystem != sym::console { - tcx.sess.fatal(&format!( - "invalid windows subsystem `{}`, only \ - `windows` and `console` are allowed", - subsystem - )); + let windows_subsystem = { + let name = subsystem.map(|subsystem| { + if subsystem != sym::windows && subsystem != sym::console { + tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \ + `windows` and `console` are allowed", + subsystem)); + } + subsystem.to_string() + }); + let t = &sess.target.target; + if t.target_vendor == "xp" && t.target_os == "windows" { + // For Windows XP the subsystem version needs to be set. + let name = name.unwrap_or("console".to_string()); + let version = match t.arch.as_str() { + "x86" => Some("5.01".to_string()), + "x86_64" => Some("5.02".to_string()), + arch => tcx.sess.fatal(&format!("invalid Windows XP arch `{}`, only \ + `x86` and `x86_64` are supported", + arch)) + }; + Some(WindowsSubsystem { name, version }) + } else { + name.and_then(|name| Some(WindowsSubsystem { + name, version: None + })) } - subsystem.to_string() - }); + }; let linker_info = LinkerInfo::new(tcx); let crate_info = CrateInfo::new(tcx); @@ -1716,7 +1733,7 @@ pub struct OngoingCodegen { pub crate_name: Symbol, pub crate_hash: Svh, pub metadata: EncodedMetadata, - pub windows_subsystem: Option, + pub windows_subsystem: Option, pub linker_info: LinkerInfo, pub crate_info: CrateInfo, pub coordinator_send: Sender>, diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 02385bdab7b19..0c027a4b86cf2 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -138,6 +138,12 @@ pub struct CrateInfo { pub dependency_formats: Lrc, } +#[derive(Debug)] +pub struct WindowsSubsystem { + pub name: String, + pub version: Option +} + pub struct CodegenResults { pub crate_name: Symbol, pub modules: Vec, @@ -145,7 +151,7 @@ pub struct CodegenResults { pub metadata_module: Option, pub crate_hash: Svh, pub metadata: rustc::middle::cstore::EncodedMetadata, - pub windows_subsystem: Option, + pub windows_subsystem: Option, pub linker_info: back::linker::LinkerInfo, pub crate_info: CrateInfo, } From beca35a4a312a55cad685bea1805b7efe8f9f34f Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 23 Dec 2019 12:48:18 +0000 Subject: [PATCH 5/5] Fixed for new format rules --- src/librustc_codegen_ssa/back/write.rs | 22 ++++++++++--------- src/librustc_codegen_ssa/lib.rs | 2 +- .../spec/i686_xp_windows_msvc.rs | 3 +-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 98443fba60076..433f9cb3cb6b7 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -5,7 +5,7 @@ use super::lto::{self, SerializedModule}; use super::symbol_export::ExportedSymbols; use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, - RLIB_BYTECODE_EXTENSION, WindowsSubsystem + WindowsSubsystem, RLIB_BYTECODE_EXTENSION, }; use crate::traits::*; @@ -342,9 +342,11 @@ pub fn start_async_codegen( let windows_subsystem = { let name = subsystem.map(|subsystem| { if subsystem != sym::windows && subsystem != sym::console { - tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \ - `windows` and `console` are allowed", - subsystem)); + tcx.sess.fatal(&format!( + "invalid windows subsystem `{}`, only \ + `windows` and `console` are allowed", + subsystem + )); } subsystem.to_string() }); @@ -355,15 +357,15 @@ pub fn start_async_codegen( let version = match t.arch.as_str() { "x86" => Some("5.01".to_string()), "x86_64" => Some("5.02".to_string()), - arch => tcx.sess.fatal(&format!("invalid Windows XP arch `{}`, only \ - `x86` and `x86_64` are supported", - arch)) + arch => tcx.sess.fatal(&format!( + "invalid Windows XP arch `{}`, only \ + `x86` and `x86_64` are supported", + arch + )), }; Some(WindowsSubsystem { name, version }) } else { - name.and_then(|name| Some(WindowsSubsystem { - name, version: None - })) + name.and_then(|name| Some(WindowsSubsystem { name, version: None })) } }; diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 0c027a4b86cf2..3321a2a6f239b 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -141,7 +141,7 @@ pub struct CrateInfo { #[derive(Debug)] pub struct WindowsSubsystem { pub name: String, - pub version: Option + pub version: Option, } pub struct CodegenResults { diff --git a/src/librustc_target/spec/i686_xp_windows_msvc.rs b/src/librustc_target/spec/i686_xp_windows_msvc.rs index c8cc5bd38ad39..89356abdcdc58 100644 --- a/src/librustc_target/spec/i686_xp_windows_msvc.rs +++ b/src/librustc_target/spec/i686_xp_windows_msvc.rs @@ -7,8 +7,7 @@ pub fn target() -> TargetResult { // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. - base.pre_link_args - .get_mut(&LinkerFlavor::Msvc).unwrap().push("/LARGEADDRESSAWARE".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/LARGEADDRESSAWARE".to_string()); // Ensure the linker will only produce an image if it can also produce a table of // the image's safe exception handlers.