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

Add Games MSVC targets #67745

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/librustc_codegen_ssa/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,10 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
// UWP apps have API restrictions enforced during Store submissions.
// To comply with the Windows App Certification Kit,
// MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc).
// Similarly, apps targeting the Games API partition need to link to the OneCore versions of
Copy link
Contributor Author

@jblazquez jblazquez Dec 31, 2019

Choose a reason for hiding this comment

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

// the runtime to ensure they don't use functions that are unavailable in that partition.
let t = &sess.target.target;
if flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" {
if flavor == LinkerFlavor::Msvc && (t.target_vendor == "uwp" || t.target_vendor == "games") {
if let Some(ref tool) = msvc_tool {
let original_path = tool.path();
if let Some(ref root_lib_path) = original_path.ancestors().skip(4).next() {
Expand All @@ -187,7 +189,19 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
};
if let Some(ref a) = arch {
let mut arg = OsString::from("/LIBPATH:");
arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a.to_string()));
if t.target_vendor == "uwp" {
arg.push(format!(
"{}\\lib\\{}\\store",
root_lib_path.display(),
a.to_string()
));
} else {
arg.push(format!(
"{}\\lib\\onecore\\{}",
root_lib_path.display(),
a.to_string()
));
}
cmd.arg(&arg);
} else {
warn!("arch is not supported");
Expand Down
25 changes: 25 additions & 0 deletions src/librustc_target/spec/aarch64_games_windows_msvc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetResult};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copied from aarch64_pc_windows_msvc with s/pc/games/


pub fn target() -> TargetResult {
let mut base = super::windows_games_msvc_base::opts();
base.max_atomic_width = Some(64);
base.has_elf_tls = true;
base.features = "+neon,+fp-armv8".to_string();

// FIXME: this shouldn't be panic=abort, it should be panic=unwind
Copy link
Contributor Author

Choose a reason for hiding this comment

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

base.panic_strategy = PanicStrategy::Abort;

Ok(Target {
llvm_target: "aarch64-games-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-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
target_os: "windows".to_string(),
target_env: "msvc".to_string(),
target_vendor: "games".to_string(),
linker_flavor: LinkerFlavor::Msvc,
options: base,
})
}
31 changes: 31 additions & 0 deletions src/librustc_target/spec/i686_games_windows_msvc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Like above, copied from i686_pc_windows_msvc with pc replaced with games.


pub fn target() -> TargetResult {
let mut base = super::windows_games_msvc_base::opts();
base.cpu = "pentium4".to_string();
base.max_atomic_width = Some(64);
base.has_elf_tls = true;

// 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://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/SAFESEH".to_string());

Ok(Target {
llvm_target: "i686-games-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: "games".to_string(),
linker_flavor: LinkerFlavor::Msvc,
options: base,
})
}
4 changes: 4 additions & 0 deletions src/librustc_target/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ mod uefi_base;
mod vxworks_base;
mod wasm32_base;
mod windows_base;
mod windows_games_msvc_base;
mod windows_msvc_base;
mod windows_uwp_base;
mod windows_uwp_msvc_base;
Expand Down Expand Up @@ -452,10 +453,13 @@ supported_targets! {

("aarch64-pc-windows-msvc", aarch64_pc_windows_msvc),
("aarch64-uwp-windows-msvc", aarch64_uwp_windows_msvc),
("aarch64-games-windows-msvc", aarch64_games_windows_msvc),
("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc),
("x86_64-uwp-windows-msvc", x86_64_uwp_windows_msvc),
("x86_64-games-windows-msvc", x86_64_games_windows_msvc),
("i686-pc-windows-msvc", i686_pc_windows_msvc),
("i686-uwp-windows-msvc", i686_uwp_windows_msvc),
("i686-games-windows-msvc", i686_games_windows_msvc),
("i586-pc-windows-msvc", i586_pc_windows_msvc),
("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc),

Expand Down
36 changes: 36 additions & 0 deletions src/librustc_target/spec/windows_games_msvc_base.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Similar to windows_uwp_msvc_base.rs except that we link against onecore.lib instead of mincore.lib.

mincore.lib is a Windows 8 umbrella library, whereas onecore.lib is a Windows 10 library. Since the games partition is new to Windows 10 it made sense to use the newer umbrella library.

See here for more info on umbrella libraries: https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-umbrella-libraries

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can add the above as a comment in code if it would be useful.

use std::default::Default;

pub fn opts() -> TargetOptions {
let mut args = LinkArgs::new();
args.insert(
LinkerFlavor::Msvc,
vec!["/NOLOGO".to_string(), "/NXCOMPAT".to_string(), "onecore.lib".to_string()],
);

TargetOptions {
function_sections: true,
dynamic_linking: true,
executables: true,
dll_prefix: String::new(),
dll_suffix: ".dll".to_string(),
exe_suffix: ".exe".to_string(),
staticlib_prefix: String::new(),
staticlib_suffix: ".lib".to_string(),
target_family: Some("windows".to_string()),
is_like_windows: true,
is_like_msvc: true,
// set VSLANG to 1033 can prevent link.exe from using
// language packs, and avoid generating Non-UTF-8 error
// messages if a link error occurred.
link_env: vec![("VSLANG".to_string(), "1033".to_string())],
pre_link_args: args,
crt_static_allows_dylibs: true,
crt_static_respected: true,
abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false,
requires_uwtable: true,

..Default::default()
}
}
22 changes: 22 additions & 0 deletions src/librustc_target/spec/x86_64_games_windows_msvc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copied from x86_64_pc_windows_msvc with s/pc/games


pub fn target() -> TargetResult {
let mut base = super::windows_games_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-games-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: "games".to_string(),
linker_flavor: LinkerFlavor::Msvc,
options: base,
})
}
53 changes: 34 additions & 19 deletions src/libstd/sys/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,6 @@ pub const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
pub const SYMLINK_FLAG_RELATIVE: DWORD = 0x00000001;
pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;

pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;

// Note that these are not actually HANDLEs, just values to pass to GetStdHandle
pub const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD;
pub const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
Expand Down Expand Up @@ -638,6 +635,34 @@ if #[cfg(not(target_vendor = "uwp"))] {
pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;

pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
Copy link
Contributor Author

@jblazquez jblazquez Dec 31, 2019

Choose a reason for hiding this comment

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

These 4 items simply moved up a little bit in the file because other items moved out. These are still forbidden when targeting UWP, but are available for Games.


extern "system" {
pub fn SetHandleInformation(hObject: HANDLE,
dwMask: DWORD,
dwFlags: DWORD) -> BOOL;
pub fn AddVectoredExceptionHandler(FirstHandler: ULONG,
VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
-> LPVOID;
pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR,
lpTargetFileName: LPCWSTR,
lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
-> BOOL;
}
}
}

