Skip to content
Merged
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
74 changes: 74 additions & 0 deletions bootstrap.rust9x.gnu.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# See bootstrap.example.toml for documentation of available options
#
change-id = 148795

[llvm]
# Will download LLVM from CI if available on your platform.
download-ci-llvm = true
# NOTE: if you set ↑ to false, disable other LLVM targets to save lots of build time!
# targets = "X86"
# experimental-targets = ""

[build]
build = "x86_64-unknown-linux-gnu"
target = [
"x86_64-unknown-linux-gnu",
"x86_64-pc-windows-gnu",
"x86_64-rust9x-windows-gnu",
"i686-pc-windows-gnu",
"i686-rust9x-windows-gnu",
"i586-rust9x-windows-gnu",
]

docs = false

# extended = true
# tools = [
# # "cargo",
# # "clippy",
# "rustdoc",
# # "rustfmt",
# # "rust-analyzer",
# # "rust-analyzer-proc-macro-srv",
# # "analysis",
# "src",
# # "wasm-component-ld",
# # "miri", "cargo-miri" # for dev/nightly channels
# ]

[target.x86_64-pc-windows-gnu]
cc = "x86_64-w64-mingw32-gcc"
cxx = "x86_64-w64-mingw32-g++"

[target.x86_64-rust9x-windows-gnu]
cc = "x86_64-w64-mingw32-gcc"
cxx = "x86_64-w64-mingw32-g++"

[target.i686-pc-windows-gnu]
cc = "i686-w64-mingw32-gcc"
cxx = "i686-w64-mingw32-g++"

[target.i686-rust9x-windows-gnu]
cc = "i686-w64-mingw32-gcc"
cxx = "i686-w64-mingw32-g++"

[target.i586-rust9x-windows-gnu]
cc = "i686-w64-mingw32-gcc"
cxx = "i686-w64-mingw32-g++"

[install]
# for creating a downloadable package: python x.py install, then create and archive this
prefix = "../dist/rust9x-gnu"
sysconfdir = "."

[rust]
# enable rust-lld.exe so we don't need editbin.exe
lld = true
dist-src = false

# you can override this with -i/--incremental
# incremental = false
# incremental = true

[dist]
src-tarball = false
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1614,9 +1614,12 @@ supported_targets! {
("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu),
("x86_64-uwp-windows-gnu", x86_64_uwp_windows_gnu),
("x86_64-win7-windows-gnu", x86_64_win7_windows_gnu),
("x86_64-rust9x-windows-gnu", x86_64_rust9x_windows_gnu),
("i686-pc-windows-gnu", i686_pc_windows_gnu),
("i686-uwp-windows-gnu", i686_uwp_windows_gnu),
("i686-win7-windows-gnu", i686_win7_windows_gnu),
("i686-rust9x-windows-gnu", i686_rust9x_windows_gnu),
("i586-rust9x-windows-gnu", i586_rust9x_windows_gnu),

("aarch64-pc-windows-gnullvm", aarch64_pc_windows_gnullvm),
("i686-pc-windows-gnullvm", i686_pc_windows_gnullvm),
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_target/src/spec/targets/i586_rust9x_windows_gnu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::spec::Target;

pub(crate) fn target() -> Target {
let mut base = super::i686_rust9x_windows_gnu::target();
base.cpu = "i586".into();
base.llvm_target = "i586-pc-windows-gnu".into();
// go back to x87 FPU ABI spec
base.rustc_abi = None;
base
}
15 changes: 15 additions & 0 deletions compiler/rustc_target/src/spec/targets/i686_rust9x_windows_gnu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::spec::{Target, cvs};

pub(crate) fn target() -> Target {
let mut base = super::i686_pc_windows_gnu::target();
base.families = cvs!["windows", "rust9x"];

base.metadata = crate::spec::TargetMetadata {
description: Some("64-bit GNU rust9x (Windows XP 64-bit+)".into()),
tier: Some(4),
host_tools: Some(false),
std: Some(true),
};

base
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::spec::{Target, cvs};

pub(crate) fn target() -> Target {
let mut base = super::x86_64_pc_windows_gnu::target();
base.families = cvs!["windows", "rust9x"];

base.metadata = crate::spec::TargetMetadata {
description: Some("32-bit GNU rust9x (Windows 98/NT4+)".into()),
tier: Some(4),
host_tools: Some(false),
std: Some(true),
};

base
}
2 changes: 1 addition & 1 deletion library/std/src/sys/pal/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub const EXIT_FAILURE: u32 = 1;
pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() };
#[cfg(any(target_vendor = "win7", target_family = "rust9x"))]
pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() };
#[cfg(not(target_thread_local))]
#[cfg(all(not(target_thread_local), not(target_family = "rust9x")))]
pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() };

