From d450f7a605e896cc40c5cb759d736d298cb4d6e9 Mon Sep 17 00:00:00 2001 From: Mathieu Strypsteen Date: Fri, 10 Jan 2025 18:05:07 +0100 Subject: [PATCH] Add support for my OS --- .forgejo/workflows/build.yaml | 23 ++ .gitignore | 1 - compiler/rustc_target/src/spec/base/mod.rs | 1 + compiler/rustc_target/src/spec/base/os.rs | 15 + compiler/rustc_target/src/spec/mod.rs | 1 + .../src/spec/targets/x86_64_unknown_os.rs | 20 + config.toml | 10 + library/std/Cargo.toml | 2 +- library/std/build.rs | 1 + library/std/src/sys/alloc/mod.rs | 2 + library/std/src/sys/alloc/os.rs | 29 ++ library/std/src/sys/pal/mod.rs | 3 + library/std/src/sys/pal/osstd/args.rs | 36 ++ library/std/src/sys/pal/osstd/common.rs | 29 ++ library/std/src/sys/pal/osstd/env.rs | 9 + library/std/src/sys/pal/osstd/fs.rs | 324 +++++++++++++++ library/std/src/sys/pal/osstd/io.rs | 51 +++ library/std/src/sys/pal/osstd/mod.rs | 48 +++ library/std/src/sys/pal/osstd/net.rs | 369 ++++++++++++++++++ library/std/src/sys/pal/osstd/os.rs | 120 ++++++ library/std/src/sys/pal/osstd/pipe.rs | 56 +++ library/std/src/sys/pal/osstd/process.rs | 322 +++++++++++++++ library/std/src/sys/pal/osstd/stdio.rs | 59 +++ library/std/src/sys/pal/osstd/thread.rs | 36 ++ library/std/src/sys/pal/osstd/time.rs | 45 +++ library/std/src/sys/random/mod.rs | 2 + library/std/src/sys/thread_local/mod.rs | 2 + src/bootstrap/src/core/sanity.rs | 1 + src/bootstrap/src/lib.rs | 2 +- 29 files changed, 1616 insertions(+), 3 deletions(-) create mode 100644 .forgejo/workflows/build.yaml create mode 100644 compiler/rustc_target/src/spec/base/os.rs create mode 100644 compiler/rustc_target/src/spec/targets/x86_64_unknown_os.rs create mode 100644 config.toml create mode 100644 library/std/src/sys/alloc/os.rs create mode 100644 library/std/src/sys/pal/osstd/args.rs create mode 100644 library/std/src/sys/pal/osstd/common.rs create mode 100644 library/std/src/sys/pal/osstd/env.rs create mode 100644 library/std/src/sys/pal/osstd/fs.rs create mode 100644 library/std/src/sys/pal/osstd/io.rs create mode 100644 library/std/src/sys/pal/osstd/mod.rs create mode 100644 library/std/src/sys/pal/osstd/net.rs create mode 100644 library/std/src/sys/pal/osstd/os.rs create mode 100644 library/std/src/sys/pal/osstd/pipe.rs create mode 100644 library/std/src/sys/pal/osstd/process.rs create mode 100644 library/std/src/sys/pal/osstd/stdio.rs create mode 100644 library/std/src/sys/pal/osstd/thread.rs create mode 100644 library/std/src/sys/pal/osstd/time.rs diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml new file mode 100644 index 00000000000..ecd9cc1ac2d --- /dev/null +++ b/.forgejo/workflows/build.yaml @@ -0,0 +1,23 @@ +name: Build +on: [push] +jobs: + build: + runs-on: debian-12 + steps: + - name: Install dependencies + run: apt-get update && apt-get install -y python3 + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 100 + - name: Build + run: ./x.py build + - name: Remove symlinks + run: | + rm build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust + rm build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/rustc-src/rust + - name: Upload compiler + uses: forgejo/upload-artifact@v4 + with: + name: compiler.zip + path: build/x86_64-unknown-linux-gnu/stage2 diff --git a/.gitignore b/.gitignore index 948133cd76e..bcdcdd76174 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,6 @@ Session.vim !/tests/run-make/thumb-none-qemu/example/.cargo ## Configuration -/config.toml /Makefile config.mk config.stamp diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index 28d10dcf2ff..ad56dedd4d1 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -21,6 +21,7 @@ pub(crate) mod msvc; pub(crate) mod netbsd; pub(crate) mod nto_qnx; pub(crate) mod openbsd; +pub(crate) mod os; pub(crate) mod redox; pub(crate) mod solaris; pub(crate) mod solid; diff --git a/compiler/rustc_target/src/spec/base/os.rs b/compiler/rustc_target/src/spec/base/os.rs new file mode 100644 index 00000000000..ee9168b7b9c --- /dev/null +++ b/compiler/rustc_target/src/spec/base/os.rs @@ -0,0 +1,15 @@ +use crate::spec::{ + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, StackProbeType, TargetOptions, +}; + +pub(crate) fn opts() -> TargetOptions { + TargetOptions { + os: "os".into(), + linker: Some("rust-lld".into()), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + relocation_model: RelocModel::Static, + panic_strategy: PanicStrategy::Abort, + stack_probes: StackProbeType::Inline, + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 321ab40403a..23744ca7558 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1947,6 +1947,7 @@ supported_targets! { ("riscv32imafc-unknown-nuttx-elf", riscv32imafc_unknown_nuttx_elf), ("riscv64imac-unknown-nuttx-elf", riscv64imac_unknown_nuttx_elf), ("riscv64gc-unknown-nuttx-elf", riscv64gc_unknown_nuttx_elf), + ("x86_64-unknown-os", x86_64_unknown_os), } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_os.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_os.rs new file mode 100644 index 00000000000..d9d2cc8aaa7 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_os.rs @@ -0,0 +1,20 @@ +use crate::spec::{Target, TargetMetadata, base}; + +pub(crate) fn target() -> Target { + let mut base = base::os::opts(); + base.cpu = "x86-64-v2".into(); + Target { + llvm_target: "x86_64-unknown-none".into(), + metadata: TargetMetadata { + description: None, + tier: None, + host_tools: Some(false), + std: Some(true), + }, + pointer_width: 64, + arch: "x86_64".into(), + data_layout: + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), + options: base, + } +} diff --git a/config.toml b/config.toml new file mode 100644 index 00000000000..c71e5c4be1a --- /dev/null +++ b/config.toml @@ -0,0 +1,10 @@ +change-id = 131075 +profile = 'dist' + +[build] +host = ["x86_64-unknown-linux-gnu"] +target = ["x86_64-unknown-linux-gnu", "x86_64-unknown-os"] +extended = false + +[llvm] +download-ci-llvm = true diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index c1ab70b714a..cece9f7ffbe 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -145,5 +145,5 @@ check-cfg = [ # of declared features, we therefor expect any feature cfg 'cfg(feature, values(any()))', # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', + 'cfg(target_os, values("rtems", "os"))', ] diff --git a/library/std/build.rs b/library/std/build.rs index 8dc326a3dde..d314387016e 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -56,6 +56,7 @@ fn main() { || target_os == "zkvm" || target_os == "rtems" || target_os == "nuttx" + || target_os == "os" // See src/bootstrap/src/core/build_steps/synthetic_targets.rs || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok() diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs index 2c0b533a570..81c405a56c2 100644 --- a/library/std/src/sys/alloc/mod.rs +++ b/library/std/src/sys/alloc/mod.rs @@ -90,5 +90,7 @@ cfg_if::cfg_if! { mod xous; } else if #[cfg(target_os = "zkvm")] { mod zkvm; + } else if #[cfg(target_os = "os")] { + mod os; } } diff --git a/library/std/src/sys/alloc/os.rs b/library/std/src/sys/alloc/os.rs new file mode 100644 index 00000000000..9814961a69c --- /dev/null +++ b/library/std/src/sys/alloc/os.rs @@ -0,0 +1,29 @@ +use crate::{ + alloc::{GlobalAlloc, Layout, System}, + ptr, + sync::atomic::{AtomicUsize, Ordering}, +}; + +#[repr(align(16))] +struct HeapData([u8; 4 * 1024 * 1024]); + +static mut HEAP_DATA: HeapData = HeapData([0; 4 * 1024 * 1024]); +static HEAP_USED: AtomicUsize = AtomicUsize::new(0); + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.align() > 16 { + return ptr::null_mut(); + } + let num_blocks = + if layout.size() % 16 == 0 { layout.size() / 16 } else { (layout.size() / 16) + 1 }; + let heap_used = HEAP_USED.fetch_add(num_blocks, Ordering::SeqCst); + let ptr = unsafe { ptr::addr_of_mut!(HEAP_DATA.0[heap_used * 16]) as *mut u8 }; + ptr + } + + #[inline] + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index 9be018c8a53..adabbdae88b 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -61,6 +61,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "zkvm")] { mod zkvm; pub use self::zkvm::*; + } else if #[cfg(target_os = "os")] { + mod osstd; + pub use self::osstd::*; } else { mod unsupported; pub use self::unsupported::*; diff --git a/library/std/src/sys/pal/osstd/args.rs b/library/std/src/sys/pal/osstd/args.rs new file mode 100644 index 00000000000..a2d75a61976 --- /dev/null +++ b/library/std/src/sys/pal/osstd/args.rs @@ -0,0 +1,36 @@ +use crate::ffi::OsString; +use crate::fmt; + +pub struct Args {} + +pub fn args() -> Args { + Args {} +} + +impl fmt::Debug for Args { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_list().finish() + } +} + +impl Iterator for Args { + type Item = OsString; + fn next(&mut self) -> Option { + None + } + fn size_hint(&self) -> (usize, Option) { + (0, Some(0)) + } +} + +impl ExactSizeIterator for Args { + fn len(&self) -> usize { + 0 + } +} + +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + None + } +} diff --git a/library/std/src/sys/pal/osstd/common.rs b/library/std/src/sys/pal/osstd/common.rs new file mode 100644 index 00000000000..34a76668383 --- /dev/null +++ b/library/std/src/sys/pal/osstd/common.rs @@ -0,0 +1,29 @@ +use crate::io as std_io; + +// SAFETY: must be called only once during runtime initialization. +// NOTE: this is not guaranteed to run, for example when Rust code is called externally. +pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} + +// SAFETY: must be called only once during runtime cleanup. +// NOTE: this is not guaranteed to run, for example when the program aborts. +pub unsafe fn cleanup() {} + +pub fn unsupported() -> std_io::Result { + Err(unsupported_err()) +} + +pub fn unsupported_err() -> std_io::Error { + std_io::Error::UNSUPPORTED_PLATFORM +} + +pub fn is_interrupted(_code: i32) -> bool { + false +} + +pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { + crate::io::ErrorKind::Uncategorized +} + +pub fn abort_internal() -> ! { + core::intrinsics::abort(); +} diff --git a/library/std/src/sys/pal/osstd/env.rs b/library/std/src/sys/pal/osstd/env.rs new file mode 100644 index 00000000000..d2efec506c5 --- /dev/null +++ b/library/std/src/sys/pal/osstd/env.rs @@ -0,0 +1,9 @@ +pub mod os { + pub const FAMILY: &str = ""; + pub const OS: &str = ""; + pub const DLL_PREFIX: &str = ""; + pub const DLL_SUFFIX: &str = ""; + pub const DLL_EXTENSION: &str = ""; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} diff --git a/library/std/src/sys/pal/osstd/fs.rs b/library/std/src/sys/pal/osstd/fs.rs new file mode 100644 index 00000000000..474c9fe97d1 --- /dev/null +++ b/library/std/src/sys/pal/osstd/fs.rs @@ -0,0 +1,324 @@ +use crate::ffi::OsString; +use crate::fmt; +use crate::hash::{Hash, Hasher}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; +use crate::path::{Path, PathBuf}; +use crate::sys::time::SystemTime; +use crate::sys::unsupported; + +pub struct File(!); + +pub struct FileAttr(!); + +pub struct ReadDir(!); + +pub struct DirEntry(!); + +#[derive(Clone, Debug)] +pub struct OpenOptions {} + +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes {} + +pub struct FilePermissions(!); + +pub struct FileType(!); + +#[derive(Debug)] +pub struct DirBuilder {} + +impl FileAttr { + pub fn size(&self) -> u64 { + self.0 + } + + pub fn perm(&self) -> FilePermissions { + self.0 + } + + pub fn file_type(&self) -> FileType { + self.0 + } + + pub fn modified(&self) -> io::Result { + self.0 + } + + pub fn accessed(&self) -> io::Result { + self.0 + } + + pub fn created(&self) -> io::Result { + self.0 + } +} + +impl Clone for FileAttr { + fn clone(&self) -> FileAttr { + self.0 + } +} + +impl FilePermissions { + pub fn readonly(&self) -> bool { + self.0 + } + + pub fn set_readonly(&mut self, _readonly: bool) { + self.0 + } +} + +impl Clone for FilePermissions { + fn clone(&self) -> FilePermissions { + self.0 + } +} + +impl PartialEq for FilePermissions { + fn eq(&self, _other: &FilePermissions) -> bool { + self.0 + } +} + +impl Eq for FilePermissions {} + +impl fmt::Debug for FilePermissions { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +impl FileTimes { + pub fn set_accessed(&mut self, _t: SystemTime) {} + pub fn set_modified(&mut self, _t: SystemTime) {} +} + +impl FileType { + pub fn is_dir(&self) -> bool { + self.0 + } + + pub fn is_file(&self) -> bool { + self.0 + } + + pub fn is_symlink(&self) -> bool { + self.0 + } +} + +impl Clone for FileType { + fn clone(&self) -> FileType { + self.0 + } +} + +impl Copy for FileType {} + +impl PartialEq for FileType { + fn eq(&self, _other: &FileType) -> bool { + self.0 + } +} + +impl Eq for FileType {} + +impl Hash for FileType { + fn hash(&self, _h: &mut H) { + self.0 + } +} + +impl fmt::Debug for FileType { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +impl fmt::Debug for ReadDir { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +impl Iterator for ReadDir { + type Item = io::Result; + + fn next(&mut self) -> Option> { + self.0 + } +} + +impl DirEntry { + pub fn path(&self) -> PathBuf { + self.0 + } + + pub fn file_name(&self) -> OsString { + self.0 + } + + pub fn metadata(&self) -> io::Result { + self.0 + } + + pub fn file_type(&self) -> io::Result { + self.0 + } +} + +impl OpenOptions { + pub fn new() -> OpenOptions { + OpenOptions {} + } + + pub fn read(&mut self, _read: bool) {} + pub fn write(&mut self, _write: bool) {} + pub fn append(&mut self, _append: bool) {} + pub fn truncate(&mut self, _truncate: bool) {} + pub fn create(&mut self, _create: bool) {} + pub fn create_new(&mut self, _create_new: bool) {} +} + +impl File { + pub fn open(_path: &Path, _opts: &OpenOptions) -> io::Result { + unsupported() + } + + pub fn file_attr(&self) -> io::Result { + self.0 + } + + pub fn fsync(&self) -> io::Result<()> { + self.0 + } + + pub fn datasync(&self) -> io::Result<()> { + self.0 + } + + pub fn truncate(&self, _size: u64) -> io::Result<()> { + self.0 + } + + pub fn read(&self, _buf: &mut [u8]) -> io::Result { + self.0 + } + + pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.0 + } + + pub fn is_read_vectored(&self) -> bool { + self.0 + } + + pub fn read_buf(&self, _cursor: BorrowedCursor<'_>) -> io::Result<()> { + self.0 + } + + pub fn write(&self, _buf: &[u8]) -> io::Result { + self.0 + } + + pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result { + self.0 + } + + pub fn is_write_vectored(&self) -> bool { + self.0 + } + + pub fn flush(&self) -> io::Result<()> { + self.0 + } + + pub fn seek(&self, _pos: SeekFrom) -> io::Result { + self.0 + } + + pub fn duplicate(&self) -> io::Result { + self.0 + } + + pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { + self.0 + } + + pub fn set_times(&self, _times: FileTimes) -> io::Result<()> { + self.0 + } +} + +impl DirBuilder { + pub fn new() -> DirBuilder { + DirBuilder {} + } + + pub fn mkdir(&self, _p: &Path) -> io::Result<()> { + unsupported() + } +} + +impl fmt::Debug for File { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +pub fn readdir(_p: &Path) -> io::Result { + unsupported() +} + +pub fn unlink(_p: &Path) -> io::Result<()> { + unsupported() +} + +pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { + unsupported() +} + +pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> { + match perm.0 {} +} + +pub fn rmdir(_p: &Path) -> io::Result<()> { + unsupported() +} + +pub fn remove_dir_all(_path: &Path) -> io::Result<()> { + unsupported() +} + +pub fn exists(_path: &Path) -> io::Result { + unsupported() +} + +pub fn readlink(_p: &Path) -> io::Result { + unsupported() +} + +pub fn symlink(_original: &Path, _link: &Path) -> io::Result<()> { + unsupported() +} + +pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { + unsupported() +} + +pub fn stat(_p: &Path) -> io::Result { + unsupported() +} + +pub fn lstat(_p: &Path) -> io::Result { + unsupported() +} + +pub fn canonicalize(_p: &Path) -> io::Result { + unsupported() +} + +pub fn copy(_from: &Path, _to: &Path) -> io::Result { + unsupported() +} diff --git a/library/std/src/sys/pal/osstd/io.rs b/library/std/src/sys/pal/osstd/io.rs new file mode 100644 index 00000000000..6372fca74e0 --- /dev/null +++ b/library/std/src/sys/pal/osstd/io.rs @@ -0,0 +1,51 @@ +use crate::mem; + +#[derive(Copy, Clone)] +pub struct IoSlice<'a>(&'a [u8]); + +impl<'a> IoSlice<'a> { + #[inline] + pub fn new(buf: &'a [u8]) -> IoSlice<'a> { + IoSlice(buf) + } + + #[inline] + pub fn advance(&mut self, n: usize) { + self.0 = &self.0[n..] + } + + #[inline] + pub fn as_slice(&self) -> &[u8] { + self.0 + } +} + +pub struct IoSliceMut<'a>(&'a mut [u8]); + +impl<'a> IoSliceMut<'a> { + #[inline] + pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { + IoSliceMut(buf) + } + + #[inline] + pub fn advance(&mut self, n: usize) { + let slice = mem::take(&mut self.0); + let (_, remaining) = slice.split_at_mut(n); + self.0 = remaining; + } + + #[inline] + pub fn as_slice(&self) -> &[u8] { + self.0 + } + + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [u8] { + self.0 + } +} + +pub fn is_terminal(_: &T) -> bool { + false +} diff --git a/library/std/src/sys/pal/osstd/mod.rs b/library/std/src/sys/pal/osstd/mod.rs new file mode 100644 index 00000000000..17c99be88a8 --- /dev/null +++ b/library/std/src/sys/pal/osstd/mod.rs @@ -0,0 +1,48 @@ +#![deny(unsafe_op_in_unsafe_fn)] + +use core::arch::global_asm; + +pub mod args; +pub mod env; +pub mod fs; +pub mod io; +pub mod net; +pub mod os; +pub mod pipe; +pub mod process; +pub mod stdio; +pub mod thread; +pub mod time; + +mod common; +pub use common::*; + +global_asm!( + " +.text + +.global _start +_start: + mov $stack, %rsp + call main + mov $1, %rdi + mov %rax, %rsi + xor %rdx, %rdx + xor %rcx, %rcx + xor %r8, %r8 + xor %r9, %r9 + call _syscall + +.global _syscall +_syscall: + mov %rcx, %r10 + syscall + ret + +.section .bss +.align 16 +.skip 0x10000 +stack: +", + options(att_syntax) +); diff --git a/library/std/src/sys/pal/osstd/net.rs b/library/std/src/sys/pal/osstd/net.rs new file mode 100644 index 00000000000..87e6106468f --- /dev/null +++ b/library/std/src/sys/pal/osstd/net.rs @@ -0,0 +1,369 @@ +use crate::fmt; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; +use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; +use crate::sys::unsupported; +use crate::time::Duration; + +pub struct TcpStream(!); + +impl TcpStream { + pub fn connect(_: io::Result<&SocketAddr>) -> io::Result { + unsupported() + } + + pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result { + unsupported() + } + + pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { + self.0 + } + + pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { + self.0 + } + + pub fn read_timeout(&self) -> io::Result> { + self.0 + } + + pub fn write_timeout(&self) -> io::Result> { + self.0 + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result { + self.0 + } + + pub fn read(&self, _: &mut [u8]) -> io::Result { + self.0 + } + + pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> { + self.0 + } + + pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result { + self.0 + } + + pub fn is_read_vectored(&self) -> bool { + self.0 + } + + pub fn write(&self, _: &[u8]) -> io::Result { + self.0 + } + + pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result { + self.0 + } + + pub fn is_write_vectored(&self) -> bool { + self.0 + } + + pub fn peer_addr(&self) -> io::Result { + self.0 + } + + pub fn socket_addr(&self) -> io::Result { + self.0 + } + + pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { + self.0 + } + + pub fn duplicate(&self) -> io::Result { + self.0 + } + + pub fn set_linger(&self, _: Option) -> io::Result<()> { + self.0 + } + + pub fn linger(&self) -> io::Result> { + self.0 + } + + pub fn set_nodelay(&self, _: bool) -> io::Result<()> { + self.0 + } + + pub fn nodelay(&self) -> io::Result { + self.0 + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + self.0 + } + + pub fn ttl(&self) -> io::Result { + self.0 + } + + pub fn take_error(&self) -> io::Result> { + self.0 + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + self.0 + } +} + +impl fmt::Debug for TcpStream { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +pub struct TcpListener(!); + +impl TcpListener { + pub fn bind(_: io::Result<&SocketAddr>) -> io::Result { + unsupported() + } + + pub fn socket_addr(&self) -> io::Result { + self.0 + } + + pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { + self.0 + } + + pub fn duplicate(&self) -> io::Result { + self.0 + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + self.0 + } + + pub fn ttl(&self) -> io::Result { + self.0 + } + + pub fn set_only_v6(&self, _: bool) -> io::Result<()> { + self.0 + } + + pub fn only_v6(&self) -> io::Result { + self.0 + } + + pub fn take_error(&self) -> io::Result> { + self.0 + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + self.0 + } +} + +impl fmt::Debug for TcpListener { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +pub struct UdpSocket(!); + +impl UdpSocket { + pub fn bind(_: io::Result<&SocketAddr>) -> io::Result { + unsupported() + } + + pub fn peer_addr(&self) -> io::Result { + self.0 + } + + pub fn socket_addr(&self) -> io::Result { + self.0 + } + + pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + self.0 + } + + pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + self.0 + } + + pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result { + self.0 + } + + pub fn duplicate(&self) -> io::Result { + self.0 + } + + pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { + self.0 + } + + pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { + self.0 + } + + pub fn read_timeout(&self) -> io::Result> { + self.0 + } + + pub fn write_timeout(&self) -> io::Result> { + self.0 + } + + pub fn set_broadcast(&self, _: bool) -> io::Result<()> { + self.0 + } + + pub fn broadcast(&self) -> io::Result { + self.0 + } + + pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { + self.0 + } + + pub fn multicast_loop_v4(&self) -> io::Result { + self.0 + } + + pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { + self.0 + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + self.0 + } + + pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { + self.0 + } + + pub fn multicast_loop_v6(&self) -> io::Result { + self.0 + } + + pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { + self.0 + } + + pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { + self.0 + } + + pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { + self.0 + } + + pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { + self.0 + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + self.0 + } + + pub fn ttl(&self) -> io::Result { + self.0 + } + + pub fn take_error(&self) -> io::Result> { + self.0 + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + self.0 + } + + pub fn recv(&self, _: &mut [u8]) -> io::Result { + self.0 + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result { + self.0 + } + + pub fn send(&self, _: &[u8]) -> io::Result { + self.0 + } + + pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { + self.0 + } +} + +impl fmt::Debug for UdpSocket { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +pub struct LookupHost(!); + +impl LookupHost { + pub fn port(&self) -> u16 { + self.0 + } +} + +impl Iterator for LookupHost { + type Item = SocketAddr; + fn next(&mut self) -> Option { + self.0 + } +} + +impl TryFrom<&str> for LookupHost { + type Error = io::Error; + + fn try_from(_v: &str) -> io::Result { + unsupported() + } +} + +impl<'a> TryFrom<(&'a str, u16)> for LookupHost { + type Error = io::Error; + + fn try_from(_v: (&'a str, u16)) -> io::Result { + unsupported() + } +} + +#[allow(nonstandard_style)] +pub mod netc { + pub const AF_INET: u8 = 0; + pub const AF_INET6: u8 = 1; + pub type sa_family_t = u8; + + #[derive(Copy, Clone)] + pub struct in_addr { + pub s_addr: u32, + } + + #[derive(Copy, Clone)] + pub struct sockaddr_in { + #[allow(dead_code)] + pub sin_family: sa_family_t, + pub sin_port: u16, + pub sin_addr: in_addr, + } + + #[derive(Copy, Clone)] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } + + #[derive(Copy, Clone)] + pub struct sockaddr_in6 { + #[allow(dead_code)] + pub sin6_family: sa_family_t, + pub sin6_port: u16, + pub sin6_addr: in6_addr, + pub sin6_flowinfo: u32, + pub sin6_scope_id: u32, + } +} diff --git a/library/std/src/sys/pal/osstd/os.rs b/library/std/src/sys/pal/osstd/os.rs new file mode 100644 index 00000000000..481fd62c04f --- /dev/null +++ b/library/std/src/sys/pal/osstd/os.rs @@ -0,0 +1,120 @@ +use super::unsupported; +use crate::error::Error as StdError; +use crate::ffi::{OsStr, OsString}; +use crate::marker::PhantomData; +use crate::path::{self, PathBuf}; +use crate::{fmt, io}; + +pub fn errno() -> i32 { + 0 +} + +pub fn error_string(_errno: i32) -> String { + "operation successful".to_string() +} + +pub fn getcwd() -> io::Result { + unsupported() +} + +pub fn chdir(_: &path::Path) -> io::Result<()> { + unsupported() +} + +pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); + +pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { + panic!("unsupported") +} + +impl<'a> Iterator for SplitPaths<'a> { + type Item = PathBuf; + fn next(&mut self) -> Option { + self.0 + } +} + +#[derive(Debug)] +pub struct JoinPathsError; + +pub fn join_paths(_paths: I) -> Result +where + I: Iterator, + T: AsRef, +{ + Err(JoinPathsError) +} + +impl fmt::Display for JoinPathsError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + "not supported on this platform yet".fmt(f) + } +} + +impl StdError for JoinPathsError { + #[allow(deprecated)] + fn description(&self) -> &str { + "not supported on this platform yet" + } +} + +pub fn current_exe() -> io::Result { + unsupported() +} + +pub struct Env(!); + +impl Env { + // FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when ::fmt matches ::fmt. + pub fn str_debug(&self) -> impl fmt::Debug + '_ { + let Self(inner) = self; + match *inner {} + } +} + +impl fmt::Debug for Env { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self(inner) = self; + match *inner {} + } +} + +impl Iterator for Env { + type Item = (OsString, OsString); + fn next(&mut self) -> Option<(OsString, OsString)> { + let Self(inner) = self; + match *inner {} + } +} + +pub fn env() -> Env { + panic!("not supported on this platform") +} + +pub fn getenv(_: &OsStr) -> Option { + None +} + +pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { + Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) +} + +pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { + Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) +} + +pub fn temp_dir() -> PathBuf { + panic!("no filesystem on this platform") +} + +pub fn home_dir() -> Option { + None +} + +pub fn exit(_code: i32) -> ! { + crate::intrinsics::abort() +} + +pub fn getpid() -> u32 { + panic!("no pids on this platform") +} diff --git a/library/std/src/sys/pal/osstd/pipe.rs b/library/std/src/sys/pal/osstd/pipe.rs new file mode 100644 index 00000000000..6799d21a1ff --- /dev/null +++ b/library/std/src/sys/pal/osstd/pipe.rs @@ -0,0 +1,56 @@ +use crate::fmt; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; + +pub struct AnonPipe(!); + +impl fmt::Debug for AnonPipe { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +impl AnonPipe { + pub fn try_clone(&self) -> io::Result { + self.0 + } + + pub fn read(&self, _buf: &mut [u8]) -> io::Result { + self.0 + } + + pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> { + self.0 + } + + pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.0 + } + + pub fn is_read_vectored(&self) -> bool { + self.0 + } + + pub fn read_to_end(&self, _buf: &mut Vec) -> io::Result { + self.0 + } + + pub fn write(&self, _buf: &[u8]) -> io::Result { + self.0 + } + + pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result { + self.0 + } + + pub fn is_write_vectored(&self) -> bool { + self.0 + } + + pub fn diverge(&self) -> ! { + self.0 + } +} + +pub fn read2(p1: AnonPipe, _v1: &mut Vec, _p2: AnonPipe, _v2: &mut Vec) -> io::Result<()> { + match p1.0 {} +} diff --git a/library/std/src/sys/pal/osstd/process.rs b/library/std/src/sys/pal/osstd/process.rs new file mode 100644 index 00000000000..fee81744f09 --- /dev/null +++ b/library/std/src/sys/pal/osstd/process.rs @@ -0,0 +1,322 @@ +pub use crate::ffi::OsString as EnvKey; +use crate::ffi::{OsStr, OsString}; +use crate::num::NonZero; +use crate::path::Path; +use crate::sys::fs::File; +use crate::sys::pipe::AnonPipe; +use crate::sys::unsupported; +use crate::sys_common::process::{CommandEnv, CommandEnvs}; +use crate::{fmt, io}; + +//////////////////////////////////////////////////////////////////////////////// +// Command +//////////////////////////////////////////////////////////////////////////////// + +pub struct Command { + program: OsString, + args: Vec, + env: CommandEnv, + + cwd: Option, + stdin: Option, + stdout: Option, + stderr: Option, +} + +// passed back to std::process with the pipes connected to the child, if any +// were requested +pub struct StdioPipes { + pub stdin: Option, + pub stdout: Option, + pub stderr: Option, +} + +#[derive(Debug)] +pub enum Stdio { + Inherit, + Null, + MakePipe, + ParentStdout, + ParentStderr, + #[allow(dead_code)] // This variant exists only for the Debug impl + InheritFile(File), +} + +impl Command { + pub fn new(program: &OsStr) -> Command { + Command { + program: program.to_owned(), + args: vec![program.to_owned()], + env: Default::default(), + cwd: None, + stdin: None, + stdout: None, + stderr: None, + } + } + + pub fn arg(&mut self, arg: &OsStr) { + self.args.push(arg.to_owned()); + } + + pub fn env_mut(&mut self) -> &mut CommandEnv { + &mut self.env + } + + pub fn cwd(&mut self, dir: &OsStr) { + self.cwd = Some(dir.to_owned()); + } + + pub fn stdin(&mut self, stdin: Stdio) { + self.stdin = Some(stdin); + } + + pub fn stdout(&mut self, stdout: Stdio) { + self.stdout = Some(stdout); + } + + pub fn stderr(&mut self, stderr: Stdio) { + self.stderr = Some(stderr); + } + + pub fn get_program(&self) -> &OsStr { + &self.program + } + + pub fn get_args(&self) -> CommandArgs<'_> { + let mut iter = self.args.iter(); + iter.next(); + CommandArgs { iter } + } + + pub fn get_envs(&self) -> CommandEnvs<'_> { + self.env.iter() + } + + pub fn get_current_dir(&self) -> Option<&Path> { + self.cwd.as_ref().map(|cs| Path::new(cs)) + } + + pub fn spawn( + &mut self, + _default: Stdio, + _needs_stdin: bool, + ) -> io::Result<(Process, StdioPipes)> { + unsupported() + } + + pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { + unsupported() + } +} + +impl From for Stdio { + fn from(pipe: AnonPipe) -> Stdio { + pipe.diverge() + } +} + +impl From for Stdio { + fn from(_: io::Stdout) -> Stdio { + Stdio::ParentStdout + } +} + +impl From for Stdio { + fn from(_: io::Stderr) -> Stdio { + Stdio::ParentStderr + } +} + +impl From for Stdio { + fn from(file: File) -> Stdio { + Stdio::InheritFile(file) + } +} + +impl fmt::Debug for Command { + // show all attributes + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if f.alternate() { + let mut debug_command = f.debug_struct("Command"); + debug_command.field("program", &self.program).field("args", &self.args); + if !self.env.is_unchanged() { + debug_command.field("env", &self.env); + } + + if self.cwd.is_some() { + debug_command.field("cwd", &self.cwd); + } + + if self.stdin.is_some() { + debug_command.field("stdin", &self.stdin); + } + if self.stdout.is_some() { + debug_command.field("stdout", &self.stdout); + } + if self.stderr.is_some() { + debug_command.field("stderr", &self.stderr); + } + + debug_command.finish() + } else { + if let Some(ref cwd) = self.cwd { + write!(f, "cd {cwd:?} && ")?; + } + if self.env.does_clear() { + write!(f, "env -i ")?; + // Altered env vars will be printed next, that should exactly work as expected. + } else { + // Removed env vars need the command to be wrapped in `env`. + let mut any_removed = false; + for (key, value_opt) in self.get_envs() { + if value_opt.is_none() { + if !any_removed { + write!(f, "env ")?; + any_removed = true; + } + write!(f, "-u {} ", key.to_string_lossy())?; + } + } + } + // Altered env vars can just be added in front of the program. + for (key, value_opt) in self.get_envs() { + if let Some(value) = value_opt { + write!(f, "{}={value:?} ", key.to_string_lossy())?; + } + } + if self.program != self.args[0] { + write!(f, "[{:?}] ", self.program)?; + } + write!(f, "{:?}", self.args[0])?; + + for arg in &self.args[1..] { + write!(f, " {:?}", arg)?; + } + Ok(()) + } + } +} + +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] +#[non_exhaustive] +pub struct ExitStatus(); + +impl ExitStatus { + pub fn exit_ok(&self) -> Result<(), ExitStatusError> { + Ok(()) + } + + pub fn code(&self) -> Option { + Some(0) + } +} + +impl fmt::Display for ExitStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "") + } +} + +pub struct ExitStatusError(!); + +impl Clone for ExitStatusError { + fn clone(&self) -> ExitStatusError { + self.0 + } +} + +impl Copy for ExitStatusError {} + +impl PartialEq for ExitStatusError { + fn eq(&self, _other: &ExitStatusError) -> bool { + self.0 + } +} + +impl Eq for ExitStatusError {} + +impl fmt::Debug for ExitStatusError { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +impl Into for ExitStatusError { + fn into(self) -> ExitStatus { + self.0 + } +} + +impl ExitStatusError { + pub fn code(self) -> Option> { + self.0 + } +} + +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitCode(u8); + +impl ExitCode { + pub const SUCCESS: ExitCode = ExitCode(0); + pub const FAILURE: ExitCode = ExitCode(1); + + pub fn as_i32(&self) -> i32 { + self.0 as i32 + } +} + +impl From for ExitCode { + fn from(code: u8) -> Self { + Self(code) + } +} + +pub struct Process(!); + +impl Process { + pub fn id(&self) -> u32 { + self.0 + } + + pub fn kill(&mut self) -> io::Result<()> { + self.0 + } + + pub fn wait(&mut self) -> io::Result { + self.0 + } + + pub fn try_wait(&mut self) -> io::Result> { + self.0 + } +} + +pub struct CommandArgs<'a> { + iter: crate::slice::Iter<'a, OsString>, +} + +impl<'a> Iterator for CommandArgs<'a> { + type Item = &'a OsStr; + fn next(&mut self) -> Option<&'a OsStr> { + self.iter.next().map(|os| &**os) + } + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +impl<'a> ExactSizeIterator for CommandArgs<'a> { + fn len(&self) -> usize { + self.iter.len() + } + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} + +impl<'a> fmt::Debug for CommandArgs<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_list().entries(self.iter.clone()).finish() + } +} diff --git a/library/std/src/sys/pal/osstd/stdio.rs b/library/std/src/sys/pal/osstd/stdio.rs new file mode 100644 index 00000000000..b5e3f5be988 --- /dev/null +++ b/library/std/src/sys/pal/osstd/stdio.rs @@ -0,0 +1,59 @@ +use crate::io; + +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; + +impl Stdin { + pub const fn new() -> Stdin { + Stdin + } +} + +impl io::Read for Stdin { + fn read(&mut self, _buf: &mut [u8]) -> io::Result { + Ok(0) + } +} + +impl Stdout { + pub const fn new() -> Stdout { + Stdout + } +} + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Stderr { + pub const fn new() -> Stderr { + Stderr + } +} + +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result { + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +pub const STDIN_BUF_SIZE: usize = 0; + +pub fn is_ebadf(_err: &io::Error) -> bool { + true +} + +pub fn panic_output() -> Option> { + None +} diff --git a/library/std/src/sys/pal/osstd/thread.rs b/library/std/src/sys/pal/osstd/thread.rs new file mode 100644 index 00000000000..89f8bad7026 --- /dev/null +++ b/library/std/src/sys/pal/osstd/thread.rs @@ -0,0 +1,36 @@ +use super::unsupported; +use crate::ffi::CStr; +use crate::io; +use crate::num::NonZero; +use crate::time::Duration; + +pub struct Thread(!); + +pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024; + +impl Thread { + // unsafe: see thread::Builder::spawn_unchecked for safety requirements + pub unsafe fn new(_stack: usize, _p: Box) -> io::Result { + unsupported() + } + + pub fn yield_now() { + // do nothing + } + + pub fn set_name(_name: &CStr) { + // nope + } + + pub fn sleep(_dur: Duration) { + panic!("can't sleep"); + } + + pub fn join(self) { + self.0 + } +} + +pub fn available_parallelism() -> io::Result> { + unsupported() +} diff --git a/library/std/src/sys/pal/osstd/time.rs b/library/std/src/sys/pal/osstd/time.rs new file mode 100644 index 00000000000..6d67b538a96 --- /dev/null +++ b/library/std/src/sys/pal/osstd/time.rs @@ -0,0 +1,45 @@ +use crate::time::Duration; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct Instant(Duration); + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct SystemTime(Duration); + +pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0)); + +impl Instant { + pub fn now() -> Instant { + panic!("time not implemented on this platform") + } + + pub fn checked_sub_instant(&self, other: &Instant) -> Option { + self.0.checked_sub(other.0) + } + + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(Instant(self.0.checked_add(*other)?)) + } + + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(Instant(self.0.checked_sub(*other)?)) + } +} + +impl SystemTime { + pub fn now() -> SystemTime { + panic!("time not implemented on this platform") + } + + pub fn sub_time(&self, other: &SystemTime) -> Result { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) + } + + pub fn checked_add_duration(&self, other: &Duration) -> Option { + Some(SystemTime(self.0.checked_add(*other)?)) + } + + pub fn checked_sub_duration(&self, other: &Duration) -> Option { + Some(SystemTime(self.0.checked_sub(*other)?)) + } +} diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index f42351deb92..2f2d4c6e3ad 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -75,6 +75,7 @@ cfg_if::cfg_if! { } else if #[cfg(any( all(target_family = "wasm", target_os = "unknown"), target_os = "xous", + target_os = "os", ))] { // FIXME: finally remove std support for wasm32-unknown-unknown // FIXME: add random data generation to xous @@ -88,6 +89,7 @@ cfg_if::cfg_if! { target_os = "android", all(target_family = "wasm", target_os = "unknown"), target_os = "xous", + target_os = "os", )))] pub fn hashmap_random_keys() -> (u64, u64) { let mut buf = [0; 16]; diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 31d3b439060..a34f677ba81 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -28,6 +28,7 @@ cfg_if::cfg_if! { all(target_family = "wasm", not(target_feature = "atomics")), target_os = "uefi", target_os = "zkvm", + target_os = "os", ))] { mod statik; pub use statik::{EagerStorage, LazyStorage, thread_local_inner}; @@ -89,6 +90,7 @@ pub(crate) mod guard { target_family = "wasm", target_os = "uefi", target_os = "zkvm", + target_os = "os", ))] { pub(crate) fn enable() { // FIXME: Right now there is no concept of "thread exit" on diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index fabb4f2b13b..246ab14d9da 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,6 +34,7 @@ pub struct Finder { // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "x86_64-unknown-os", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index c384fd6bf43..7221704680d 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -667,7 +667,7 @@ impl Build { } // Generate memcpy, etc. FIXME: Remove this once compiler-builtins // automatically detects this target. - if target.contains("zkvm") { + if target.contains("zkvm") || target.contains("os") { features.insert("compiler-builtins-mem"); }