// Functions forbidden when targeting the Games API partition
cfg_if::cfg_if! {
if #[cfg(not(target_vendor = "games"))] {
pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
Copy link
Contributor Author

@jblazquez jblazquez Dec 31, 2019

Choose a reason for hiding this comment

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

According to the Windows SDK headers, symbolic links are only supported on desktop apps and drivers (not UWP or games):

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)

#define SYMBOLIC_LINK_FLAG_DIRECTORY                    (0x1)
#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE    (0x2)

The MSDN docs agree (they say [desktop apps only] at the bottom instead of [desktop apps | UWP apps])

So I think these should be also compiled out for target_vendor = "uwp", but they weren't before for some reason. I can merge this with the block below if you think I should do that.

pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
}
}

// Functions forbidden when targeting UWP or the Games API partition
cfg_if::cfg_if! {
if #[cfg(not(any(target_vendor = "uwp", target_vendor = "games")))] {
#[repr(C)]
#[derive(Copy, Clone)]
pub struct CONSOLE_READCONSOLE_CONTROL {
Copy link
Contributor Author

@jblazquez jblazquez Dec 31, 2019

Choose a reason for hiding this comment

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

Console stuff is also unavailable in Games (a little ironic...)

Expand Down Expand Up @@ -666,8 +691,6 @@ if #[cfg(not(target_vendor = "uwp"))] {
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
pub type LPCVOID = *const c_void;

pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;

pub const TOKEN_READ: DWORD = 0x20008;

extern "system" {
Expand All @@ -688,33 +711,24 @@ if #[cfg(not(target_vendor = "uwp"))] {

pub fn GetConsoleMode(hConsoleHandle: HANDLE,
lpMode: LPDWORD) -> BOOL;
// Allowed but unused by UWP
// Allowed but unused by UWP and Games
pub fn OpenProcessToken(ProcessHandle: HANDLE,
DesiredAccess: DWORD,
TokenHandle: *mut HANDLE) -> BOOL;
pub fn GetUserProfileDirectoryW(hToken: HANDLE,
lpProfileDir: LPWSTR,
lpcchSize: *mut DWORD) -> BOOL;
// Allowed but unused by Games
pub fn GetFileInformationByHandle(hFile: HANDLE,
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
-> BOOL;
pub fn SetHandleInformation(hObject: HANDLE,
dwMask: DWORD,
dwFlags: DWORD) -> BOOL;
pub fn AddVectoredExceptionHandler(FirstHandler: ULONG,
VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
-> LPVOID;
pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR,
lpTargetFileName: LPCWSTR,
lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
-> BOOL;
}
}
}

// UWP specific functions & types
// UWP and Games specific functions & types
cfg_if::cfg_if! {
if #[cfg(target_vendor = "uwp")] {
if #[cfg(any(target_vendor = "uwp", target_vendor = "games"))] {
pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;

#[repr(C)]
Expand All @@ -732,7 +746,7 @@ if #[cfg(target_vendor = "uwp")] {
lpFileInformation: LPVOID,
dwBufferSize: DWORD) -> BOOL;
pub fn BCryptGenRandom(hAlgorithm: LPVOID, pBuffer: *mut u8,
cbBuffer: ULONG, dwFlags: ULONG) -> LONG;
cbBuffer: ULONG, dwFlags: ULONG) -> LONG;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure what happened here with whitespace but tidy didn't complain. I can fix on a later commit.

}
}
}
Expand Down Expand Up @@ -1019,6 +1033,7 @@ extern "system" {
compat_fn! {
kernel32:

#[cfg(not(target_vendor = "games"))]
pub fn CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR,
_lpTargetFileName: LPCWSTR,
_dwFlags: DWORD) -> BOOLEAN {
Expand Down
13 changes: 11 additions & 2 deletions src/libstd/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ impl File {
Ok(())
}

#[cfg(not(target_vendor = "uwp"))]
#[cfg(not(any(target_vendor = "uwp", target_vendor = "games")))]
pub fn file_attr(&self) -> io::Result<FileAttr> {
unsafe {
let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed();
Expand Down Expand Up @@ -350,7 +350,7 @@ impl File {
}
}

#[cfg(target_vendor = "uwp")]
#[cfg(any(target_vendor = "uwp", target_vendor = "games"))]
pub fn file_attr(&self) -> io::Result<FileAttr> {
unsafe {
let mut info: c::FILE_BASIC_INFO = mem::zeroed();
Expand Down Expand Up @@ -753,6 +753,7 @@ pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
symlink_inner(src, dst, false)
}

#[cfg(not(target_vendor = "games"))]
pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
let src = to_u16s(src)?;
let dst = to_u16s(dst)?;
Expand Down Expand Up @@ -780,6 +781,14 @@ pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
Ok(())
}

#[cfg(target_vendor = "games")]
pub fn symlink_inner(_: &Path, _: &Path, _: bool) -> io::Result<()> {
return Err(io::Error::new(
io::ErrorKind::Other,
"symbolic links are not supported on the Games API partition",
));
}

#[cfg(not(target_vendor = "uwp"))]
pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
let src = to_u16s(src)?;
Expand Down
12 changes: 8 additions & 4 deletions src/libstd/sys/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,18 @@ pub mod thread;
pub mod thread_local;
pub mod time;
cfg_if::cfg_if! {
if #[cfg(not(target_vendor = "uwp"))] {
pub mod stdio;
pub mod stack_overflow;
} else {
if #[cfg(target_vendor = "uwp")] {
pub mod stdio_uwp;
pub mod stack_overflow_uwp;
pub use self::stdio_uwp as stdio;
pub use self::stack_overflow_uwp as stack_overflow;
} else if #[cfg(target_vendor = "games")] {
pub mod stdio_uwp;
pub mod stack_overflow;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Vectored exception handling is available in Games (but not UWP).

pub use self::stdio_uwp as stdio;
} else {
pub mod stdio;
pub mod stack_overflow;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sys/windows/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ pub fn temp_dir() -> PathBuf {
super::fill_utf16_buf(|buf, sz| unsafe { c::GetTempPathW(sz, buf) }, super::os2path).unwrap()
}

#[cfg(not(target_vendor = "uwp"))]
#[cfg(not(any(target_vendor = "uwp", target_vendor = "games")))]
fn home_dir_crt() -> Option<PathBuf> {
unsafe {
use crate::sys::handle::Handle;
Expand All @@ -309,7 +309,7 @@ fn home_dir_crt() -> Option<PathBuf> {
}
}

#[cfg(target_vendor = "uwp")]
#[cfg(any(target_vendor = "uwp", target_vendor = "games"))]
fn home_dir_crt() -> Option<PathBuf> {
None
}
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sys/windows/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::io;
use crate::mem;
use crate::sys::c;

#[cfg(not(target_vendor = "uwp"))]
#[cfg(not(any(target_vendor = "uwp", target_vendor = "games")))]
pub fn hashmap_random_keys() -> (u64, u64) {
let mut v = (0, 0);
let ret =
Expand All @@ -13,7 +13,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
v
}

#[cfg(target_vendor = "uwp")]
#[cfg(any(target_vendor = "uwp", target_vendor = "games"))]
pub fn hashmap_random_keys() -> (u64, u64) {
use crate::ptr;

Expand Down