// Some windows_sys types have different signs than the types we use.
Expand Down
6 changes: 2 additions & 4 deletions library/std/src/sys/random/linux.rs
Comment thread
Jookia marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,8 @@ pub fn fill_bytes(bytes: &mut [u8]) {
getrandom(bytes, false);
}

pub fn hashmap_random_keys() -> (u64, u64) {
pub fn hashmap_random_keys() -> [u8; 16] {
let mut bytes = [0; 16];
getrandom(&mut bytes, true);
let k1 = u64::from_ne_bytes(bytes[..8].try_into().unwrap());
let k2 = u64::from_ne_bytes(bytes[8..].try_into().unwrap());
(k1, k2)
bytes
}
83 changes: 83 additions & 0 deletions library/std/src/sys/thread_local/key/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@
// FIXME: investigate using a fixed-size array instead, as the maximum number
// of keys is [limited to 1088](https://learn.microsoft.com/en-us/windows/win32/ProcThread/thread-local-storage).

#[cfg(not(target_family = "rust9x"))]
use crate::cell::UnsafeCell;
use crate::ptr;
use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
use crate::sync::atomic::{Atomic, AtomicPtr, AtomicU32};
#[cfg(target_family = "rust9x")]
use crate::sync::atomic::AtomicBool;
#[cfg(target_family = "rust9x")]
use crate::sync::nonpoison::Mutex;
use crate::sys::c;
use crate::sys::thread_local::guard;

Expand All @@ -44,7 +49,12 @@ pub struct LazyKey {
/// Currently, destructors cannot be unregistered, so we cannot use racy
/// initialization for keys. Instead, we need synchronize initialization.
/// Use the Windows-provided `Once` since it does not require TLS.
#[cfg(not(target_family = "rust9x"))]
once: UnsafeCell<c::INIT_ONCE>,
#[cfg(target_family = "rust9x")]
pending: AtomicBool,
#[cfg(target_family = "rust9x")]
initing: Mutex<()>,
}

impl LazyKey {
Expand All @@ -54,7 +64,12 @@ impl LazyKey {
key: AtomicU32::new(0),
dtor,
next: AtomicPtr::new(ptr::null_mut()),
#[cfg(not(target_family = "rust9x"))]
once: UnsafeCell::new(c::INIT_ONCE_STATIC_INIT),
#[cfg(target_family = "rust9x")]
pending: AtomicBool::new(true),
#[cfg(target_family = "rust9x")]
initing: Mutex::new(()),
}
}

Expand All @@ -67,6 +82,7 @@ impl LazyKey {
}

#[cold]
#[cfg(not(target_family = "rust9x"))]
unsafe fn init(&'static self) -> Key {
if self.dtor.is_some() {
let mut pending = c::FALSE;
Expand Down Expand Up @@ -123,6 +139,73 @@ impl LazyKey {
}
}
}

#[cold]
#[cfg(target_family = "rust9x")]
unsafe fn init(&'static self) -> Key {
if self.dtor.is_some() {
let pending = self.pending.load(Acquire);
if pending == false {
Comment on lines +147 to +148

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: could store initialized instead, preventing the inverted logic here (and have the initial state be zero instead of 1)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I kind of wanted to match the the logic from the other code but yeah I can update this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ah i see, that makes sense -- std Once also seems to agree:

/// Initialization has completed and all future calls should finish immediately.
/// By choosing this state as the all-zero state the `is_completed` check can be
/// a bit faster on some platforms.
const COMPLETE: Primitive = 0;

am convinced, can stay as is ^^

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

also, if !pending would be better I guess?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It's a somewhat stylistic choice but I wanted to match the other functions pending == c::FALSE.

If it really matters I can do a PR for it.

// Some other thread initialized the key, load it.
// We can use Relaxed here because pending will ensure
// key has been initialized.
self.key.load(Relaxed) - 1
} else {
let _lock_guard = self.initing.lock();

// Multiple threads may have seen pending as true and
// tried to initialize it. We have the lock now,
// but we may not have the first to get it.
// Check if it was already initialized.
let pending2 = self.pending.load(Acquire);
if pending2 == false {
return self.key.load(Relaxed) - 1;
}

let key = unsafe { c::TlsAlloc() };
if key == c::TLS_OUT_OF_INDEXES {
// Since we abort the process, there is no need to wake up
// the waiting threads. If this were a panic, the wakeup
// would need to occur first in order to avoid deadlock.
rtabort!("out of TLS indexes");
}

unsafe {
register_dtor(self);
}

// Store key with a Release to ensure loaders have
// access to our destructor.
self.key.store(key + 1, Release);

// Store pending with a release to ensure any pending
// loads see the key store value. This ensures we won't
// ever hit a situation of finding pending false and
// the key uninitialized.
self.pending.store(false, Release);

key
}
} else {
// If there is no destructor to clean up, we can use racy initialization.

let key = unsafe { c::TlsAlloc() };
if key == c::TLS_OUT_OF_INDEXES {
rtabort!("out of TLS indexes");
}

match self.key.compare_exchange(0, key + 1, AcqRel, Acquire) {
Ok(_) => key,
Err(new) => unsafe {
// Some other thread completed initialization first, so destroy
// our key and use theirs.
let r = c::TlsFree(key);
debug_assert_eq!(r, c::TRUE);
new - 1
},
}
}
}
}

unsafe impl Send for LazyKey {}
Expand Down
8 changes: 7 additions & 1 deletion src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,13 @@ impl Step for StartupObjects {
let src_file = &src_dir.join(file.to_string() + ".rs");
let dst_file = &dst_dir.join(file.to_string() + ".o");
if !up_to_date(src_file, dst_file) {
let mut cmd = command(&builder.initial_rustc);
let mut cmd = if target.contains("-rust9x-windows-gnu") {
// stage0 doesn't know about Rust9x targets, use a compiler
// we've built ourselves
builder.rustc_cmd(for_compiler)
} else {
command(&builder.initial_rustc)
};
cmd.env("RUSTC_BOOTSTRAP", "1");
if !builder.local_rebuild {
// a local_rebuild compiler already has stage1 features
Expand Down
13 changes: 8 additions & 5 deletions src/bootstrap/src/core/build_steps/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,12 @@ fn make_win_dist(plat_root: &Path, target: TargetSelection, builder: &Builder<'_

let (bin_path, lib_path) = get_cc_search_dirs(target, builder);

let compiler = if target == "i686-pc-windows-gnu" {
let compiler = if target == "i686-pc-windows-gnu" ||
target == "i686-rust9x-windows-gnu" ||
target == "i586-rust9x-windows-gnu" {
"i686-w64-mingw32-gcc.exe"
} else if target == "x86_64-pc-windows-gnu" {
} else if target == "x86_64-pc-windows-gnu" ||
target == "x86_64-rust9x-windows-gnu" {
"x86_64-w64-mingw32-gcc.exe"
} else {
"gcc.exe"
Expand Down Expand Up @@ -434,14 +437,14 @@ impl Step for Mingw {

fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
let target = self.target;
if !target.contains("pc-windows-gnu") || !builder.config.dist_include_mingw_linker {
if !target.contains("windows-gnu") || !builder.config.dist_include_mingw_linker {
return None;
}

let mut tarball = Tarball::new(builder, "rust-mingw", &target.triple);
tarball.set_product_name("Rust MinGW");

if target.ends_with("pc-windows-gnu") {
if target.ends_with("windows-gnu") {
make_win_dist(tarball.image_dir(), target, builder);
} else if target.ends_with("pc-windows-gnullvm") {
make_win_llvm_dist(tarball.image_dir(), target, builder);
Expand Down Expand Up @@ -506,7 +509,7 @@ impl Step for Rustc {
// anything requiring us to distribute a license, but it's likely the
// install will *also* include the rust-mingw package, which also needs
// licenses, so to be safe we just include it here in all MinGW packages.
if target.contains("pc-windows-gnu") && builder.config.dist_include_mingw_linker {
if target.contains("windows-gnu") && builder.config.dist_include_mingw_linker {
runtime_dll_dist(tarball.image_dir(), target, builder);
tarball.add_dir(builder.src.join("src/etc/third-party"), "share/doc");
}
Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[
"aarch64v8r-unknown-none-softfloat",
"s390x-unknown-none-softfloat",
"i586-rust9x-windows-msvc",
"i586-rust9x-windows-gnu",
"i686-rust9x-windows-msvc",
"i686-rust9x-windows-gnu",
"x86_64-rust9x-windows-msvc",
Comment thread
Jookia marked this conversation as resolved.
"x86_64-rust9x-windows-gnu",
];

/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
Expand Down
5 changes: 4 additions & 1 deletion src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,10 @@ impl Build {
// Work around an apparently bad MinGW / GCC optimization,
// See: https://lists.llvm.org/pipermail/cfe-dev/2016-December/051980.html
// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78936
if &*target.triple == "i686-pc-windows-gnu" {
if &*target.triple == "i686-pc-windows-gnu" ||
&*target.triple == "i586-rust9x-windows-gnu" ||
&*target.triple == "i686-rust9x-windows-gnu"
{
base.push("-fno-omit-frame-pointer".into());
}

Expand Down
6 changes: 2 additions & 4 deletions src/tools/build-manifest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,14 +288,12 @@ impl Builder {
}
// so is rust-mingw if it's available for the target
PkgType::RustMingw => {
if host.contains("pc-windows-gnu") {
if host.contains("windows-gnu") {
components.push(host_component(pkg));
extensions.extend(
TARGETS
.iter()
.filter(|&&target| {
target.contains("pc-windows-gnu") && target != host
})
.filter(|&&target| target.contains("windows-gnu") && target != host)
.map(|target| Component::from_pkg(pkg, target)),
);
}
Expand Down