From 5b5f0a7e9235fb6379d880b18534ad71c460aadd Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Mon, 27 May 2024 19:42:48 -0700 Subject: [PATCH 01/72] add armv7a-vex-v5 target --- compiler/rustc_target/src/spec/mod.rs | 2 + .../src/spec/targets/armv7a_vex_v5.rs | 34 ++++++++++++ .../targets/armv7a_vex_v5_linker_script.ld | 52 +++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs create mode 100644 compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 37564ab38fca4..4aaba2732683b 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1952,6 +1952,8 @@ supported_targets! { ("armv7-sony-vita-newlibeabihf", armv7_sony_vita_newlibeabihf), + ("armv7a-vex-v5", armv7a_vex_v5), + ("armv7-unknown-linux-uclibceabi", armv7_unknown_linux_uclibceabi), ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs new file mode 100644 index 0000000000000..bac7747e7d80e --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -0,0 +1,34 @@ +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; + +const LINK_SCRIPT: &str = include_str!("./armv7a_vex_v5_linker_script.ld"); + +pub(crate) fn target() -> Target { + Target { + llvm_target: "armv7a-none-eabi".into(), + metadata: crate::spec::TargetMetadata { + description: None, + tier: None, + host_tools: None, + std: None, + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: "arm".into(), + options: TargetOptions { + abi: "eabi".into(), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), + link_script: Some(LINK_SCRIPT.into()), + features: "+v7,+thumb2,+soft-float,-neon,+strict-align".into(), + relocation_model: RelocModel::Static, + disable_redzone: true, + max_atomic_width: Some(64), + panic_strategy: PanicStrategy::Abort, + emit_debug_gdb_scripts: false, + c_enum_min_bits: Some(8), + os: "vexos".into(), + vendor: "vex".into(), + ..Default::default() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld new file mode 100644 index 0000000000000..f9436907c7feb --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -0,0 +1,52 @@ +OUTPUT_FORMAT("elf32-littlearm") + +ENTRY(_start) + +__cold_start = 0x03800000; +__cold_length = 0x04800000; +__cold_end = __cold_start + __cold_length; + +MEMORY { + COLD : ORIGIN = __cold_start, LENGTH = __cold_length +} + +__stack_length = 0x400000; +/* +I'm not sure why subtracting anything is necessary, but it fixes memory permission errors. +0x1000 is an arbitrary number that works. +*/ +__heap_end = __cold_end - __stack_length - 0x1000; + +SECTIONS { + .code_signature { + KEEP(*(.code_signature)) + . = __cold_start + 0x20; + } > COLD + .text : { + KEEP(*(.text.boot)) + *(.text .text.*) + } > COLD + .rodata : { + __rodata_start = .; + *(.rodata1 .rodata1.*) + __rodata_end = .; + } > COLD + .data : { + *(.data .data.*) + *(.data1 .data1.*) + } > COLD + .bss : { + __bss_start = .; + *(.bss .bss.*) + __bss_end = .; + } > COLD + .heap (NOLOAD) : ALIGN(4) { + __heap_start = .; + . = __heap_end; + } > COLD + .stack (NOLOAD) : ALIGN(8) { + __stack_end = .; + . += __stack_length; + __stack_start = .; + } > COLD +} From 266d1b6abab8536c39c83c3b0011872ab8c7d033 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Mon, 27 May 2024 20:31:34 -0700 Subject: [PATCH 02/72] add (shimmed) std support for armv7a-vex-v5 --- library/std/Cargo.toml | 3 +++ library/std/build.rs | 1 + library/std/src/sys/pal/mod.rs | 3 +++ library/std/src/sys/pal/vexos/mod.rs | 31 ++++++++++++++++++++++++++++ src/bootstrap/src/core/sanity.rs | 1 + src/bootstrap/src/lib.rs | 6 +++--- 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 library/std/src/sys/pal/vexos/mod.rs diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index da58d7c13bd12..283e2dbf11769 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -85,6 +85,9 @@ wasi = { version = "0.11.0", features = [ r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] } +[target.'cfg(target_os = "vexos")'.dependencies] +vex-sdk = { version = "0.16.1", features = ['rustc-dep-of-std'] } + [features] backtrace = [ 'addr2line/rustc-dep-of-std', diff --git a/library/std/build.rs b/library/std/build.rs index 8dc326a3dde6a..e61e59b5fd629 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 == "vexos" // 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/pal/mod.rs b/library/std/src/sys/pal/mod.rs index 9be018c8a5312..45c692c805c80 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 = "vexos")] { + mod vexos; + pub use self::vexos::*; } else { mod unsupported; pub use self::unsupported::*; diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs new file mode 100644 index 0000000000000..d57afead5606b --- /dev/null +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -0,0 +1,31 @@ +#[path = "../unsupported/alloc.rs"] +pub mod alloc; +#[path = "../unsupported/args.rs"] +pub mod args; +#[path = "../unsupported/env.rs"] +pub mod env; +#[path = "../unsupported/fs.rs"] +pub mod fs; +#[path = "../unsupported/io.rs"] +pub mod io; +#[path = "../unsupported/net.rs"] +pub mod net; +#[path = "../unsupported/os.rs"] +pub mod os; +#[path = "../unsupported/pipe.rs"] +pub mod pipe; +#[path = "../unsupported/process.rs"] +pub mod process; +#[path = "../unsupported/stdio.rs"] +pub mod stdio; +#[path = "../unsupported/thread.rs"] +pub mod thread; +#[path = "../unsupported/thread_local_key.rs"] +pub mod thread_local_key; +#[path = "../unsupported/time.rs"] +pub mod time; + +#[path = "../unsupported/common.rs"] +#[deny(unsafe_op_in_unsafe_fn)] +mod common; +pub use common::*; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index ed0155622c226..c8e65bc4c79f6 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -33,6 +33,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] = &[ + "armv7a-vex-v5", // just a dummy comment so the list doesn't get onelined ]; diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 482e23cd04c31..e3dfac2334adf 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -617,9 +617,9 @@ impl Build { if self.config.profiler_enabled(target) { features.insert("profiler"); } - - // If zkvm target, generate memcpy, etc. - if target.contains("zkvm") { + // Generate memcpy, etc. FIXME: Remove this once compiler-builtins + // automatically detects this target. + if target.contains("zkvm") || target.contains("vex") { features.insert("compiler-builtins-mem"); } From 83f35f36cd0365929a7039ce4f74563f301f8694 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 28 May 2024 11:39:16 -0700 Subject: [PATCH 03/72] add panic, stdio, and alloc support to armv7a-vex-v5 --- .../targets/armv7a_vex_v5_linker_script.ld | 2 +- library/panic_abort/src/lib.rs | 1 + library/std/Cargo.toml | 2 +- library/std/src/sys/pal/vexos/alloc.rs | 97 +++++++++++++++++++ library/std/src/sys/pal/vexos/mod.rs | 17 +++- library/std/src/sys/pal/vexos/stdio.rs | 86 ++++++++++++++++ 6 files changed, 201 insertions(+), 4 deletions(-) create mode 100644 library/std/src/sys/pal/vexos/alloc.rs create mode 100644 library/std/src/sys/pal/vexos/stdio.rs diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld index f9436907c7feb..c62b872fd84c4 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -18,7 +18,7 @@ I'm not sure why subtracting anything is necessary, but it fixes memory permissi __heap_end = __cold_end - __stack_length - 0x1000; SECTIONS { - .code_signature { + .code_signature : { KEEP(*(.code_signature)) . = __cold_start + 0x20; } > COLD diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index dc2b42bb90ae8..6e2b29a41a995 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -51,6 +51,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 { all(target_vendor = "fortanix", target_env = "sgx"), target_os = "xous", target_os = "uefi", + target_os = "vexos", ))] { unsafe fn abort() -> ! { // call std::sys::abort_internal diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 283e2dbf11769..f1a3f47959ef3 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -63,7 +63,7 @@ path = "../windows_targets" rand = { version = "0.8.5", default-features = false, features = ["alloc"] } rand_xorshift = "0.3.0" -[target.'cfg(any(all(target_family = "wasm", target_os = "unknown"), target_os = "xous", all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies] +[target.'cfg(any(all(target_family = "wasm", target_os = "unknown"), target_os = "vexos", target_os = "xous", all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies] dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] } [target.x86_64-fortanix-unknown-sgx.dependencies] diff --git a/library/std/src/sys/pal/vexos/alloc.rs b/library/std/src/sys/pal/vexos/alloc.rs new file mode 100644 index 0000000000000..8ff93fe03335e --- /dev/null +++ b/library/std/src/sys/pal/vexos/alloc.rs @@ -0,0 +1,97 @@ +use crate::{ + alloc::{GlobalAlloc, Layout, System}, + ptr, + sync::atomic::{AtomicBool, Ordering}, +}; + +static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new_with_allocator(Vexos); + +extern "C" { + static mut __heap_start: u8; + static mut __heap_end: u8; +} + +struct Vexos; + +unsafe impl dlmalloc::Allocator for Vexos { + /// Allocs system resources + fn alloc(&self, _size: usize) -> (*mut u8, usize, u32) { + static INIT: AtomicBool = AtomicBool::new(false); + + if !INIT.swap(true, Ordering::Relaxed) { + unsafe { + ( + ptr::addr_of_mut!(__heap_start).cast(), + ptr::addr_of!(__heap_end).byte_offset_from(ptr::addr_of!(__heap_start)) as _, + 0, + ) + } + } else { + (ptr::null_mut(), 0, 0) + } + } + + fn remap(&self, _ptr: *mut u8, _oldsize: usize, _newsize: usize, _can_move: bool) -> *mut u8 { + ptr::null_mut() + } + + fn free_part(&self, _ptr: *mut u8, _oldsize: usize, _newsize: usize) -> bool { + false + } + + fn free(&self, _ptr: *mut u8, _size: usize) -> bool { + return false; + } + + fn can_release_part(&self, _flags: u32) -> bool { + false + } + + fn allocates_zeros(&self) -> bool { + false + } + + fn page_size(&self) -> usize { + 0x1000 + } +} + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. + // Calling malloc() is safe because preconditions on this function match the trait method preconditions. + let _lock = lock::lock(); + unsafe { DLMALLOC.malloc(layout.size(), layout.align()) } + } + + #[inline] + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. + // Calling calloc() is safe because preconditions on this function match the trait method preconditions. + let _lock = lock::lock(); + unsafe { DLMALLOC.calloc(layout.size(), layout.align()) } + } + + #[inline] + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. + // Calling free() is safe because preconditions on this function match the trait method preconditions. + let _lock = lock::lock(); + unsafe { DLMALLOC.free(ptr, layout.size(), layout.align()) } + } + + #[inline] + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. + // Calling realloc() is safe because preconditions on this function match the trait method preconditions. + let _lock = lock::lock(); + unsafe { DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) } + } +} + +mod lock { + #[inline] + pub fn lock() {} // we don't have threads, which makes this real easy +} diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index d57afead5606b..26423c68a8ca2 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -1,4 +1,3 @@ -#[path = "../unsupported/alloc.rs"] pub mod alloc; #[path = "../unsupported/args.rs"] pub mod args; @@ -16,7 +15,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -#[path = "../unsupported/stdio.rs"] pub mod stdio; #[path = "../unsupported/thread.rs"] pub mod thread; @@ -29,3 +27,18 @@ pub mod time; #[deny(unsafe_op_in_unsafe_fn)] mod common; pub use common::*; + +// This function is needed by the panic runtime. The symbol is named in +// pre-link args for the target specification, so keep that in sync. +#[cfg(not(test))] +#[no_mangle] +// NB. used by both libunwind and libpanic_abort +pub extern "C" fn __rust_abort() -> ! { + unsafe { + vex_sdk::vexSystemExitRequest(); + } + + loop { + crate::hint::spin_loop() + } +} diff --git a/library/std/src/sys/pal/vexos/stdio.rs b/library/std/src/sys/pal/vexos/stdio.rs new file mode 100644 index 0000000000000..eb09b4a5c51d3 --- /dev/null +++ b/library/std/src/sys/pal/vexos/stdio.rs @@ -0,0 +1,86 @@ +use crate::io; + +pub struct Stdin(()); +pub struct Stdout(()); +pub struct Stderr(()); + +const STDIO_CHANNEL: u32 = 1; + +impl Stdin { + pub const fn new() -> Stdin { + Stdin(()) + } +} + +impl io::Read for Stdin { + fn read(&mut self, mut buf: &mut [u8]) -> io::Result { + let mut written = 0; + + while let Some((out_byte, new_buf)) = buf.split_first_mut() { + buf = new_buf; + + let byte = unsafe { vex_sdk::vexSerialReadChar(STDIO_CHANNEL) }; + if byte < 0 { + break; + } + + *out_byte = byte as u8; + written += 1; + } + + Ok(written) + } +} + +impl Stdout { + pub const fn new() -> Stdout { + Stdout(()) + } +} + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + let written = + unsafe { vex_sdk::vexSerialWriteBuffer(STDIO_CHANNEL, buf.as_ptr(), buf.len() as u32) }; + + if written < 0 { + return Err(io::Error::new(io::ErrorKind::Other, "Internal write error occurred.")); + } + + Ok(written as usize) + } + + fn flush(&mut self) -> io::Result<()> { + unsafe { + vex_sdk::vexTasksRun(); + } + + 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 { + Some(Stdout::new()) +} From 56084ebc2475d7888dd2175fba191fa824783d27 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Wed, 29 May 2024 23:19:23 -0700 Subject: [PATCH 04/72] fix linker script and call main --- .../targets/armv7a_vex_v5_linker_script.ld | 54 ++++++++++--------- library/std/Cargo.toml | 2 +- library/std/src/sys/pal/vexos/mod.rs | 49 +++++++++++++++-- 3 files changed, 74 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld index c62b872fd84c4..ccdd6110e2eb6 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -2,51 +2,53 @@ OUTPUT_FORMAT("elf32-littlearm") ENTRY(_start) -__cold_start = 0x03800000; -__cold_length = 0x04800000; -__cold_end = __cold_start + __cold_length; +__user_ram_start = 0x03800000; +__user_ram_length = 0x04800000; +__user_ram_end = __user_ram_start + __user_ram_length; MEMORY { - COLD : ORIGIN = __cold_start, LENGTH = __cold_length + USER_RAM : ORIGIN = __user_ram_start, LENGTH = __user_ram_length } __stack_length = 0x400000; -/* -I'm not sure why subtracting anything is necessary, but it fixes memory permission errors. -0x1000 is an arbitrary number that works. -*/ -__heap_end = __cold_end - __stack_length - 0x1000; +__heap_end = __user_ram_end - __stack_length - 64; SECTIONS { - .code_signature : { + .code_signature __user_ram_start : { KEEP(*(.code_signature)) - . = __cold_start + 0x20; - } > COLD - .text : { - KEEP(*(.text.boot)) + } > USER_RAM = 0 + + .text __user_ram_start + 0x20 : { + *(.text.boot) *(.text .text.*) - } > COLD + } > USER_RAM + .rodata : { - __rodata_start = .; - *(.rodata1 .rodata1.*) - __rodata_end = .; - } > COLD + *(.rodata .rodata.*) + } > USER_RAM + .data : { *(.data .data.*) - *(.data1 .data1.*) - } > COLD + } > USER_RAM + .bss : { __bss_start = .; *(.bss .bss.*) __bss_end = .; - } > COLD + } > USER_RAM + .heap (NOLOAD) : ALIGN(4) { __heap_start = .; . = __heap_end; - } > COLD + } > USER_RAM + .stack (NOLOAD) : ALIGN(8) { - __stack_end = .; + __stack_bottom = .; . += __stack_length; - __stack_start = .; - } > COLD + __stack_top = .; + } > USER_RAM + + /DISCARD/ : { + *(.ARM.exidx) + } } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f1a3f47959ef3..a4c611218034a 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -86,7 +86,7 @@ r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] } [target.'cfg(target_os = "vexos")'.dependencies] -vex-sdk = { version = "0.16.1", features = ['rustc-dep-of-std'] } +vex-sdk = { version = "0.17.0", features = ['rustc-dep-of-std'] } [features] backtrace = [ diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 26423c68a8ca2..41354a20603c2 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -15,6 +15,7 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; +#[path = "../unsupported/stdio.rs"] pub mod stdio; #[path = "../unsupported/thread.rs"] pub mod thread; @@ -23,10 +24,22 @@ pub mod thread_local_key; #[path = "../unsupported/time.rs"] pub mod time; -#[path = "../unsupported/common.rs"] -#[deny(unsafe_op_in_unsafe_fn)] -mod common; -pub use common::*; +use crate::arch::asm; + +#[cfg(not(test))] +#[no_mangle] +#[link_section = ".text.boot"] +pub unsafe extern "C" fn _start() -> ! { + extern "C" { + fn main() -> i32; + } + + asm!("ldr sp, =__stack_top", options(nostack)); + + main(); + + abort_internal() +} // This function is needed by the panic runtime. The symbol is named in // pre-link args for the target specification, so keep that in sync. @@ -34,6 +47,30 @@ pub use common::*; #[no_mangle] // NB. used by both libunwind and libpanic_abort pub extern "C" fn __rust_abort() -> ! { + abort_internal() +} + +pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} + +pub unsafe fn cleanup() {} + +pub fn unsupported() -> crate::io::Result { + Err(unsupported_err()) +} + +pub fn unsupported_err() -> crate::io::Error { + crate::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() -> ! { unsafe { vex_sdk::vexSystemExitRequest(); } @@ -42,3 +79,7 @@ pub extern "C" fn __rust_abort() -> ! { crate::hint::spin_loop() } } + +pub fn hashmap_random_keys() -> (u64, u64) { + (1, 2) +} From c20455084bdab9339b324a8a94564f06eda6d3aa Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Wed, 17 Jul 2024 16:16:47 -0700 Subject: [PATCH 05/72] zero out bss section in _start --- library/std/src/sys/pal/vexos/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 41354a20603c2..c077871671c61 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -24,18 +24,29 @@ pub mod thread_local_key; #[path = "../unsupported/time.rs"] pub mod time; -use crate::arch::asm; +use crate::{arch::asm, ptr::{self, addr_of_mut}}; #[cfg(not(test))] #[no_mangle] #[link_section = ".text.boot"] pub unsafe extern "C" fn _start() -> ! { extern "C" { + static mut __bss_start: u8; + static mut __bss_end: u8; + fn main() -> i32; } asm!("ldr sp, =__stack_top", options(nostack)); + ptr::slice_from_raw_parts_mut( + addr_of_mut!(__bss_start), + addr_of_mut!(__bss_end).offset_from(addr_of_mut!(__bss_start)) as usize, + ) + .as_mut() + .unwrap_unchecked() + .fill(0); + main(); abort_internal() From c684a49b58855378a53b6705f0199de56827cac2 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Wed, 17 Jul 2024 16:29:44 -0700 Subject: [PATCH 06/72] use static TLS implementation on vexos --- library/std/src/sys/thread_local/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index f0a13323ec93f..e74e0fe3fc6a3 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 = "vexos", ))] { mod statik; pub use statik::{EagerStorage, LazyStorage, thread_local_inner}; From cdbfde6a59d1b9520e023a5eb1d940862da1cb6f Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Wed, 17 Jul 2024 16:30:45 -0700 Subject: [PATCH 07/72] make minor improvements to linker script --- .../src/spec/targets/armv7a_vex_v5_linker_script.ld | 8 +++++++- library/std/src/sys/pal/vexos/alloc.rs | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld index ccdd6110e2eb6..a3d45b0a660c0 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -11,7 +11,11 @@ MEMORY { } __stack_length = 0x400000; -__heap_end = __user_ram_end - __stack_length - 64; +/* +It's currently unclear why subtracting anything is necessary, but it fixes memory permission errors. +0x100 is an arbitrary number that works. +*/ +__heap_end = __user_ram_end - __stack_length - 0x1000; SECTIONS { .code_signature __user_ram_start : { @@ -25,10 +29,12 @@ SECTIONS { .rodata : { *(.rodata .rodata.*) + *(.rodata1 .rodata1.*) } > USER_RAM .data : { *(.data .data.*) + *(.data1 .data1.*) } > USER_RAM .bss : { diff --git a/library/std/src/sys/pal/vexos/alloc.rs b/library/std/src/sys/pal/vexos/alloc.rs index 8ff93fe03335e..f760ebef770f9 100644 --- a/library/std/src/sys/pal/vexos/alloc.rs +++ b/library/std/src/sys/pal/vexos/alloc.rs @@ -40,7 +40,7 @@ unsafe impl dlmalloc::Allocator for Vexos { } fn free(&self, _ptr: *mut u8, _size: usize) -> bool { - return false; + false } fn can_release_part(&self, _flags: u32) -> bool { From 5f8ee0c52565858743ef4966dbe8f8b5c7ac0eb2 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Wed, 17 Jul 2024 17:36:53 -0700 Subject: [PATCH 08/72] enable stdio and fix stdout flushing --- library/std/src/sys/pal/vexos/mod.rs | 5 +++-- library/std/src/sys/pal/vexos/stdio.rs | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index c077871671c61..e0466b90b8a6f 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -15,7 +15,6 @@ pub mod os; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -#[path = "../unsupported/stdio.rs"] pub mod stdio; #[path = "../unsupported/thread.rs"] pub mod thread; @@ -63,7 +62,9 @@ pub extern "C" fn __rust_abort() -> ! { pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} -pub unsafe fn cleanup() {} +pub unsafe fn cleanup() { + stdio:: +} pub fn unsupported() -> crate::io::Result { Err(unsupported_err()) diff --git a/library/std/src/sys/pal/vexos/stdio.rs b/library/std/src/sys/pal/vexos/stdio.rs index eb09b4a5c51d3..998592e762434 100644 --- a/library/std/src/sys/pal/vexos/stdio.rs +++ b/library/std/src/sys/pal/vexos/stdio.rs @@ -52,7 +52,9 @@ impl io::Write for Stdout { fn flush(&mut self) -> io::Result<()> { unsafe { - vex_sdk::vexTasksRun(); + while (vex_sdk::vexSerialWriteFree(STDIO_CHANNEL) as usize) != STDOUT_BUF_SIZE { + vex_sdk::vexTasksRun(); + } } Ok(()) @@ -75,7 +77,8 @@ impl io::Write for Stderr { } } -pub const STDIN_BUF_SIZE: usize = 0; +pub const STDIN_BUF_SIZE: usize = 4096; +const STDOUT_BUF_SIZE: usize = 2048; pub fn is_ebadf(_err: &io::Error) -> bool { true From a5403ca8aa487d09b4d45e8e37e54a6bda05bac5 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Wed, 17 Jul 2024 17:59:01 -0700 Subject: [PATCH 09/72] add: `Instant` implementation --- library/std/src/sys/pal/vexos/mod.rs | 1 - library/std/src/sys/pal/vexos/time.rs | 46 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 library/std/src/sys/pal/vexos/time.rs diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index e0466b90b8a6f..432e041d3cfa7 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -20,7 +20,6 @@ pub mod stdio; pub mod thread; #[path = "../unsupported/thread_local_key.rs"] pub mod thread_local_key; -#[path = "../unsupported/time.rs"] pub mod time; use crate::{arch::asm, ptr::{self, addr_of_mut}}; diff --git a/library/std/src/sys/pal/vexos/time.rs b/library/std/src/sys/pal/vexos/time.rs new file mode 100644 index 0000000000000..94699d64d2307 --- /dev/null +++ b/library/std/src/sys/pal/vexos/time.rs @@ -0,0 +1,46 @@ +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 { + let micros = unsafe { vex_sdk::vexSystemHighResTimeGet() }; + Self(Duration::from_micros(micros)) + } + + 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)?)) + } +} From d8c32e9293b309a9380aa09278c2c2fb61474909 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Wed, 17 Jul 2024 18:06:29 -0700 Subject: [PATCH 10/72] remove broken cleanup --- library/std/src/sys/pal/vexos/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 432e041d3cfa7..9189ac2a47925 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -61,9 +61,7 @@ pub extern "C" fn __rust_abort() -> ! { pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} -pub unsafe fn cleanup() { - stdio:: -} +pub unsafe fn cleanup() {} pub fn unsupported() -> crate::io::Result { Err(unsupported_err()) From f5125f62d7a3a8b775641ba35fb4ca416c09e881 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 17 Jul 2024 22:56:53 -0400 Subject: [PATCH 11/72] fix `.code_signature` section error --- .../src/spec/targets/armv7a_vex_v5_linker_script.ld | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld index a3d45b0a660c0..8ff88f24adf38 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -15,11 +15,13 @@ __stack_length = 0x400000; It's currently unclear why subtracting anything is necessary, but it fixes memory permission errors. 0x100 is an arbitrary number that works. */ -__heap_end = __user_ram_end - __stack_length - 0x1000; +__heap_end = __user_ram_end - __stack_length - 0x100; SECTIONS { .code_signature __user_ram_start : { + __code_signature_start = .; KEEP(*(.code_signature)) + . = __code_signature_start + 0x20; } > USER_RAM = 0 .text __user_ram_start + 0x20 : { From ac5f5527cb9fe2bd3d3606c5b2323aa8ea5e5b52 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 17 Jul 2024 23:07:27 -0400 Subject: [PATCH 12/72] move `.code_signature` section into `.text` --- .../targets/armv7a_vex_v5_linker_script.ld | 18 +++++++----------- library/std/src/sys/pal/vexos/mod.rs | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld index 8ff88f24adf38..37fc390401ead 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -18,19 +18,15 @@ It's currently unclear why subtracting anything is necessary, but it fixes memor __heap_end = __user_ram_end - __stack_length - 0x100; SECTIONS { - .code_signature __user_ram_start : { - __code_signature_start = .; + .text : { + __text_start = .; KEEP(*(.code_signature)) - . = __code_signature_start + 0x20; - } > USER_RAM = 0 - - .text __user_ram_start + 0x20 : { - *(.text.boot) + . = __text_start + 0x20; + *(.boot) *(.text .text.*) - } > USER_RAM + } > USER_RAM = 0 - .rodata : { - *(.rodata .rodata.*) + .rodata1 : { *(.rodata1 .rodata1.*) } > USER_RAM @@ -59,4 +55,4 @@ SECTIONS { /DISCARD/ : { *(.ARM.exidx) } -} +} \ No newline at end of file diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 9189ac2a47925..cb80cf675a09c 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -26,7 +26,7 @@ use crate::{arch::asm, ptr::{self, addr_of_mut}}; #[cfg(not(test))] #[no_mangle] -#[link_section = ".text.boot"] +#[link_section = ".boot"] pub unsafe extern "C" fn _start() -> ! { extern "C" { static mut __bss_start: u8; From bc078814d0aaf598f64d1cc1436ff3b5af476cd7 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jul 2024 00:13:16 -0400 Subject: [PATCH 13/72] adjust `armv7a-vex-v5` target features for more aggressive hardware optimization --- compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index bac7747e7d80e..bc117b64c2301 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -15,11 +15,12 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: "arm".into(), options: TargetOptions { - abi: "eabi".into(), + cpu: "cortex-a9".into(), + abi: "eabihf".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), link_script: Some(LINK_SCRIPT.into()), - features: "+v7,+thumb2,+soft-float,-neon,+strict-align".into(), + features: "+v7,+thumb2,+vfp3,+neon".into(), relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(64), From 170ba625a93034533977270a0098d606c97c9677 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jul 2024 00:31:41 -0400 Subject: [PATCH 14/72] switch `llvm_target` to use ARM hard-float abi --- compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index bc117b64c2301..a6a6f542e3103 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -4,7 +4,7 @@ const LINK_SCRIPT: &str = include_str!("./armv7a_vex_v5_linker_script.ld"); pub(crate) fn target() -> Target { Target { - llvm_target: "armv7a-none-eabi".into(), + llvm_target: "armv7a-none-eabihf".into(), metadata: crate::spec::TargetMetadata { description: None, tier: None, From 80b1d36dca48fb14c639679e8542aa290f25f898 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jul 2024 00:31:57 -0400 Subject: [PATCH 15/72] add `env` implementation for `vexos` PAL --- library/std/src/sys/pal/vexos/env.rs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 library/std/src/sys/pal/vexos/env.rs diff --git a/library/std/src/sys/pal/vexos/env.rs b/library/std/src/sys/pal/vexos/env.rs new file mode 100644 index 0000000000000..381658cfd342e --- /dev/null +++ b/library/std/src/sys/pal/vexos/env.rs @@ -0,0 +1,9 @@ +pub mod os { + pub const FAMILY: &str = ""; + pub const OS: &str = "vexos"; + pub const DLL_PREFIX: &str = ""; + pub const DLL_SUFFIX: &str = ""; + pub const DLL_EXTENSION: &str = ""; + pub const EXE_SUFFIX: &str = ".bin"; + pub const EXE_EXTENSION: &str = "bin"; +} From 2855b3113177a6daa8112003b99c970a9ceb70ff Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Wed, 17 Jul 2024 22:51:28 -0700 Subject: [PATCH 16/72] feat: experimental fs support --- library/std/src/sys/pal/vexos/fs.rs | 325 +++++++++++++++++++++++++++ library/std/src/sys/pal/vexos/mod.rs | 2 - 2 files changed, 325 insertions(+), 2 deletions(-) create mode 100644 library/std/src/sys/pal/vexos/fs.rs diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs new file mode 100644 index 0000000000000..005dc2645990a --- /dev/null +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -0,0 +1,325 @@ +use crate::ffi::{CString, OsString}; +use crate::fmt; +use crate::hash::Hash; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; +use crate::path::{Path, PathBuf}; +use crate::sys::time::SystemTime; +use crate::sys::unsupported; + +struct Fd(*mut vex_sdk::FIL); + +pub struct File(Fd); + +//TODO: We may be able to get some of this info +#[derive(Clone)] +pub struct FileAttr; + +pub struct ReadDir(!); + +pub struct DirEntry(!); + +#[derive(Clone, Debug)] +pub struct OpenOptions { + read: bool, + write: bool, + append: bool, +} + +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes {} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct FilePermissions; + +#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)] +pub struct FileType { + is_dir: bool, +} + +#[derive(Debug)] +pub struct DirBuilder {} + +impl FileAttr { + pub fn size(&self) -> u64 { + todo!() + } + + pub fn perm(&self) -> FilePermissions { + todo!() + } + + pub fn file_type(&self) -> FileType { + todo!() + } + + pub fn modified(&self) -> io::Result { + todo!() + } + + pub fn accessed(&self) -> io::Result { + todo!() + } + + pub fn created(&self) -> io::Result { + todo!() + } +} + +impl FilePermissions { + pub fn readonly(&self) -> bool { + false + } + + pub fn set_readonly(&mut self, _readonly: bool) { + panic!("Perimissions do not exist") + } +} + +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.is_dir + } + + pub fn is_file(&self) -> bool { + !self.is_dir + } + + pub fn is_symlink(&self) -> bool { + false + } +} + +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 { read: false, write: false, append: false } + } + + pub fn read(&mut self, read: bool) { + self.read = read; + } + pub fn write(&mut self, write: bool) { + self.write = write; + } + pub fn append(&mut self, append: bool) { + self.append = append; + } + pub fn truncate(&mut self, _truncate: bool) {} + pub fn create(&mut self, create: bool) { + self.write = create; + } + pub fn create_new(&mut self, _create_new: bool) {} +} + +impl File { + pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { + let path = CString::new(path.as_os_str().as_encoded_bytes()).map_err(|_| { + io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte") + })?; + + let file = if opts.read && !opts.write { + // The second argument to this function is ignored. + // Open in read only mode + unsafe { vex_sdk::vexFileOpen(path.as_ptr(), c"".as_ptr()) } + } else if opts.write && opts.append { + // Open in read/write and append mode + unsafe { vex_sdk::vexFileOpenWrite(path.as_ptr()) } + } else if opts.write { + // Open in read/write mode + unsafe { vex_sdk::vexFileOpenCreate(path.as_ptr()) } + } else { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Files cannot be opened without read or write access", + )); + }; + + if file.is_null() { + Err(io::Error::new(io::ErrorKind::NotFound, "Could not open file")) + } else { + Ok(Self(Fd(file))) + } + } + + pub fn file_attr(&self) -> io::Result { + todo!() + } + + pub fn fsync(&self) -> io::Result<()> { + todo!() + } + + pub fn datasync(&self) -> io::Result<()> { + todo!() + } + + pub fn truncate(&self, _size: u64) -> io::Result<()> { + todo!() + } + + pub fn read(&self, buf: &mut [u8]) -> io::Result { + let len = buf.len() as _; + let buf_ptr = buf.as_mut_ptr(); + let read = unsafe { vex_sdk::vexFileRead(buf_ptr.cast(), 1, len, self.0.0) }; + if read < 0 { + Err(io::Error::new( + io::ErrorKind::Other, + "Could not read from file", + )) + } else { + Ok(read as usize) + } + } + + pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result { + todo!() + } + + pub fn is_read_vectored(&self) -> bool { + todo!() + } + + pub fn read_buf(&self, _cursor: BorrowedCursor<'_>) -> io::Result<()> { + todo!() + } + + pub fn write(&self, _buf: &[u8]) -> io::Result { + todo!() + } + + pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result { + todo!() + } + + pub fn is_write_vectored(&self) -> bool { + todo!() + } + + pub fn flush(&self) -> io::Result<()> { + todo!() + } + + pub fn seek(&self, _pos: SeekFrom) -> io::Result { + todo!() + } + + pub fn duplicate(&self) -> io::Result { + todo!() + } + + pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { + todo!() + } + + pub fn set_times(&self, _times: FileTimes) -> io::Result<()> { + todo!() + } +} + +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 { + f.debug_struct("File").finish_non_exhaustive() + } +} + +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<()> { + unsupported() +} + +pub fn rmdir(_p: &Path) -> io::Result<()> { + unsupported() +} + +pub fn remove_dir_all(_path: &Path) -> io::Result<()> { + unsupported() +} + +pub fn try_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/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index cb80cf675a09c..bd99234b9e192 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -1,9 +1,7 @@ pub mod alloc; #[path = "../unsupported/args.rs"] pub mod args; -#[path = "../unsupported/env.rs"] pub mod env; -#[path = "../unsupported/fs.rs"] pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; From 9aeeaa0e727eacaa61bc14ab6b966e3f95592f0a Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:19:56 -0400 Subject: [PATCH 17/72] add support for more missing file operations --- library/std/src/sys/pal/vexos/fs.rs | 48 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 005dc2645990a..ba5a704dbb768 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -6,9 +6,9 @@ use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; use crate::sys::unsupported; -struct Fd(*mut vex_sdk::FIL); +struct FileDesc(*mut vex_sdk::FIL); -pub struct File(Fd); +pub struct File(FileDesc); //TODO: We may be able to get some of this info #[derive(Clone)] @@ -173,7 +173,7 @@ impl File { if file.is_null() { Err(io::Error::new(io::ErrorKind::NotFound, "Could not open file")) } else { - Ok(Self(Fd(file))) + Ok(Self(FileDesc(file))) } } @@ -182,15 +182,15 @@ impl File { } pub fn fsync(&self) -> io::Result<()> { - todo!() + self.flush() } pub fn datasync(&self) -> io::Result<()> { - todo!() + self.flush() } pub fn truncate(&self, _size: u64) -> io::Result<()> { - todo!() + unsupported() } pub fn read(&self, buf: &mut [u8]) -> io::Result { @@ -198,57 +198,59 @@ impl File { let buf_ptr = buf.as_mut_ptr(); let read = unsafe { vex_sdk::vexFileRead(buf_ptr.cast(), 1, len, self.0.0) }; if read < 0 { - Err(io::Error::new( - io::ErrorKind::Other, - "Could not read from file", - )) + Err(io::Error::new(io::ErrorKind::Other, "Could not read from file")) } else { Ok(read as usize) } } - pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result { - todo!() + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + crate::io::default_read_vectored(|buf| self.read(buf), bufs) } + #[inline] pub fn is_read_vectored(&self) -> bool { - todo!() + false } - pub fn read_buf(&self, _cursor: BorrowedCursor<'_>) -> io::Result<()> { - todo!() + pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + crate::io::default_read_buf(|b| self.read(b), cursor) } pub fn write(&self, _buf: &[u8]) -> io::Result { todo!() } - pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result { - todo!() + pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + crate::io::default_write_vectored(|buf| self.write(buf), bufs) } + #[inline] pub fn is_write_vectored(&self) -> bool { - todo!() + false } pub fn flush(&self) -> io::Result<()> { - todo!() + unsafe { + vex_sdk::vexFileSync(self.0.0); + } + Ok(()) } pub fn seek(&self, _pos: SeekFrom) -> io::Result { - todo!() + todo!(); } pub fn duplicate(&self) -> io::Result { - todo!() + unsupported!() } pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { - todo!() + unsupported() } pub fn set_times(&self, _times: FileTimes) -> io::Result<()> { - todo!() + unsupported() } } From 4f59642591a83d9f737364bee0f5df4d54b92930 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Thu, 18 Jul 2024 12:04:56 -0700 Subject: [PATCH 18/72] feat: file writes vectored writes and vectored reads --- library/std/src/sys/pal/vexos/fs.rs | 32 ++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index ba5a704dbb768..7368eaecf6041 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -45,7 +45,7 @@ impl FileAttr { } pub fn perm(&self) -> FilePermissions { - todo!() + FilePermissions } pub fn file_type(&self) -> FileType { @@ -149,6 +149,13 @@ impl OpenOptions { impl File { pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { + let fs_status = unsafe { vex_sdk::vexFileMountSD() }; + match fs_status { + vex_sdk::FRESULT::FR_OK => (), + //TODO: cover more results + _ => return Err(io::Error::new(io::ErrorKind::NotFound, "SD card cannot be written or read from")), + } + let path = CString::new(path.as_os_str().as_encoded_bytes()).map_err(|_| { io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte") })?; @@ -205,7 +212,7 @@ impl File { } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - crate::io::default_read_vectored(|buf| self.read(buf), bufs) + crate::io::default_read_vectored(|b| self.read(b), bufs) } #[inline] @@ -217,12 +224,22 @@ impl File { crate::io::default_read_buf(|b| self.read(b), cursor) } - pub fn write(&self, _buf: &[u8]) -> io::Result { - todo!() + pub fn write(&self, buf: &[u8]) -> io::Result { + let len = buf.len(); + let buf_ptr = buf.as_ptr(); + let written = unsafe { vex_sdk::vexFileWrite(buf_ptr.cast_mut().cast(), 1, len as _, self.0.0) }; + if written < 0 { + Err(io::Error::new( + io::ErrorKind::Other, + "Could not write to file", + )) + } else { + Ok(written as usize) + } } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - crate::io::default_write_vectored(|buf| self.write(buf), bufs) + crate::io::default_write_vectored(|b| self.write(b), bufs) } #[inline] @@ -269,6 +286,11 @@ impl fmt::Debug for File { f.debug_struct("File").finish_non_exhaustive() } } +impl Drop for File { + fn drop(&mut self) { + unsafe { vex_sdk::vexFileClose(self.0.0) }; + } +} pub fn readdir(_p: &Path) -> io::Result { unsupported() From 1900699e18b8bee4e3ce5125203f318640514d08 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 21 Jul 2024 13:58:58 -0400 Subject: [PATCH 19/72] add helper for mapping FRESULT values --- library/std/src/sys/pal/vexos/fs.rs | 132 +++++++++++++++++++++++----- 1 file changed, 109 insertions(+), 23 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 7368eaecf6041..95eb9707539ff 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -6,9 +6,12 @@ use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; use crate::sys::unsupported; +#[derive(Debug)] struct FileDesc(*mut vex_sdk::FIL); -pub struct File(FileDesc); +pub struct File { + fd: FileDesc, +} //TODO: We may be able to get some of this info #[derive(Clone)] @@ -149,12 +152,8 @@ impl OpenOptions { impl File { pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { - let fs_status = unsafe { vex_sdk::vexFileMountSD() }; - match fs_status { - vex_sdk::FRESULT::FR_OK => (), - //TODO: cover more results - _ => return Err(io::Error::new(io::ErrorKind::NotFound, "SD card cannot be written or read from")), - } + // Mount sdcard volume as FAT filesystem + map_fresult(unsafe { vex_sdk::vexFileMountSD() })?; let path = CString::new(path.as_os_str().as_encoded_bytes()).map_err(|_| { io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte") @@ -180,7 +179,7 @@ impl File { if file.is_null() { Err(io::Error::new(io::ErrorKind::NotFound, "Could not open file")) } else { - Ok(Self(FileDesc(file))) + Ok(Self { fd: FileDesc(file) }) } } @@ -203,7 +202,7 @@ impl File { pub fn read(&self, buf: &mut [u8]) -> io::Result { let len = buf.len() as _; let buf_ptr = buf.as_mut_ptr(); - let read = unsafe { vex_sdk::vexFileRead(buf_ptr.cast(), 1, len, self.0.0) }; + let read = unsafe { vex_sdk::vexFileRead(buf_ptr.cast(), 1, len, self.fd.0) }; if read < 0 { Err(io::Error::new(io::ErrorKind::Other, "Could not read from file")) } else { @@ -227,12 +226,10 @@ impl File { pub fn write(&self, buf: &[u8]) -> io::Result { let len = buf.len(); let buf_ptr = buf.as_ptr(); - let written = unsafe { vex_sdk::vexFileWrite(buf_ptr.cast_mut().cast(), 1, len as _, self.0.0) }; + let written = + unsafe { vex_sdk::vexFileWrite(buf_ptr.cast_mut().cast(), 1, len as _, self.fd.0) }; if written < 0 { - Err(io::Error::new( - io::ErrorKind::Other, - "Could not write to file", - )) + Err(io::Error::new(io::ErrorKind::Other, "Could not write to file")) } else { Ok(written as usize) } @@ -249,7 +246,7 @@ impl File { pub fn flush(&self) -> io::Result<()> { unsafe { - vex_sdk::vexFileSync(self.0.0); + vex_sdk::vexFileSync(self.fd.0); } Ok(()) } @@ -259,7 +256,7 @@ impl File { } pub fn duplicate(&self) -> io::Result { - unsupported!() + unsupported() } pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { @@ -283,17 +280,17 @@ impl DirBuilder { impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("File").finish_non_exhaustive() + f.debug_struct("File").field("fd", &self.fd.0).finish() } } impl Drop for File { fn drop(&mut self) { - unsafe { vex_sdk::vexFileClose(self.0.0) }; + unsafe { vex_sdk::vexFileClose(self.fd.0) }; } } pub fn readdir(_p: &Path) -> io::Result { - unsupported() + todo!() } pub fn unlink(_p: &Path) -> io::Result<()> { @@ -317,7 +314,7 @@ pub fn remove_dir_all(_path: &Path) -> io::Result<()> { } pub fn try_exists(_path: &Path) -> io::Result { - unsupported() + todo!() } pub fn readlink(_p: &Path) -> io::Result { @@ -333,7 +330,7 @@ pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { } pub fn stat(_p: &Path) -> io::Result { - unsupported() + todo!() } pub fn lstat(_p: &Path) -> io::Result { @@ -344,6 +341,95 @@ pub fn canonicalize(_p: &Path) -> io::Result { unsupported() } -pub fn copy(_from: &Path, _to: &Path) -> io::Result { - unsupported() +pub fn copy(from: &Path, to: &Path) -> io::Result { + use crate::fs::File; + + let mut reader = File::open(from)?; + let mut writer = File::create(to)?; + + io::copy(&mut reader, &mut writer) +} + +fn map_fresult(fresult: vex_sdk::FRESULT) -> io::Result<()> { + // VEX presumably uses a derivative of FatFs (most likely the xilffs library) + // for sdcard filesystem functions. + // + // Documentation for each FRESULT originates from here: + // + match fresult { + vex_sdk::FRESULT::FR_OK => Ok(()), + vex_sdk::FRESULT::FR_DISK_ERR => Err(io::Error::new( + io::ErrorKind::Uncategorized, + "internal function reported an unrecoverable hard error", + )), + vex_sdk::FRESULT::FR_INT_ERR => Err(io::Error::new( + io::ErrorKind::Uncategorized, + "assertion failed and an insanity is detected in the internal process", + )), + vex_sdk::FRESULT::FR_NOT_READY => Err(io::Error::new( + io::ErrorKind::Uncategorized, + "the storage device could not be prepared to work", + )), + vex_sdk::FRESULT::FR_NO_FILE => { + Err(io::Error::new(io::ErrorKind::NotFound, "could not find the file in the directory")) + } + vex_sdk::FRESULT::FR_NO_PATH => Err(io::Error::new( + io::ErrorKind::NotFound, + "a directory in the path name could not be found", + )), + vex_sdk::FRESULT::FR_INVALID_NAME => Err(io::Error::new( + io::ErrorKind::InvalidInput, + "the given string is invalid as a path name", + )), + vex_sdk::FRESULT::FR_DENIED => Err(io::Error::new( + io::ErrorKind::PermissionDenied, + "the required access for this operation was denied", + )), + vex_sdk::FRESULT::FR_EXIST => Err(io::Error::new( + io::ErrorKind::AlreadyExists, + "an object with the same name already exists in the directory", + )), + vex_sdk::FRESULT::FR_INVALID_OBJECT => Err(io::Error::new( + io::ErrorKind::Uncategorized, + "invalid or null file/directory object", + )), + vex_sdk::FRESULT::FR_WRITE_PROTECTED => Err(io::Error::new( + io::ErrorKind::PermissionDenied, + "a write operation was performed on write-protected media", + )), + vex_sdk::FRESULT::FR_INVALID_DRIVE => Err(io::Error::new( + io::ErrorKind::InvalidInput, + "an invalid drive number was specified in the path name", + )), + vex_sdk::FRESULT::FR_NOT_ENABLED => Err(io::Error::new( + io::ErrorKind::Uncategorized, + "work area for the logical drive has not been registered", + )), + vex_sdk::FRESULT::FR_NO_FILESYSTEM => Err(io::Error::new( + io::ErrorKind::Uncategorized, + "valid FAT volume could not be found on the drive", + )), + vex_sdk::FRESULT::FR_MKFS_ABORTED => { + Err(io::Error::new(io::ErrorKind::Uncategorized, "failed to create filesystem volume")) + } + vex_sdk::FRESULT::FR_TIMEOUT => Err(io::Error::new( + io::ErrorKind::TimedOut, + "the function was canceled due to a timeout of thread-safe control", + )), + vex_sdk::FRESULT::FR_LOCKED => Err(io::Error::new( + io::ErrorKind::Uncategorized, + "the operation to the object was rejected by file sharing control", + )), + vex_sdk::FRESULT::FR_NOT_ENOUGH_CORE => { + Err(io::Error::new(io::ErrorKind::OutOfMemory, "not enough memory for the operation")) + } + vex_sdk::FRESULT::FR_TOO_MANY_OPEN_FILES => Err(io::Error::new( + io::ErrorKind::Uncategorized, + "maximum number of open files has been reached", + )), + vex_sdk::FRESULT::FR_INVALID_PARAMETER => { + Err(io::Error::new(io::ErrorKind::InvalidInput, "a given parameter was invalid")) + } + _ => unreachable!(), // C-style enum + } } From 92d44bc2e013cfa9b244b530bd83520b1f4bd038 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 21 Jul 2024 12:53:31 -0700 Subject: [PATCH 20/72] add: try_file_exists and stat --- library/std/src/sys/pal/vexos/fs.rs | 76 ++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 95eb9707539ff..aa7e8540292f8 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -15,7 +15,9 @@ pub struct File { //TODO: We may be able to get some of this info #[derive(Clone)] -pub struct FileAttr; +pub struct FileAttr { + size: u64, +} pub struct ReadDir(!); @@ -26,6 +28,7 @@ pub struct OpenOptions { read: bool, write: bool, append: bool, + create_new: bool, } #[derive(Copy, Clone, Debug, Default)] @@ -44,7 +47,7 @@ pub struct DirBuilder {} impl FileAttr { pub fn size(&self) -> u64 { - todo!() + self.size } pub fn perm(&self) -> FilePermissions { @@ -131,7 +134,7 @@ impl DirEntry { impl OpenOptions { pub fn new() -> OpenOptions { - OpenOptions { read: false, write: false, append: false } + OpenOptions { read: false, write: false, append: false, create_new: false } } pub fn read(&mut self, read: bool) { @@ -143,11 +146,17 @@ impl OpenOptions { pub fn append(&mut self, append: bool) { self.append = append; } - pub fn truncate(&mut self, _truncate: bool) {} + pub fn truncate(&mut self, truncate: bool) { + if truncate { + panic!("Truncation is not supported") + } + } pub fn create(&mut self, create: bool) { self.write = create; } - pub fn create_new(&mut self, _create_new: bool) {} + pub fn create_new(&mut self, create_new: bool) { + self.create_new = create_new; + } } impl File { @@ -159,6 +168,18 @@ impl File { io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte") })?; + if opts.create_new { + let file_exists = unsafe { + vex_sdk::vexFileStatus(path.as_ptr()) + }; + if file_exists != 0 { + return Err(io::Error::new( + io::ErrorKind::AlreadyExists, + "File already exists" + )) + } + } + let file = if opts.read && !opts.write { // The second argument to this function is ignored. // Open in read only mode @@ -313,8 +334,19 @@ pub fn remove_dir_all(_path: &Path) -> io::Result<()> { unsupported() } -pub fn try_exists(_path: &Path) -> io::Result { - todo!() +pub fn try_exists(path: &Path) -> io::Result { + let path = CString::new(path.as_os_str().as_encoded_bytes()).map_err(|_| { + io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte") + })?; + + let file_exists = unsafe { + vex_sdk::vexFileStatus(path.as_ptr()) + }; + if file_exists != 0 { + Ok(true) + } else { + Ok(false) + } } pub fn readlink(_p: &Path) -> io::Result { @@ -329,12 +361,34 @@ pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { unsupported() } -pub fn stat(_p: &Path) -> io::Result { - todo!() +pub fn stat(p: &Path) -> io::Result { + let mut opts = OpenOptions::new(); + opts.read(true); + let file = File::open(p, &opts)?; + let fd = file.fd.0; + + const SEEK_END: i32 = 2; + + let end = unsafe { + map_fresult(vex_sdk::vexFileSeek(fd, 0, SEEK_END))?; + vex_sdk::vexFileTell(fd) + }; + + if end >= 0 { + Ok(FileAttr { + size: end as u64, + }) + } else { + Err(io::Error::new( + io::ErrorKind::NotSeekable, + "Failed to seek file" + )) + } } -pub fn lstat(_p: &Path) -> io::Result { - unsupported() +pub fn lstat(p: &Path) -> io::Result { + // Symlinks aren't supported in our filesystem + stat(p) } pub fn canonicalize(_p: &Path) -> io::Result { From 62b6344109e995e7f674515e601d49977fe57015 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 21 Jul 2024 13:26:58 -0700 Subject: [PATCH 21/72] add: fileattr functions --- library/std/src/sys/pal/vexos/fs.rs | 46 +++++++++++------------------ 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index aa7e8540292f8..a56ea5c4da0d5 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -55,19 +55,21 @@ impl FileAttr { } pub fn file_type(&self) -> FileType { - todo!() + FileType { + is_dir: false, + } } pub fn modified(&self) -> io::Result { - todo!() + unsupported() } pub fn accessed(&self) -> io::Result { - todo!() + unsupported() } pub fn created(&self) -> io::Result { - todo!() + unsupported() } } @@ -146,11 +148,7 @@ impl OpenOptions { pub fn append(&mut self, append: bool) { self.append = append; } - pub fn truncate(&mut self, truncate: bool) { - if truncate { - panic!("Truncation is not supported") - } - } + pub fn truncate(&mut self, _truncate: bool) {} pub fn create(&mut self, create: bool) { self.write = create; } @@ -169,14 +167,9 @@ impl File { })?; if opts.create_new { - let file_exists = unsafe { - vex_sdk::vexFileStatus(path.as_ptr()) - }; + let file_exists = unsafe { vex_sdk::vexFileStatus(path.as_ptr()) }; if file_exists != 0 { - return Err(io::Error::new( - io::ErrorKind::AlreadyExists, - "File already exists" - )) + return Err(io::Error::new(io::ErrorKind::AlreadyExists, "File already exists")); } } @@ -335,18 +328,11 @@ pub fn remove_dir_all(_path: &Path) -> io::Result<()> { } pub fn try_exists(path: &Path) -> io::Result { - let path = CString::new(path.as_os_str().as_encoded_bytes()).map_err(|_| { - io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte") - })?; + let path = CString::new(path.as_os_str().as_encoded_bytes()) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte"))?; - let file_exists = unsafe { - vex_sdk::vexFileStatus(path.as_ptr()) - }; - if file_exists != 0 { - Ok(true) - } else { - Ok(false) - } + let file_exists = unsafe { vex_sdk::vexFileStatus(path.as_ptr()) }; + if file_exists != 0 { Ok(true) } else { Ok(false) } } pub fn readlink(_p: &Path) -> io::Result { @@ -368,10 +354,14 @@ pub fn stat(p: &Path) -> io::Result { let fd = file.fd.0; const SEEK_END: i32 = 2; + const SEEK_SET: i32 = 0; let end = unsafe { + let cur = vex_sdk::vexFileTell(fd); map_fresult(vex_sdk::vexFileSeek(fd, 0, SEEK_END))?; - vex_sdk::vexFileTell(fd) + let end = vex_sdk::vexFileTell(fd); + map_fresult(vex_sdk::vexFileSeek(fd, cur as _, SEEK_SET))?; + end }; if end >= 0 { From cf90d393e14ebc5fbb21a418e01f047639072c65 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 21 Jul 2024 14:39:26 -0700 Subject: [PATCH 22/72] fix: check current position in file when getting size --- library/std/src/sys/pal/vexos/fs.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index a56ea5c4da0d5..2a4c9511d45a3 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -55,9 +55,7 @@ impl FileAttr { } pub fn file_type(&self) -> FileType { - FileType { - is_dir: false, - } + FileType { is_dir: false } } pub fn modified(&self) -> io::Result { @@ -358,6 +356,9 @@ pub fn stat(p: &Path) -> io::Result { let end = unsafe { let cur = vex_sdk::vexFileTell(fd); + if cur < 0 { + return Err(io::Error::new(io::ErrorKind::NotSeekable, "Failed to seek file")); + } map_fresult(vex_sdk::vexFileSeek(fd, 0, SEEK_END))?; let end = vex_sdk::vexFileTell(fd); map_fresult(vex_sdk::vexFileSeek(fd, cur as _, SEEK_SET))?; @@ -365,14 +366,9 @@ pub fn stat(p: &Path) -> io::Result { }; if end >= 0 { - Ok(FileAttr { - size: end as u64, - }) + Ok(FileAttr { size: end as u64 }) } else { - Err(io::Error::new( - io::ErrorKind::NotSeekable, - "Failed to seek file" - )) + Err(io::Error::new(io::ErrorKind::NotSeekable, "Failed to seek file")) } } From ff1aaf8d9b357f1a8d483de8a8487a973d0efe34 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 21 Jul 2024 15:23:45 -0700 Subject: [PATCH 23/72] refactor: pseudorandom hashmap keys --- library/std/src/sys/pal/vexos/mod.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index bd99234b9e192..2469b6fa855ed 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -21,6 +21,7 @@ pub mod thread_local_key; pub mod time; use crate::{arch::asm, ptr::{self, addr_of_mut}}; +use crate::hash::{DefaultHasher, Hasher}; #[cfg(not(test))] #[no_mangle] @@ -87,6 +88,18 @@ pub fn abort_internal() -> ! { } } +fn hash_time() -> u64 { + let mut hasher = DefaultHasher::new(); + // The closest we can get to a random number is the time since program start + let time = unsafe { + vex_sdk::vexSystemHighResTimeGet() + }; + hasher.write_u64(time); + hasher.finish() +} + pub fn hashmap_random_keys() -> (u64, u64) { - (1, 2) + let key1 = hash_time(); + let key2 = hash_time(); + (key1, key2) } From 5e78476a8ae239fac1e4500471f4016ac69c7334 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 22 Jul 2024 14:39:48 -0700 Subject: [PATCH 24/72] fix: support File::file_attr and dissalow read and write mode at the same time --- library/std/src/sys/pal/vexos/fs.rs | 60 ++++++++++++++++++----------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 2a4c9511d45a3..785639ad1d340 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -28,6 +28,7 @@ pub struct OpenOptions { read: bool, write: bool, append: bool, + truncate: bool, create_new: bool, } @@ -46,6 +47,19 @@ pub struct FileType { pub struct DirBuilder {} impl FileAttr { + /// Creates a FileAttr by getting data from an opened file. + fn from_fd(fd: *mut vex_sdk::FIL) -> io::Result { + let size = unsafe { + vex_sdk::vexFileSize(fd) + }; + + if size >= 0 { + Ok(Self { size: size as u64 }) + } else { + Err(io::Error::new(io::ErrorKind::NotSeekable, "Failed to seek file")) + } + } + pub fn size(&self) -> u64 { self.size } @@ -134,7 +148,7 @@ impl DirEntry { impl OpenOptions { pub fn new() -> OpenOptions { - OpenOptions { read: false, write: false, append: false, create_new: false } + OpenOptions { read: false, write: false, append: false, truncate: false, create_new: false } } pub fn read(&mut self, read: bool) { @@ -146,7 +160,9 @@ impl OpenOptions { pub fn append(&mut self, append: bool) { self.append = append; } - pub fn truncate(&mut self, _truncate: bool) {} + pub fn truncate(&mut self, truncate: bool) { + self.truncate = truncate; + } pub fn create(&mut self, create: bool) { self.write = create; } @@ -164,6 +180,12 @@ impl File { io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte") })?; + if opts.write && opts.read { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Files cannot be opened with read and write access", + )); + } if opts.create_new { let file_exists = unsafe { vex_sdk::vexFileStatus(path.as_ptr()) }; if file_exists != 0 { @@ -178,9 +200,19 @@ impl File { } else if opts.write && opts.append { // Open in read/write and append mode unsafe { vex_sdk::vexFileOpenWrite(path.as_ptr()) } - } else if opts.write { + } else if opts.write && opts.truncate { // Open in read/write mode unsafe { vex_sdk::vexFileOpenCreate(path.as_ptr()) } + } else if opts.write { + // Open in read/write and overwrite mode + unsafe { + // Open in read/write and append mode + let fd = vex_sdk::vexFileOpenWrite(path.as_ptr()); + // Seek to beginning of the file + vex_sdk::vexFileSeek(fd, 0, 0); + + fd + } } else { return Err(io::Error::new( io::ErrorKind::InvalidInput, @@ -196,7 +228,7 @@ impl File { } pub fn file_attr(&self) -> io::Result { - todo!() + FileAttr::from_fd(self.fd.0) } pub fn fsync(&self) -> io::Result<()> { @@ -351,25 +383,7 @@ pub fn stat(p: &Path) -> io::Result { let file = File::open(p, &opts)?; let fd = file.fd.0; - const SEEK_END: i32 = 2; - const SEEK_SET: i32 = 0; - - let end = unsafe { - let cur = vex_sdk::vexFileTell(fd); - if cur < 0 { - return Err(io::Error::new(io::ErrorKind::NotSeekable, "Failed to seek file")); - } - map_fresult(vex_sdk::vexFileSeek(fd, 0, SEEK_END))?; - let end = vex_sdk::vexFileTell(fd); - map_fresult(vex_sdk::vexFileSeek(fd, cur as _, SEEK_SET))?; - end - }; - - if end >= 0 { - Ok(FileAttr { size: end as u64 }) - } else { - Err(io::Error::new(io::ErrorKind::NotSeekable, "Failed to seek file")) - } + FileAttr::from_fd(fd) } pub fn lstat(p: &Path) -> io::Result { From a5b9f71c08f1b590457503424a18dfcb8d4fb5b1 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 22 Jul 2024 15:19:26 -0700 Subject: [PATCH 25/72] feat: seek implementation --- library/std/src/sys/pal/vexos/fs.rs | 85 +++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 785639ad1d340..43f637c30ce27 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -49,10 +49,8 @@ pub struct DirBuilder {} impl FileAttr { /// Creates a FileAttr by getting data from an opened file. fn from_fd(fd: *mut vex_sdk::FIL) -> io::Result { - let size = unsafe { - vex_sdk::vexFileSize(fd) - }; - + let size = unsafe { vex_sdk::vexFileSize(fd) }; + if size >= 0 { Ok(Self { size: size as u64 }) } else { @@ -295,8 +293,83 @@ impl File { Ok(()) } - pub fn seek(&self, _pos: SeekFrom) -> io::Result { - todo!(); + fn tell(&self) -> io::Result { + let position = unsafe { vex_sdk::vexFileTell(self.fd.0) }; + position.try_into().map_err(|_| { + io::Error::new(io::ErrorKind::InvalidData, "Failed to get current location in file") + }) + } + + pub fn seek(&self, pos: SeekFrom) -> io::Result { + const SEEK_SET: i32 = 0; + const SEEK_CUR: i32 = 1; + const SEEK_END: i32 = 2; + + fn try_convert_offset>(offset: T) -> io::Result { + offset.try_into().map_err(|_| { + io::Error::new( + io::ErrorKind::InvalidInput, + "Cannot seek to an offset too large to fit in a 32 bit integer", + ) + }) + } + + match pos { + SeekFrom::Start(offset) => unsafe { + map_fresult(vex_sdk::vexFileSeek(self.fd.0, try_convert_offset(offset)?, SEEK_SET))? + }, + + // The VEX SDK does not allow seeking with negative offsets. + // That means we need to calculate the offset from the start for both of these. + SeekFrom::End(offset) => unsafe { + // If our offset is positive, everything is easy + if offset >= 0 { + map_fresult(vex_sdk::vexFileSeek( + self.fd.0, + try_convert_offset(offset)?, + SEEK_END, + ))? + } else { + // Get the position of the end of the file... + map_fresult(vex_sdk::vexFileSeek( + self.fd.0, + try_convert_offset(offset)?, + SEEK_END, + ))?; + // The number returned by the VEX SDK tell is stored as a 32 bit interger, + // and therefore this conversion cannot fail. + let position = self.tell()? as i64; + + // Offset from that position + let new_position = position + offset; + map_fresult(vex_sdk::vexFileSeek( + self.fd.0, + try_convert_offset(new_position)?, + SEEK_SET, + ))? + } + }, + SeekFrom::Current(offset) => unsafe { + if offset >= 0 { + map_fresult(vex_sdk::vexFileSeek( + self.fd.0, + try_convert_offset(offset)?, + SEEK_CUR, + ))? + } else { + let position = self.tell()? as i64; + + let new_position = position + offset; + map_fresult(vex_sdk::vexFileSeek( + self.fd.0, + try_convert_offset(new_position)?, + SEEK_SET, + ))? + } + }, + } + + Ok(self.tell()?) } pub fn duplicate(&self) -> io::Result { From 1878f62743d203e9b12d9dd643423e7badae2e01 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 22 Jul 2024 18:40:53 -0700 Subject: [PATCH 26/72] feat: almost working directory reading --- library/std/src/sys/pal/vexos/fs.rs | 104 +++++++++++++++++++++------- 1 file changed, 80 insertions(+), 24 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 43f637c30ce27..614dfc133df9a 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -17,11 +17,18 @@ pub struct File { #[derive(Clone)] pub struct FileAttr { size: u64, + is_dir: bool, } -pub struct ReadDir(!); +#[derive(Debug)] +pub struct ReadDir { + entries: Vec, +} -pub struct DirEntry(!); +#[derive(Debug)] +pub struct DirEntry { + path: PathBuf, +} #[derive(Clone, Debug)] pub struct OpenOptions { @@ -52,9 +59,31 @@ impl FileAttr { let size = unsafe { vex_sdk::vexFileSize(fd) }; if size >= 0 { - Ok(Self { size: size as u64 }) + Ok(Self { size: size as u64, is_dir: false }) + } else { + Err(io::Error::new(io::ErrorKind::InvalidData, "Failed to get file size")) + } + } + + fn from_path(path: &Path) -> io::Result { + let c_path = CString::new(path.as_os_str().as_encoded_bytes()).map_err(|_| { + io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte") + })?; + + let file_type = unsafe { vex_sdk::vexFileStatus(c_path.as_ptr()) }; + let is_dir = file_type == 3; + println!("{is_dir}"); + + // We can't get the size if its a directory because we cant open it as a file + if is_dir { + Ok(Self { size: 0, is_dir: true }) } else { - Err(io::Error::new(io::ErrorKind::NotSeekable, "Failed to seek file")) + let mut opts = OpenOptions::new(); + opts.read(true); + let file = File::open(path, &opts)?; + let fd = file.fd.0; + + Self::from_fd(fd) } } @@ -67,7 +96,7 @@ impl FileAttr { } pub fn file_type(&self) -> FileType { - FileType { is_dir: false } + FileType { is_dir: self.is_dir } } pub fn modified(&self) -> io::Result { @@ -112,35 +141,32 @@ impl FileType { } } -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 + self.entries.pop().map(Ok) } } impl DirEntry { pub fn path(&self) -> PathBuf { - self.0 + self.path.clone() } pub fn file_name(&self) -> OsString { - self.0 + self.path + .file_name() + .unwrap_or(crate::ffi::OsStr::new("")) + .to_os_string() } pub fn metadata(&self) -> io::Result { - self.0 + stat(&self.path) } pub fn file_type(&self) -> io::Result { - self.0 + Ok(self.metadata()?.file_type()) } } @@ -406,8 +432,43 @@ impl Drop for File { } } -pub fn readdir(_p: &Path) -> io::Result { - todo!() +pub fn readdir(p: &Path) -> io::Result { + if !stat(p)?.file_type().is_dir() { + return Err(io::Error::new(io::ErrorKind::InvalidInput, "Given directory was not a path")); + } + + // getting directory entries does not work with trailing slashes + let path = p + .to_str() + .ok_or(io::Error::new(io::ErrorKind::InvalidInput, "Path contained invalid characters"))? + .trim_end_matches("/"); + let path = CString::new(path.as_bytes()) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "Path contained a null byte"))?; + + //TODO: Figure out if there is any way to check the number of entries in a directory/the needed length + let mut filenames_buffer = [0u8; 1000]; + unsafe { + vex_sdk::vexFileDirectoryGet( + path.as_ptr(), + filenames_buffer.as_mut_ptr().cast(), + filenames_buffer.len() as _, + ); + } + let filenames_buffer = filenames_buffer.to_vec(); + // stop at null-terminator + let filenames = match filenames_buffer.split(|&e| e == 0).next() { + Some(filenames) => filenames, + None => &filenames_buffer + }; + let filenames = String::from_utf8(filenames.to_vec()).map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte"))?; + let paths = filenames.split('\n').map(|filename| { + let mut path = PathBuf::new(); + path.push(p); + path.push(filename); + DirEntry { path } + }).collect::>(); + + Ok(ReadDir { entries: paths }) } pub fn unlink(_p: &Path) -> io::Result<()> { @@ -451,12 +512,7 @@ pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { } pub fn stat(p: &Path) -> io::Result { - let mut opts = OpenOptions::new(); - opts.read(true); - let file = File::open(p, &opts)?; - let fd = file.fd.0; - - FileAttr::from_fd(fd) + FileAttr::from_path(p) } pub fn lstat(p: &Path) -> io::Result { From 0aff419053dd72ee69d9be17c327d8be2872c744 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 22 Jul 2024 18:47:18 -0700 Subject: [PATCH 27/72] fix: remove trailing slashes sooner --- library/std/src/sys/pal/vexos/fs.rs | 42 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 614dfc133df9a..0d248f3770b28 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -155,10 +155,7 @@ impl DirEntry { } pub fn file_name(&self) -> OsString { - self.path - .file_name() - .unwrap_or(crate::ffi::OsStr::new("")) - .to_os_string() + self.path.file_name().unwrap_or(crate::ffi::OsStr::new("")).to_os_string() } pub fn metadata(&self) -> io::Result { @@ -433,16 +430,21 @@ impl Drop for File { } pub fn readdir(p: &Path) -> io::Result { + // getting directory entries does not work with trailing slashes + let p = Path::new( + p.to_str() + .ok_or(io::Error::new( + io::ErrorKind::InvalidInput, + "Path contained invalid characters", + ))? + .trim_end_matches("/"), + ); + if !stat(p)?.file_type().is_dir() { return Err(io::Error::new(io::ErrorKind::InvalidInput, "Given directory was not a path")); } - // getting directory entries does not work with trailing slashes - let path = p - .to_str() - .ok_or(io::Error::new(io::ErrorKind::InvalidInput, "Path contained invalid characters"))? - .trim_end_matches("/"); - let path = CString::new(path.as_bytes()) + let path = CString::new(p.as_os_str().as_encoded_bytes()) .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "Path contained a null byte"))?; //TODO: Figure out if there is any way to check the number of entries in a directory/the needed length @@ -458,15 +460,19 @@ pub fn readdir(p: &Path) -> io::Result { // stop at null-terminator let filenames = match filenames_buffer.split(|&e| e == 0).next() { Some(filenames) => filenames, - None => &filenames_buffer + None => &filenames_buffer, }; - let filenames = String::from_utf8(filenames.to_vec()).map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte"))?; - let paths = filenames.split('\n').map(|filename| { - let mut path = PathBuf::new(); - path.push(p); - path.push(filename); - DirEntry { path } - }).collect::>(); + let filenames = String::from_utf8(filenames.to_vec()) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte"))?; + let paths = filenames + .split('\n') + .map(|filename| { + let mut path = PathBuf::new(); + path.push(p); + path.push(filename); + DirEntry { path } + }) + .collect::>(); Ok(ReadDir { entries: paths }) } From 0e0579aee8639e6bac544420464117e1c3d895f8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Fri, 26 Jul 2024 23:22:39 -0400 Subject: [PATCH 28/72] remove test code and document filesystem quirks --- library/std/src/sys/pal/vexos/fs.rs | 61 +++++--------------------- library/std/src/sys/pal/vexos/mod.rs | 3 ++ library/std/src/sys/pal/vexos/stdio.rs | 5 ++- 3 files changed, 18 insertions(+), 51 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 0d248f3770b28..f5cb0a961cf22 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -13,7 +13,6 @@ pub struct File { fd: FileDesc, } -//TODO: We may be able to get some of this info #[derive(Clone)] pub struct FileAttr { size: u64, @@ -72,7 +71,6 @@ impl FileAttr { let file_type = unsafe { vex_sdk::vexFileStatus(c_path.as_ptr()) }; let is_dir = file_type == 3; - println!("{is_dir}"); // We can't get the size if its a directory because we cant open it as a file if is_dir { @@ -342,7 +340,7 @@ impl File { map_fresult(vex_sdk::vexFileSeek(self.fd.0, try_convert_offset(offset)?, SEEK_SET))? }, - // The VEX SDK does not allow seeking with negative offsets. + // vexOS does not allow seeking with negative offsets. // That means we need to calculate the offset from the start for both of these. SeekFrom::End(offset) => unsafe { // If our offset is positive, everything is easy @@ -429,52 +427,15 @@ impl Drop for File { } } -pub fn readdir(p: &Path) -> io::Result { - // getting directory entries does not work with trailing slashes - let p = Path::new( - p.to_str() - .ok_or(io::Error::new( - io::ErrorKind::InvalidInput, - "Path contained invalid characters", - ))? - .trim_end_matches("/"), - ); - - if !stat(p)?.file_type().is_dir() { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "Given directory was not a path")); - } - - let path = CString::new(p.as_os_str().as_encoded_bytes()) - .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "Path contained a null byte"))?; - - //TODO: Figure out if there is any way to check the number of entries in a directory/the needed length - let mut filenames_buffer = [0u8; 1000]; - unsafe { - vex_sdk::vexFileDirectoryGet( - path.as_ptr(), - filenames_buffer.as_mut_ptr().cast(), - filenames_buffer.len() as _, - ); - } - let filenames_buffer = filenames_buffer.to_vec(); - // stop at null-terminator - let filenames = match filenames_buffer.split(|&e| e == 0).next() { - Some(filenames) => filenames, - None => &filenames_buffer, - }; - let filenames = String::from_utf8(filenames.to_vec()) - .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte"))?; - let paths = filenames - .split('\n') - .map(|filename| { - let mut path = PathBuf::new(); - path.push(p); - path.push(filename); - DirEntry { path } - }) - .collect::>(); - - Ok(ReadDir { entries: paths }) +pub fn readdir(_p: &Path) -> io::Result { + // While there *is* a userspace function for reading file directories, + // the necessary implementation cannot currently be done cleanly, as + // vexOS does not expose directory length to user programs. + // + // This means that we would need to create a large fixed-length buffer + // and hope that the folder's contents didn't exceed that buffer's length, + // which obviously isn't behavior we want to rely on in the standard library. + unsupported() } pub fn unlink(_p: &Path) -> io::Result<()> { @@ -522,7 +483,7 @@ pub fn stat(p: &Path) -> io::Result { } pub fn lstat(p: &Path) -> io::Result { - // Symlinks aren't supported in our filesystem + // Symlinks aren't supported in this filesystem stat(p) } diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 2469b6fa855ed..ab3d2505ec6f2 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -34,8 +34,11 @@ pub unsafe extern "C" fn _start() -> ! { fn main() -> i32; } + // Setup the stack asm!("ldr sp, =__stack_top", options(nostack)); + // vexOS doesn't explicitly clean out .bss, so as a sanity + // check we'll fill it with zeroes. ptr::slice_from_raw_parts_mut( addr_of_mut!(__bss_start), addr_of_mut!(__bss_end).offset_from(addr_of_mut!(__bss_start)) as usize, diff --git a/library/std/src/sys/pal/vexos/stdio.rs b/library/std/src/sys/pal/vexos/stdio.rs index 998592e762434..a9e05e3537f8d 100644 --- a/library/std/src/sys/pal/vexos/stdio.rs +++ b/library/std/src/sys/pal/vexos/stdio.rs @@ -44,7 +44,10 @@ impl io::Write for Stdout { unsafe { vex_sdk::vexSerialWriteBuffer(STDIO_CHANNEL, buf.as_ptr(), buf.len() as u32) }; if written < 0 { - return Err(io::Error::new(io::ErrorKind::Other, "Internal write error occurred.")); + return Err(io::Error::new( + io::ErrorKind::Uncategorized, + "Internal write error occurred.", + )); } Ok(written as usize) From ea7507eacf0d50671b6866f6f1c207f6784bf3ba Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 4 Aug 2024 00:50:40 -0400 Subject: [PATCH 29/72] add default code signature, ensure stdout flush --- library/std/src/sys/pal/vexos/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index ab3d2505ec6f2..b2f3361ac66c9 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -52,6 +52,16 @@ pub unsafe extern "C" fn _start() -> ! { abort_internal() } +#[link_section = ".code_signature"] +#[linkage = "weak"] +#[used] +static CODE_SIGNATURE: vex_sdk::vcodesig = vex_sdk::vcodesig { + magic: u32::from_le_bytes(*b"XVX5"), + r#type: 2, + owner: 0, + options: 0, +}; + // This function is needed by the panic runtime. The symbol is named in // pre-link args for the target specification, so keep that in sync. #[cfg(not(test))] @@ -61,8 +71,12 @@ pub extern "C" fn __rust_abort() -> ! { abort_internal() } +// 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() -> crate::io::Result { @@ -83,6 +97,7 @@ pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { pub fn abort_internal() -> ! { unsafe { + vex_sdk::vexTasksRun(); vex_sdk::vexSystemExitRequest(); } From 77e03a93d44239682712ec3e66307ba87189f669 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 4 Aug 2024 00:52:55 -0400 Subject: [PATCH 30/72] add platform docs --- src/doc/rustc/src/platform-support.md | 1 + .../src/platform-support/armv7a-vex-v5.md | 91 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 src/doc/rustc/src/platform-support/armv7a-vex-v5.md diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index a706926f7435c..bf61038c76fe2 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -160,6 +160,7 @@ target | std | notes `armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat [`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | Armv7-A OpenHarmony [`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A +[`armv7a-vex-v5`](platform-support/armv7a-vex-v5.md) | * | Armv7-A Cortex-A9 VEX V5 Brain, vexOS [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat `i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE [^x86_32-floats-x87] diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md new file mode 100644 index 0000000000000..897e884c65508 --- /dev/null +++ b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md @@ -0,0 +1,91 @@ +# `armv7a-vex-v5` + +**Tier: 3** + + +Allows compiling user programs for the [VEX V5 Brain](https://www.vexrobotics.com/276-4810.html), a microcontroller for educational and competitive robotics. + +Rust support for this target is not affiliated with VEX Robotics or IFI, and is not derived from nor used with any official VEX SDK. + +## Target maintainers + +This target is maintained by members of the [vexide](https://github.com/vexide) organization: + +- [@Tropix126](https://github.com/Tropix126) +- [@Gavin-Niederman](https://github.com/Gavin-Niederman) +- [@max-niederman](https://github.com/max-niederman) +- [@doinkythederp](https://github.com/doinkythederp) + +## Requirements + +This target is cross-compiled. Dynamic linking is unsupported. + +`#![no_std]` crates can be built using `build-std` to build `core` and optionally +`alloc`. Unwinding panics are not yet supported. + +`std` is partially implemented, but many modules (such as `thread`, `process`, `net`, etc...) will return errors. An allocator is provided along with partial support for the `time`, `env` and `io` modules. Filesystem operations over SDCard through `std::fs` are partially supported within the restrictions of the user enviornment (e.g. directories cannot be created, filesystem objects cannot be removed). + +This target generates binaries in the ELF format that may uploaded to the brain with external tools. + +## Building the target + +Rust does not ship pre-compiled artifacts for this target. You can use `build-std` feature to build ELF binaries with `std` support. + +`.cargo/config.toml`: + +```toml +[build] +target = "armv7a-vex-v5" + +[unstable] +build-std = ["std", "panic_abort"] +build-std-features = ["compiler-builtins-mem"] +``` + +## Building Rust programs + +The recommended way to build artifacts that can be installed and run on V5 Brain is by using the [cargo-v5](https://github.com/vexide/cargo-v5) tool. This tool wraps the `cargo build` command by supplying arguments necessary to build the target, while also providing uploading functionality. + +To install the tool run: + +```sh +cargo install cargo-v5 +``` + +The following fields in your project's `Cargo.toml` are read by `cargo-v5` to configure upload behavior: + +```toml +[package.metadata.v5] +# Slot number to upload the user program to. This should be from 1-8. +slot = 1 +# Program icon/thumbnail that will be displayed on the dashboard. +icon = "cool-x" +# Use gzip compression when uploading binaries. +compress = true +``` + +To build an uploadable BIN file using the release profile, run: + +```sh +cargo v5 build --release +``` + +Programs can also be directly uploaded to the brain over a USB connection after building: + +```sh +cargo v5 upload --release +``` + +## Testing + +Binaries built for this target can be run in an emulator (such as [vex-v5-qemu](https://github.com/vexide/vex-v5-qemu)), or uploaded to a device over a USB or bluetooth connection. + +The default Rust test runner is not supported. + +The Rust test suite for `library/std` is not yet supported. + +## Cross-compilation toolchains and C code + +This target can be cross-compiled from any host. + +This target does not link to C libraries. OS calls are implemented in rust through the [vex-sdk](https://github.com/vexide/vex-sdk) crate. No `libc` or crt0 implementation is present on this target. \ No newline at end of file From 1581d0887b1a74a7b515ed609dc4238b334b6377 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 4 Aug 2024 01:52:16 -0400 Subject: [PATCH 31/72] adjust wording and fix typos in target documentation --- library/Cargo.lock | 11 +++++++++++ library/panic_abort/Cargo.toml | 4 ++++ library/std/Cargo.toml | 1 + src/doc/rustc/src/platform-support/armv7a-vex-v5.md | 12 ++++++------ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index 7b9081d46a056..cac36c813b5a3 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -333,6 +333,7 @@ dependencies = [ "rustc-demangle", "std_detect", "unwind", + "vex-sdk", "wasi", "windows-targets 0.0.0", ] @@ -401,6 +402,16 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "vex-sdk" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f285bbc2b96fc4c7fae42ebe365dd2e9121e7002a58b1a9e0e4b1d14dba4d6d0" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml index a9d1f53761cbf..e73db243560e9 100644 --- a/library/panic_abort/Cargo.toml +++ b/library/panic_abort/Cargo.toml @@ -19,3 +19,7 @@ compiler_builtins = "0.1.0" [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] libc = { version = "0.2", default-features = false } + +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ['cfg(target_os, values("vexos"))'] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index a4c611218034a..36be1d036da79 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -143,6 +143,7 @@ level = "warn" check-cfg = [ 'cfg(bootstrap)', 'cfg(target_arch, values("xtensa"))', + 'cfg(target_os, values("vexos"))', # std use #[path] imports to portable-simd `std_float` crate # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md index 897e884c65508..de009d78cfcb6 100644 --- a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md +++ b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md @@ -5,7 +5,7 @@ Allows compiling user programs for the [VEX V5 Brain](https://www.vexrobotics.com/276-4810.html), a microcontroller for educational and competitive robotics. -Rust support for this target is not affiliated with VEX Robotics or IFI, and is not derived from nor used with any official VEX SDK. +Rust support for this target is not affiliated with VEX Robotics or IFI. ## Target maintainers @@ -29,7 +29,7 @@ This target generates binaries in the ELF format that may uploaded to the brain ## Building the target -Rust does not ship pre-compiled artifacts for this target. You can use `build-std` feature to build ELF binaries with `std` support. +Rust does not ship pre-compiled artifacts for this target. You can use the `build-std` feature to build ELF binaries with `std` support. `.cargo/config.toml`: @@ -44,9 +44,9 @@ build-std-features = ["compiler-builtins-mem"] ## Building Rust programs -The recommended way to build artifacts that can be installed and run on V5 Brain is by using the [cargo-v5](https://github.com/vexide/cargo-v5) tool. This tool wraps the `cargo build` command by supplying arguments necessary to build the target, while also providing uploading functionality. +The recommended way to build artifacts that run on V5 Brain is by using the [cargo-v5](https://github.com/vexide/cargo-v5) tool. This tool wraps the `cargo build` command by supplying arguments necessary to build the target, while also providing functionality for uploading over USB to a V5 Controller or Brain. -To install the tool run: +To install the tool, run: ```sh cargo install cargo-v5 @@ -70,7 +70,7 @@ To build an uploadable BIN file using the release profile, run: cargo v5 build --release ``` -Programs can also be directly uploaded to the brain over a USB connection after building: +Programs can also be directly uploaded to the brain over a USB connection immediately after building: ```sh cargo v5 upload --release @@ -78,7 +78,7 @@ cargo v5 upload --release ## Testing -Binaries built for this target can be run in an emulator (such as [vex-v5-qemu](https://github.com/vexide/vex-v5-qemu)), or uploaded to a device over a USB or bluetooth connection. +Binaries built for this target can be run in an emulator (such as [vex-v5-qemu](https://github.com/vexide/vex-v5-qemu)), or uploaded to a physical device over a serial (USB) connection. The default Rust test runner is not supported. From 8a69bd735dc2c1dbfa649b109ee848e86c44032d Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:48:15 -0400 Subject: [PATCH 32/72] update PAL and add `check-cfg` override for `target_os` --- library/std/src/sys/pal/vexos/fs.rs | 6 +++--- library/std/src/sys/pal/vexos/mod.rs | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index f5cb0a961cf22..7d8af80fd94d9 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -340,7 +340,7 @@ impl File { map_fresult(vex_sdk::vexFileSeek(self.fd.0, try_convert_offset(offset)?, SEEK_SET))? }, - // vexOS does not allow seeking with negative offsets. + // VEXos does not allow seeking with negative offsets. // That means we need to calculate the offset from the start for both of these. SeekFrom::End(offset) => unsafe { // If our offset is positive, everything is easy @@ -430,7 +430,7 @@ impl Drop for File { pub fn readdir(_p: &Path) -> io::Result { // While there *is* a userspace function for reading file directories, // the necessary implementation cannot currently be done cleanly, as - // vexOS does not expose directory length to user programs. + // VEXos does not expose directory length to user programs. // // This means that we would need to create a large fixed-length buffer // and hope that the folder's contents didn't exceed that buffer's length, @@ -458,7 +458,7 @@ pub fn remove_dir_all(_path: &Path) -> io::Result<()> { unsupported() } -pub fn try_exists(path: &Path) -> io::Result { +pub fn exists(path: &Path) -> io::Result { let path = CString::new(path.as_os_str().as_encoded_bytes()) .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Path contained a null byte"))?; diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index b2f3361ac66c9..6ca3d23f63556 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -16,8 +16,6 @@ pub mod process; pub mod stdio; #[path = "../unsupported/thread.rs"] pub mod thread; -#[path = "../unsupported/thread_local_key.rs"] -pub mod thread_local_key; pub mod time; use crate::{arch::asm, ptr::{self, addr_of_mut}}; @@ -37,7 +35,7 @@ pub unsafe extern "C" fn _start() -> ! { // Setup the stack asm!("ldr sp, =__stack_top", options(nostack)); - // vexOS doesn't explicitly clean out .bss, so as a sanity + // VEXos doesn't explicitly clean out .bss, so as a sanity // check we'll fill it with zeroes. ptr::slice_from_raw_parts_mut( addr_of_mut!(__bss_start), From 1dbfadad53de755658d0132ba8dde8aef1214a49 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:48:30 -0400 Subject: [PATCH 33/72] add additional information to target spec and supporting docs --- .../src/spec/targets/armv7a_vex_v5.rs | 24 ++++++++++--------- src/doc/rustc/src/platform-support.md | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index a6a6f542e3103..418bf2a0c5bc8 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -6,29 +6,31 @@ pub(crate) fn target() -> Target { Target { llvm_target: "armv7a-none-eabihf".into(), metadata: crate::spec::TargetMetadata { - description: None, - tier: None, - host_tools: None, - std: None, + description: Some("Armv7-A Cortex-A9 VEX V5 Brain, VEXos".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: "arm".into(), options: TargetOptions { + os: "vexos".into(), + vendor: "vex".into(), + exe_suffix: "elf".into(), cpu: "cortex-a9".into(), abi: "eabihf".into(), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + features: "+v7,+neon,+vfp3,+thumb2,+thumb-mode".into(), linker: Some("rust-lld".into()), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), link_script: Some(LINK_SCRIPT.into()), - features: "+v7,+thumb2,+vfp3,+neon".into(), + panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, - disable_redzone: true, + c_enum_min_bits: Some(8), max_atomic_width: Some(64), - panic_strategy: PanicStrategy::Abort, + disable_redzone: true, emit_debug_gdb_scripts: false, - c_enum_min_bits: Some(8), - os: "vexos".into(), - vendor: "vex".into(), + has_thumb_interworking: true, ..Default::default() }, } diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index bf61038c76fe2..f330ed9c4722f 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -160,7 +160,7 @@ target | std | notes `armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat [`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | Armv7-A OpenHarmony [`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A -[`armv7a-vex-v5`](platform-support/armv7a-vex-v5.md) | * | Armv7-A Cortex-A9 VEX V5 Brain, vexOS +[`armv7a-vex-v5`](platform-support/armv7a-vex-v5.md) | * | Armv7-A Cortex-A9 VEX V5 Brain, VEXos [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat `i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE [^x86_32-floats-x87] From f39ea4a1653a2f94a89eb055dee1a0233313129c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 8 Aug 2024 23:03:32 -0400 Subject: [PATCH 34/72] fix `EXE_SUFFFIX` to use dot --- compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index 418bf2a0c5bc8..6a5714b02fc6f 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { os: "vexos".into(), vendor: "vex".into(), - exe_suffix: "elf".into(), + exe_suffix: ".elf".into(), cpu: "cortex-a9".into(), abi: "eabihf".into(), features: "+v7,+neon,+vfp3,+thumb2,+thumb-mode".into(), From 77ddf8d65450290f366c2389c57c3798889b7cd6 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 17 Aug 2024 00:35:30 -0500 Subject: [PATCH 35/72] fix: use correct code signature default values --- library/std/src/sys/pal/vexos/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 6ca3d23f63556..9c034252b7f9d 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -55,8 +55,8 @@ pub unsafe extern "C" fn _start() -> ! { #[used] static CODE_SIGNATURE: vex_sdk::vcodesig = vex_sdk::vcodesig { magic: u32::from_le_bytes(*b"XVX5"), - r#type: 2, - owner: 0, + r#type: 0, + owner: 2, options: 0, }; From b6b37890b40e3287427ee57c4c7f7e0a54ed808b Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:30:13 -0500 Subject: [PATCH 36/72] don't compile with `+thumb-mode` feature for now --- compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index 6a5714b02fc6f..f661a5931e7a6 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { exe_suffix: ".elf".into(), cpu: "cortex-a9".into(), abi: "eabihf".into(), - features: "+v7,+neon,+vfp3,+thumb2,+thumb-mode".into(), + features: "+v7,+neon,+vfp3,+thumb2".into(), linker: Some("rust-lld".into()), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), link_script: Some(LINK_SCRIPT.into()), From b1671f1fcfe4f1b542e2884e8636cbee47397d4d Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 5 Sep 2024 21:02:01 -0500 Subject: [PATCH 37/72] properly flush serial on abort --- library/std/src/sys/pal/vexos/mod.rs | 29 ++++++++++++++++---------- library/std/src/sys/pal/vexos/stdio.rs | 4 ++-- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 9c034252b7f9d..69599d03dc1c5 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -18,8 +18,10 @@ pub mod stdio; pub mod thread; pub mod time; -use crate::{arch::asm, ptr::{self, addr_of_mut}}; +use crate::arch::asm; use crate::hash::{DefaultHasher, Hasher}; +use crate::ptr::{self, addr_of_mut}; +use crate::time::{Duration, Instant}; #[cfg(not(test))] #[no_mangle] @@ -53,12 +55,8 @@ pub unsafe extern "C" fn _start() -> ! { #[link_section = ".code_signature"] #[linkage = "weak"] #[used] -static CODE_SIGNATURE: vex_sdk::vcodesig = vex_sdk::vcodesig { - magic: u32::from_le_bytes(*b"XVX5"), - r#type: 0, - owner: 2, - options: 0, -}; +static CODE_SIGNATURE: vex_sdk::vcodesig = + vex_sdk::vcodesig { magic: u32::from_le_bytes(*b"XVX5"), r#type: 0, owner: 2, options: 0 }; // This function is needed by the panic runtime. The symbol is named in // pre-link args for the target specification, so keep that in sync. @@ -94,8 +92,19 @@ pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { } pub fn abort_internal() -> ! { + let exit_time = Instant::now(); + const FLUSH_TIMEOUT: Duration = Duration::from_millis(15); + unsafe { - vex_sdk::vexTasksRun(); + // Force the serial buffer to flush + while exit_time.elapsed() < FLUSH_TIMEOUT { + // If the buffer has been fully flushed, exit the loop + if vex_sdk::vexSerialWriteFree(stdio::STDIO_CHANNEL) == (stdio::STDOUT_BUF_SIZE as i32) + { + break; + } + vex_sdk::vexTasksRun(); + } vex_sdk::vexSystemExitRequest(); } @@ -107,9 +116,7 @@ pub fn abort_internal() -> ! { fn hash_time() -> u64 { let mut hasher = DefaultHasher::new(); // The closest we can get to a random number is the time since program start - let time = unsafe { - vex_sdk::vexSystemHighResTimeGet() - }; + let time = unsafe { vex_sdk::vexSystemHighResTimeGet() }; hasher.write_u64(time); hasher.finish() } diff --git a/library/std/src/sys/pal/vexos/stdio.rs b/library/std/src/sys/pal/vexos/stdio.rs index a9e05e3537f8d..57557ead13f63 100644 --- a/library/std/src/sys/pal/vexos/stdio.rs +++ b/library/std/src/sys/pal/vexos/stdio.rs @@ -4,7 +4,7 @@ pub struct Stdin(()); pub struct Stdout(()); pub struct Stderr(()); -const STDIO_CHANNEL: u32 = 1; +pub const STDIO_CHANNEL: u32 = 1; impl Stdin { pub const fn new() -> Stdin { @@ -81,7 +81,7 @@ impl io::Write for Stderr { } pub const STDIN_BUF_SIZE: usize = 4096; -const STDOUT_BUF_SIZE: usize = 2048; +pub const STDOUT_BUF_SIZE: usize = 2048; pub fn is_ebadf(_err: &io::Error) -> bool { true From 3d0f59fe426d9d469a4c67bdc810c15f2f800040 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 7 Sep 2024 14:02:24 -0500 Subject: [PATCH 38/72] clarify documentation regarding cargo-v5, adjust `SystemTime` panic message --- compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 1 - library/std/src/sys/pal/vexos/mod.rs | 7 +++++-- library/std/src/sys/pal/vexos/time.rs | 2 +- src/doc/rustc/src/platform-support/armv7a-vex-v5.md | 6 ++++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index f661a5931e7a6..d986132e251dd 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -17,7 +17,6 @@ pub(crate) fn target() -> Target { options: TargetOptions { os: "vexos".into(), vendor: "vex".into(), - exe_suffix: ".elf".into(), cpu: "cortex-a9".into(), abi: "eabihf".into(), features: "+v7,+neon,+vfp3,+thumb2".into(), diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 69599d03dc1c5..421d4cb2c831a 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -37,8 +37,7 @@ pub unsafe extern "C" fn _start() -> ! { // Setup the stack asm!("ldr sp, =__stack_top", options(nostack)); - // VEXos doesn't explicitly clean out .bss, so as a sanity - // check we'll fill it with zeroes. + // VEXos doesn't explicitly clean out .bss. ptr::slice_from_raw_parts_mut( addr_of_mut!(__bss_start), addr_of_mut!(__bss_end).offset_from(addr_of_mut!(__bss_start)) as usize, @@ -52,6 +51,10 @@ pub unsafe extern "C" fn _start() -> ! { abort_internal() } +// The code signature is a 32 byte header at the start of user programs that +// identifies the owner and type of the program, as well as certain flags for +// program behavior dictated by the OS. In the event that the user wants to +// change this header, we use weak linkage so it can be overwritten. #[link_section = ".code_signature"] #[linkage = "weak"] #[used] diff --git a/library/std/src/sys/pal/vexos/time.rs b/library/std/src/sys/pal/vexos/time.rs index 94699d64d2307..60805ea2759d0 100644 --- a/library/std/src/sys/pal/vexos/time.rs +++ b/library/std/src/sys/pal/vexos/time.rs @@ -29,7 +29,7 @@ impl Instant { impl SystemTime { pub fn now() -> SystemTime { - panic!("time not implemented on this platform") + panic!("system time not implemented on this platform") } pub fn sub_time(&self, other: &SystemTime) -> Result { diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md index de009d78cfcb6..4a0d82126163f 100644 --- a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md +++ b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md @@ -23,7 +23,7 @@ This target is cross-compiled. Dynamic linking is unsupported. `#![no_std]` crates can be built using `build-std` to build `core` and optionally `alloc`. Unwinding panics are not yet supported. -`std` is partially implemented, but many modules (such as `thread`, `process`, `net`, etc...) will return errors. An allocator is provided along with partial support for the `time`, `env` and `io` modules. Filesystem operations over SDCard through `std::fs` are partially supported within the restrictions of the user enviornment (e.g. directories cannot be created, filesystem objects cannot be removed). +`std` is partially implemented, but many modules (such as `thread`, `process`, `net`, etc...) will return errors. An allocator is provided along with partial support for the `time`, `env` and `io` modules. Filesystem operations over SDCard through `std::fs` are partially supported within the restrictions of the user environment (e.g. directories cannot be created, filesystem objects cannot be removed). This target generates binaries in the ELF format that may uploaded to the brain with external tools. @@ -44,7 +44,9 @@ build-std-features = ["compiler-builtins-mem"] ## Building Rust programs -The recommended way to build artifacts that run on V5 Brain is by using the [cargo-v5](https://github.com/vexide/cargo-v5) tool. This tool wraps the `cargo build` command by supplying arguments necessary to build the target, while also providing functionality for uploading over USB to a V5 Controller or Brain. +When the compiler builds a binary, an ELF build artifact will be produced. Additional tools are required for this artifact to be recognizable to VEXos as a user program. + +The [cargo-v5](https://github.com/vexide/cargo-v5) tool is capable of creating binaries that can be uploaded to the V5 brain. This tool wraps the `cargo build` command by supplying arguments necessary to build the target and produce an artifact recognizable to VEXos, while also providing functionality for uploading over USB to a V5 Controller or Brain. To install the tool, run: From ace69e65747d35a3964110de2e875ee841a359a1 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 8 Oct 2024 20:12:00 -0700 Subject: [PATCH 39/72] use aapcs as system abi --- compiler/rustc_target/src/spec/mod.rs | 4 ++++ compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 1 + library/Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- library/std/src/sys/pal/vexos/alloc.rs | 8 +++----- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 4aaba2732683b..a415026e62fb3 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2338,6 +2338,8 @@ pub struct TargetOptions { pub is_like_wasm: bool, /// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc pub is_like_android: bool, + /// Whether a target toolchain is like VEXos. + pub is_like_vexos: bool, /// Default supported version of DWARF on this platform. /// Useful because some platforms (osx, bsd) only want up to DWARF2. pub default_dwarf_version: u32, @@ -2710,6 +2712,7 @@ impl Default for TargetOptions { is_like_msvc: false, is_like_wasm: false, is_like_android: false, + is_like_vexos: false, default_dwarf_version: 4, allows_weak_linkage: true, has_rpath: false, @@ -2817,6 +2820,7 @@ impl Target { Abi::System { unwind } if self.is_like_windows && self.arch == "x86" && !c_variadic => { Abi::Stdcall { unwind } } + Abi::System { unwind } if self.is_like_vexos && !c_variadic => Abi::Aapcs { unwind }, Abi::System { unwind } => Abi::C { unwind }, Abi::EfiApi if self.arch == "arm" => Abi::Aapcs { unwind: false }, Abi::EfiApi if self.arch == "x86_64" => Abi::Win64 { unwind: false }, diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index d986132e251dd..5451c0e12a8e1 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -16,6 +16,7 @@ pub(crate) fn target() -> Target { arch: "arm".into(), options: TargetOptions { os: "vexos".into(), + is_like_vexos: true, vendor: "vex".into(), cpu: "cortex-a9".into(), abi: "eabihf".into(), diff --git a/library/Cargo.lock b/library/Cargo.lock index cac36c813b5a3..8b2aac35fc812 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -404,9 +404,9 @@ dependencies = [ [[package]] name = "vex-sdk" -version = "0.17.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f285bbc2b96fc4c7fae42ebe365dd2e9121e7002a58b1a9e0e4b1d14dba4d6d0" +checksum = "79ec210898aed247c0fb1ae4834b4648669050ae8275423a1ce5cc3d6f07649a" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 36be1d036da79..44a4df7726394 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -86,7 +86,7 @@ r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] } [target.'cfg(target_os = "vexos")'.dependencies] -vex-sdk = { version = "0.17.0", features = ['rustc-dep-of-std'] } +vex-sdk = { version = "0.21.0", features = ['rustc-dep-of-std'] } [features] backtrace = [ diff --git a/library/std/src/sys/pal/vexos/alloc.rs b/library/std/src/sys/pal/vexos/alloc.rs index f760ebef770f9..04d13e00a534d 100644 --- a/library/std/src/sys/pal/vexos/alloc.rs +++ b/library/std/src/sys/pal/vexos/alloc.rs @@ -1,8 +1,6 @@ -use crate::{ - alloc::{GlobalAlloc, Layout, System}, - ptr, - sync::atomic::{AtomicBool, Ordering}, -}; +use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::ptr; +use crate::sync::atomic::{AtomicBool, Ordering}; static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new_with_allocator(Vexos); From ea04c9246d18ed406e4b1df09abe203fab47f259 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 8 Oct 2024 20:31:43 -0700 Subject: [PATCH 40/72] fix stack corruptions in startup routine --- .../spec/targets/armv7a_vex_v5_linker_script.ld | 8 ++------ library/std/src/sys/pal/vexos/mod.rs | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld index 37fc390401ead..63bca9d44168e 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -11,11 +11,7 @@ MEMORY { } __stack_length = 0x400000; -/* -It's currently unclear why subtracting anything is necessary, but it fixes memory permission errors. -0x100 is an arbitrary number that works. -*/ -__heap_end = __user_ram_end - __stack_length - 0x100; +__heap_end = __user_ram_end - __stack_length; SECTIONS { .text : { @@ -55,4 +51,4 @@ SECTIONS { /DISCARD/ : { *(.ARM.exidx) } -} \ No newline at end of file +} diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 421d4cb2c831a..43275ba02d754 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -18,14 +18,24 @@ pub mod stdio; pub mod thread; pub mod time; -use crate::arch::asm; +use crate::arch::global_asm; use crate::hash::{DefaultHasher, Hasher}; use crate::ptr::{self, addr_of_mut}; use crate::time::{Duration, Instant}; +global_asm!( + r#" + .section .boot, "ax" + .global _boot + + _boot: + ldr sp, =__stack_top @ Set up the user stack. + b _start @ Jump to the Rust entrypoint. + "# +); + #[cfg(not(test))] #[no_mangle] -#[link_section = ".boot"] pub unsafe extern "C" fn _start() -> ! { extern "C" { static mut __bss_start: u8; @@ -34,9 +44,6 @@ pub unsafe extern "C" fn _start() -> ! { fn main() -> i32; } - // Setup the stack - asm!("ldr sp, =__stack_top", options(nostack)); - // VEXos doesn't explicitly clean out .bss. ptr::slice_from_raw_parts_mut( addr_of_mut!(__bss_start), From f5237d60eea46a095ec488b5a2c5cfb1ed3a6c6a Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 8 Oct 2024 21:13:40 -0700 Subject: [PATCH 41/72] fix thread locals --- library/std/src/sys/pal/vexos/mod.rs | 5 +++++ library/std/src/sys/thread_local/mod.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 43275ba02d754..84f42d5dab7a5 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -55,6 +55,11 @@ pub unsafe extern "C" fn _start() -> ! { main(); + unsafe { + crate::sys::thread_local::destructors::run(); + } + crate::rt::thread_cleanup(); + abort_internal() } diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index e74e0fe3fc6a3..30504c0c2b399 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -92,6 +92,7 @@ pub(crate) mod guard { )), target_os = "uefi", target_os = "zkvm", + target_os = "vexos", ))] { pub(crate) fn enable() { // FIXME: Right now there is no concept of "thread exit" on From e0e1eba78d8eaf0916d66607fcc6c4fef9eb596d Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 8 Oct 2024 22:54:35 -0700 Subject: [PATCH 42/72] implement (shimmed) std::random --- library/std/src/sys/pal/vexos/mod.rs | 21 --------------------- library/std/src/sys/random/mod.rs | 2 ++ 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 84f42d5dab7a5..0fc76a8444468 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -1,4 +1,3 @@ -pub mod alloc; #[path = "../unsupported/args.rs"] pub mod args; pub mod env; @@ -19,7 +18,6 @@ pub mod thread; pub mod time; use crate::arch::global_asm; -use crate::hash::{DefaultHasher, Hasher}; use crate::ptr::{self, addr_of_mut}; use crate::time::{Duration, Instant}; @@ -55,11 +53,6 @@ pub unsafe extern "C" fn _start() -> ! { main(); - unsafe { - crate::sys::thread_local::destructors::run(); - } - crate::rt::thread_cleanup(); - abort_internal() } @@ -127,17 +120,3 @@ pub fn abort_internal() -> ! { crate::hint::spin_loop() } } - -fn hash_time() -> u64 { - let mut hasher = DefaultHasher::new(); - // The closest we can get to a random number is the time since program start - let time = unsafe { vex_sdk::vexSystemHighResTimeGet() }; - hasher.write_u64(time); - hasher.finish() -} - -pub fn hashmap_random_keys() -> (u64, u64) { - let key1 = hash_time(); - let key2 = hash_time(); - (key1, key2) -} diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index f42351deb92c0..a406aef53d1e8 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 = "vexos", ))] { // 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 = "vexos", )))] pub fn hashmap_random_keys() -> (u64, u64) { let mut buf = [0; 16]; From e18377933c421a8effa8de6eb9a4654db426f23e Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 8 Oct 2024 22:54:49 -0700 Subject: [PATCH 43/72] fix allocation --- library/std/src/sys/alloc/mod.rs | 2 ++ library/std/src/sys/{pal/vexos/alloc.rs => alloc/vexos.rs} | 3 +++ 2 files changed, 5 insertions(+) rename library/std/src/sys/{pal/vexos/alloc.rs => alloc/vexos.rs} (97%) diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs index 2c0b533a5703f..1a41fa9f3adfc 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 = "vexos")] { + mod vexos; } } diff --git a/library/std/src/sys/pal/vexos/alloc.rs b/library/std/src/sys/alloc/vexos.rs similarity index 97% rename from library/std/src/sys/pal/vexos/alloc.rs rename to library/std/src/sys/alloc/vexos.rs index 04d13e00a534d..e1033f4a62cfd 100644 --- a/library/std/src/sys/pal/vexos/alloc.rs +++ b/library/std/src/sys/alloc/vexos.rs @@ -1,3 +1,6 @@ +// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint +#![allow(static_mut_refs)] + use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ptr; use crate::sync::atomic::{AtomicBool, Ordering}; From c492684de46100778843a73b60804af822be7dcd Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:30:49 -0500 Subject: [PATCH 44/72] update linkerscript to include unwinding-related sections --- .../targets/armv7a_vex_v5_linker_script.ld | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld index 63bca9d44168e..1a7a8d2e38b75 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -1,34 +1,40 @@ OUTPUT_FORMAT("elf32-littlearm") -ENTRY(_start) +ENTRY(_boot) __user_ram_start = 0x03800000; __user_ram_length = 0x04800000; __user_ram_end = __user_ram_start + __user_ram_length; -MEMORY { - USER_RAM : ORIGIN = __user_ram_start, LENGTH = __user_ram_length -} +__code_signature_length = 0x20; __stack_length = 0x400000; __heap_end = __user_ram_end - __stack_length; +__eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0; +__eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0; + +MEMORY { + USER_RAM : ORIGIN = __user_ram_start, LENGTH = __user_ram_length +} + SECTIONS { - .text : { - __text_start = .; + .code_signature : { KEEP(*(.code_signature)) - . = __text_start + 0x20; + . = __user_ram_start + __code_signature_length; + } > USER_RAM + + .text : { *(.boot) *(.text .text.*) - } > USER_RAM = 0 + } > USER_RAM - .rodata1 : { - *(.rodata1 .rodata1.*) + .rodata : { + *(.rodata .rodata.*) } > USER_RAM .data : { *(.data .data.*) - *(.data1 .data1.*) } > USER_RAM .bss : { @@ -37,6 +43,30 @@ SECTIONS { __bss_end = .; } > USER_RAM + /* The unwind tables enabled by "default-uwtable" in the target file live here. */ + /* __eh_frame_start and similar symbols are used by libunwind. */ + .eh_frame_hdr : { + KEEP(*(.eh_frame_hdr)) + } > USER_RAM + + .eh_frame : { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + __eh_frame_end = .; + } > USER_RAM + + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > USER_RAM + + .ARM.extab : { + __extab_start = .; + *(.ARM.extab*) + __extab_end = .; + } > USER_RAM + .heap (NOLOAD) : ALIGN(4) { __heap_start = .; . = __heap_end; @@ -49,6 +79,6 @@ SECTIONS { } > USER_RAM /DISCARD/ : { - *(.ARM.exidx) + *(.ARM.attributes*) } } From 84dcb23f5746c75ad60c4b6a2a6b9852fbc49a3b Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Thu, 10 Oct 2024 22:09:42 -0700 Subject: [PATCH 45/72] format target doc and reorder maintainer list --- src/doc/rustc/src/platform-support/armv7a-vex-v5.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md index 4a0d82126163f..e20fd539bb55b 100644 --- a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md +++ b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md @@ -2,7 +2,6 @@ **Tier: 3** - Allows compiling user programs for the [VEX V5 Brain](https://www.vexrobotics.com/276-4810.html), a microcontroller for educational and competitive robotics. Rust support for this target is not affiliated with VEX Robotics or IFI. @@ -11,9 +10,9 @@ Rust support for this target is not affiliated with VEX Robotics or IFI. This target is maintained by members of the [vexide](https://github.com/vexide) organization: +- [@max-niederman](https://github.com/max-niederman) - [@Tropix126](https://github.com/Tropix126) - [@Gavin-Niederman](https://github.com/Gavin-Niederman) -- [@max-niederman](https://github.com/max-niederman) - [@doinkythederp](https://github.com/doinkythederp) ## Requirements @@ -90,4 +89,4 @@ The Rust test suite for `library/std` is not yet supported. This target can be cross-compiled from any host. -This target does not link to C libraries. OS calls are implemented in rust through the [vex-sdk](https://github.com/vexide/vex-sdk) crate. No `libc` or crt0 implementation is present on this target. \ No newline at end of file +This target does not link to C libraries. OS calls are implemented in rust through the [vex-sdk](https://github.com/vexide/vex-sdk) crate. No `libc` or crt0 implementation is present on this target. From 097d7925d3bdc3a6561d9fd28faa532493ebb046 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Thu, 10 Oct 2024 22:11:43 -0700 Subject: [PATCH 46/72] bump vex-sdk version and allow vex-sdk to be a stdlib dep --- library/Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- src/tools/tidy/src/deps.rs | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index 8b2aac35fc812..05be04ea8f92d 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -404,9 +404,9 @@ dependencies = [ [[package]] name = "vex-sdk" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ec210898aed247c0fb1ae4834b4648669050ae8275423a1ce5cc3d6f07649a" +checksum = "40b1777b4e4a60f9fed09417dafdc4a6a3393a67df1bd02c3b589770d906cff3" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 44a4df7726394..5a77188ed3552 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -86,7 +86,7 @@ r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] } [target.'cfg(target_os = "vexos")'.dependencies] -vex-sdk = { version = "0.21.0", features = ['rustc-dep-of-std'] } +vex-sdk = { version = "0.22.0", features = ['rustc-dep-of-std'] } [features] backtrace = [ diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 59e0042e5c9b2..f5134c731d0cb 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -488,6 +488,7 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ "shlex", "unicode-width", "unwinding", + "vex-sdk", "wasi", "windows-sys", "windows-targets", From 6c2287cf23dc54fd8d2529526bcbac5303cc46ca Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Thu, 10 Oct 2024 22:14:13 -0700 Subject: [PATCH 47/72] add assembly test for armv7a-vex-v5 From b6d41fa437eeffa25c069b7eb1f2e40236391ba5 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Fri, 11 Oct 2024 02:12:09 -0700 Subject: [PATCH 48/72] add armv7a-vex-v5 target docs to summary --- src/doc/rustc/src/SUMMARY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 670e4bd1be68b..922bea9176785 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -45,6 +45,7 @@ - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) + - [armv7a-vex-v5](platform-support/armv7a-vex-v5.md) - [\*-android and \*-androideabi](platform-support/android.md) - [\*-linux-ohos](platform-support/openharmony.md) - [\*-hurd-gnu](platform-support/hurd.md) From 0d441ab793c963968b9ec45e41876a6fcbf0ef4f Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Fri, 11 Oct 2024 10:09:41 -0700 Subject: [PATCH 49/72] better document the is_like_vexos property of TargetOptions --- compiler/rustc_target/src/spec/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index a415026e62fb3..bb58191e358d2 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2338,7 +2338,8 @@ pub struct TargetOptions { pub is_like_wasm: bool, /// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc pub is_like_android: bool, - /// Whether a target toolchain is like VEXos. + /// Whether a target toolchain is like VEXos, the operating system used by the VEX Robotics V5 Brain. + /// Introduced for the `armv7a-vex-v5` target. pub is_like_vexos: bool, /// Default supported version of DWARF on this platform. /// Useful because some platforms (osx, bsd) only want up to DWARF2. From 7bb6a04b1f35518bdbd3e119dcfca2054a2fd0db Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Fri, 11 Oct 2024 10:29:30 -0700 Subject: [PATCH 50/72] detail summary of armv7a-vex-v5's target support --- .../src/platform-support/armv7a-vex-v5.md | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md index e20fd539bb55b..20f90583e5e1c 100644 --- a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md +++ b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md @@ -20,12 +20,27 @@ This target is maintained by members of the [vexide](https://github.com/vexide) This target is cross-compiled. Dynamic linking is unsupported. `#![no_std]` crates can be built using `build-std` to build `core` and optionally -`alloc`. Unwinding panics are not yet supported. - -`std` is partially implemented, but many modules (such as `thread`, `process`, `net`, etc...) will return errors. An allocator is provided along with partial support for the `time`, `env` and `io` modules. Filesystem operations over SDCard through `std::fs` are partially supported within the restrictions of the user environment (e.g. directories cannot be created, filesystem objects cannot be removed). +`alloc`. Unwinding panics are not yet supported. `std` is partially implemented, see below. This target generates binaries in the ELF format that may uploaded to the brain with external tools. +## Standard Library Support + +`armv7a-vex-v5` implements as much of the standard library as is possible using only public VEX SDK functions. +This includes: + +- `std::time`, not including `SystemTime` as the SDK does not provide absolute time information. +- `std::io`, including `stdin()` and `stdout()`, but not `stderr()`, as stderr does not exist on this platform. +- `std::fs`, with the exception of directory reading and file deletion, due to public SDK limitations. +- modules which do not need to interact with the OS beyond allocation, + such as `std::collections`, `std::hash`, `std::future`, `std::sync`, etc. + +Notable modules which are not implemented include: + +- `std::process` +- `std::thread` +- `std::net` + ## Building the target Rust does not ship pre-compiled artifacts for this target. You can use the `build-std` feature to build ELF binaries with `std` support. From a9ca387d3f13c4eae3ad0692db29078d5fc74a43 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 13 Oct 2024 11:28:38 -0500 Subject: [PATCH 51/72] add more descriptive comments to the `armv7a-vex-v5` linkerscript --- .../targets/armv7a_vex_v5_linker_script.ld | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld index 1a7a8d2e38b75..319f29a281d5b 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld @@ -11,6 +11,7 @@ __code_signature_length = 0x20; __stack_length = 0x400000; __heap_end = __user_ram_end - __stack_length; +/* see https://github.com/llvm/llvm-project/blob/main/libunwind/src/AddressSpace.hpp#L78 */ __eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0; __eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0; @@ -19,6 +20,13 @@ MEMORY { } SECTIONS { + /* + * VEXos expects program binaries to have a 32-byte header called a "code signature", + * at their start, which tells the OS that we are a valid program and configures some + * miscellaneous startup behavior. + * + * This section is then initialized as a weak symbol in our PAL. + */ .code_signature : { KEEP(*(.code_signature)) . = __user_ram_start + __code_signature_length; @@ -29,6 +37,7 @@ SECTIONS { *(.text .text.*) } > USER_RAM + /* Global/uninitialized/static/constant data sections. */ .rodata : { *(.rodata .rodata.*) } > USER_RAM @@ -43,8 +52,10 @@ SECTIONS { __bss_end = .; } > USER_RAM - /* The unwind tables enabled by "default-uwtable" in the target file live here. */ - /* __eh_frame_start and similar symbols are used by libunwind. */ + /* + * These sections are added by the compiler in some cases to facilitate stack unwinding. + * __eh_frame_start and similar symbols are used by libunwind. + */ .eh_frame_hdr : { KEEP(*(.eh_frame_hdr)) } > USER_RAM @@ -67,6 +78,7 @@ SECTIONS { __extab_end = .; } > USER_RAM + /* Active memory regions for the stack/heap. */ .heap (NOLOAD) : ALIGN(4) { __heap_start = .; . = __heap_end; @@ -78,6 +90,10 @@ SECTIONS { __stack_top = .; } > USER_RAM + /* + * `.ARM.attributes` contains arch metadata for compatibility purposes, but we + * only target one hardware configuration, meaning it'd just take up space. + */ /DISCARD/ : { *(.ARM.attributes*) } From 24e381c113d1e39a7464662a47ca5eaac6f60cc8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:42:38 -0500 Subject: [PATCH 52/72] add `"v5"` target env armv7a-vex-v5 target spec --- compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 1 + tests/ui/check-cfg/well-known-values.stderr | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index 5451c0e12a8e1..af784dcc52cdb 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -18,6 +18,7 @@ pub(crate) fn target() -> Target { os: "vexos".into(), is_like_vexos: true, vendor: "vex".into(), + env: "v5".into(), cpu: "cortex-a9".into(), abi: "eabihf".into(), features: "+v7,+neon,+vfp3,+thumb2".into(), diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 5c1898a0ae365..7a572a30cf421 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc` + = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, `uclibc`, and `v5` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From d11d208ef493d22c4454c54a8dabd2d144dd44ca Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:01:22 -0500 Subject: [PATCH 53/72] implement `Stderr` in vexos PAL --- library/std/src/sys/pal/vexos/stdio.rs | 18 +++++++++++++++++- .../src/platform-support/armv7a-vex-v5.md | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/vexos/stdio.rs b/library/std/src/sys/pal/vexos/stdio.rs index 57557ead13f63..d0800682ff7e4 100644 --- a/library/std/src/sys/pal/vexos/stdio.rs +++ b/library/std/src/sys/pal/vexos/stdio.rs @@ -72,10 +72,26 @@ impl Stderr { impl io::Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result { - Ok(buf.len()) + let written = + unsafe { vex_sdk::vexSerialWriteBuffer(STDIO_CHANNEL, buf.as_ptr(), buf.len() as u32) }; + + if written < 0 { + return Err(io::Error::new( + io::ErrorKind::Uncategorized, + "Internal write error occurred.", + )); + } + + Ok(written as usize) } fn flush(&mut self) -> io::Result<()> { + unsafe { + while (vex_sdk::vexSerialWriteFree(STDIO_CHANNEL) as usize) != STDOUT_BUF_SIZE { + vex_sdk::vexTasksRun(); + } + } + Ok(()) } } diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md index 20f90583e5e1c..1cd3e889bd889 100644 --- a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md +++ b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md @@ -30,7 +30,7 @@ This target generates binaries in the ELF format that may uploaded to the brain This includes: - `std::time`, not including `SystemTime` as the SDK does not provide absolute time information. -- `std::io`, including `stdin()` and `stdout()`, but not `stderr()`, as stderr does not exist on this platform. +- `std::io`, including `stdin`/`stdout`/`stderr`. `stdout` and `stderr` are both written to USB channel 1 on this platform and are not differentiated. - `std::fs`, with the exception of directory reading and file deletion, due to public SDK limitations. - modules which do not need to interact with the OS beyond allocation, such as `std::collections`, `std::hash`, `std::future`, `std::sync`, etc. From 1660bc646e52b215b42ee5b9ec200302f5416949 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:06:59 -0500 Subject: [PATCH 54/72] run VEXos cpu1 scheduler while waiting for abort This isn't necessarily fixing anything on the V5 in particular (exit requests are handled by CPU0, which then interrupt CPU1 after), but it's certainly more correct and may be required for other single-core VEXos targets if support is added in the future. --- library/std/src/sys/pal/vexos/mod.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 0fc76a8444468..8fab2da5fa5b1 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -106,17 +106,19 @@ pub fn abort_internal() -> ! { unsafe { // Force the serial buffer to flush while exit_time.elapsed() < FLUSH_TIMEOUT { + vex_sdk::vexTasksRun(); + // If the buffer has been fully flushed, exit the loop if vex_sdk::vexSerialWriteFree(stdio::STDIO_CHANNEL) == (stdio::STDOUT_BUF_SIZE as i32) { break; } - vex_sdk::vexTasksRun(); } + vex_sdk::vexSystemExitRequest(); - } - - loop { - crate::hint::spin_loop() + + loop { + vex_sdk::vexTasksRun(); + } } } From 508177c682e4b0c1d40e0a3d58da949249ee707a Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:44:39 -0500 Subject: [PATCH 55/72] update to `vex-sdk` 0.23.0 0.23.0 most notably removes uses of `#[no_mangle]` from symbols in `vex-sdk` to avoid conflicts with other versions of the crate. Symbols were originally `#[no_mangle]` for the purposes of compiling to a C static library, but this never ended up being useful and would be actively harmful to include in `libstd`. --- library/Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- library/std/src/sys/pal/vexos/mod.rs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index 05be04ea8f92d..96dd5f42c7fe0 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -404,9 +404,9 @@ dependencies = [ [[package]] name = "vex-sdk" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b1777b4e4a60f9fed09417dafdc4a6a3393a67df1bd02c3b589770d906cff3" +checksum = "cddff1d9785c5e35e031340c0a24afbeb911a654f99fec062c5ec94281c189ed" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 5a77188ed3552..bbfcc931777b0 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -86,7 +86,7 @@ r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] } [target.'cfg(target_os = "vexos")'.dependencies] -vex-sdk = { version = "0.22.0", features = ['rustc-dep-of-std'] } +vex-sdk = { version = "0.23.0", features = ['rustc-dep-of-std'] } [features] backtrace = [ diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 8fab2da5fa5b1..49b55eb9c7f32 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -107,16 +107,16 @@ pub fn abort_internal() -> ! { // Force the serial buffer to flush while exit_time.elapsed() < FLUSH_TIMEOUT { vex_sdk::vexTasksRun(); - + // If the buffer has been fully flushed, exit the loop if vex_sdk::vexSerialWriteFree(stdio::STDIO_CHANNEL) == (stdio::STDOUT_BUF_SIZE as i32) { break; } } - + vex_sdk::vexSystemExitRequest(); - + loop { vex_sdk::vexTasksRun(); } From 4d95d1f533ab919147934019d798460823558751 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Fri, 25 Oct 2024 13:08:18 -0500 Subject: [PATCH 56/72] add rudimentary implementation of `Thread::sleep` and `Thread::yield_now` on armv7a-vex-v5 --- library/std/src/sys/pal/vexos/mod.rs | 1 - library/std/src/sys/pal/vexos/thread.rs | 44 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 library/std/src/sys/pal/vexos/thread.rs diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 49b55eb9c7f32..282443046b106 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -13,7 +13,6 @@ pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; pub mod stdio; -#[path = "../unsupported/thread.rs"] pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/vexos/thread.rs b/library/std/src/sys/pal/vexos/thread.rs new file mode 100644 index 0000000000000..b355a6bfd72d4 --- /dev/null +++ b/library/std/src/sys/pal/vexos/thread.rs @@ -0,0 +1,44 @@ +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() { + unsafe { + vex_sdk::vexTasksRun(); + } + } + + pub fn set_name(_name: &CStr) { + // nope + } + + pub fn sleep(dur: Duration) { + let start = Instant::now(); + + while start.elapsed() < dur { + unsafe { + vex_sdk::vexTasksRun(); + } + } + } + + pub fn join(self) { + self.0 + } +} + +pub fn available_parallelism() -> io::Result> { + unsupported() +} From 034467f01dc0851e73bc916de63d842109b63108 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 29 Oct 2024 21:21:16 -0700 Subject: [PATCH 57/72] fix broken reference to Instant in pal --- library/std/src/sys/pal/vexos/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/vexos/thread.rs b/library/std/src/sys/pal/vexos/thread.rs index b355a6bfd72d4..f00ff9f7b1066 100644 --- a/library/std/src/sys/pal/vexos/thread.rs +++ b/library/std/src/sys/pal/vexos/thread.rs @@ -2,7 +2,7 @@ use super::unsupported; use crate::ffi::CStr; use crate::io; use crate::num::NonZero; -use crate::time::Duration; +use crate::time::{Duration, Instant}; pub struct Thread(!); From ed5773962491a112dd459e912eaf68c61e28390e Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 10 Nov 2024 19:23:30 -0600 Subject: [PATCH 58/72] switch to `+vfp3d16` LLVM feature in `armv7a-vex-v5` The Cortex-A9 only has 16 double-precision registers (`d0`-`d15`), so this is the correct VFP instructionset to use. --- compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index af784dcc52cdb..837255f6585ed 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { env: "v5".into(), cpu: "cortex-a9".into(), abi: "eabihf".into(), - features: "+v7,+neon,+vfp3,+thumb2".into(), + features: "+v7,+neon,+vfp3d16,+thumb2".into(), linker: Some("rust-lld".into()), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), link_script: Some(LINK_SCRIPT.into()), From a4701ce63d04b8287ac33b151cc29d4f63223c8e Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:28:47 -0600 Subject: [PATCH 59/72] fix and clean up comments surrounding file seeking --- library/std/src/sys/pal/vexos/fs.rs | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 7d8af80fd94d9..142ec81b84d1d 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -339,11 +339,7 @@ impl File { SeekFrom::Start(offset) => unsafe { map_fresult(vex_sdk::vexFileSeek(self.fd.0, try_convert_offset(offset)?, SEEK_SET))? }, - - // VEXos does not allow seeking with negative offsets. - // That means we need to calculate the offset from the start for both of these. SeekFrom::End(offset) => unsafe { - // If our offset is positive, everything is easy if offset >= 0 { map_fresult(vex_sdk::vexFileSeek( self.fd.0, @@ -351,21 +347,11 @@ impl File { SEEK_END, ))? } else { - // Get the position of the end of the file... + // `vexFileSeek` does not support seeking with negative offset, meaning + // we have to calculate the offset from the end of the file ourselves. map_fresult(vex_sdk::vexFileSeek( self.fd.0, - try_convert_offset(offset)?, - SEEK_END, - ))?; - // The number returned by the VEX SDK tell is stored as a 32 bit interger, - // and therefore this conversion cannot fail. - let position = self.tell()? as i64; - - // Offset from that position - let new_position = position + offset; - map_fresult(vex_sdk::vexFileSeek( - self.fd.0, - try_convert_offset(new_position)?, + try_convert_offset(self.file_attr().size + offset)?, SEEK_SET, ))? } @@ -378,12 +364,11 @@ impl File { SEEK_CUR, ))? } else { - let position = self.tell()? as i64; - - let new_position = position + offset; + // `vexFileSeek` does not support seeking with negative offset, meaning + // we have to calculate the offset from the stream position ourselves. map_fresult(vex_sdk::vexFileSeek( self.fd.0, - try_convert_offset(new_position)?, + try_convert_offset((self.tell()? as i64) + offset)?, SEEK_SET, ))? } From 33f5078a391def57d5d7e62046a537e14f98a22f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:30:37 -0600 Subject: [PATCH 60/72] add private unit to all pub fs types in vexos PAL --- library/std/src/sys/pal/vexos/fs.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 142ec81b84d1d..e7f195ec50e55 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -39,7 +39,7 @@ pub struct OpenOptions { } #[derive(Copy, Clone, Debug, Default)] -pub struct FileTimes {} +pub struct FileTimes(()); #[derive(Clone, Debug, PartialEq, Eq)] pub struct FilePermissions; @@ -50,7 +50,7 @@ pub struct FileType { } #[derive(Debug)] -pub struct DirBuilder {} +pub struct DirBuilder(()); impl FileAttr { /// Creates a FileAttr by getting data from an opened file. @@ -217,13 +217,12 @@ impl File { // Open in read only mode unsafe { vex_sdk::vexFileOpen(path.as_ptr(), c"".as_ptr()) } } else if opts.write && opts.append { - // Open in read/write and append mode + // Open in write and append mode unsafe { vex_sdk::vexFileOpenWrite(path.as_ptr()) } } else if opts.write && opts.truncate { - // Open in read/write mode + // Open in write mode unsafe { vex_sdk::vexFileOpenCreate(path.as_ptr()) } } else if opts.write { - // Open in read/write and overwrite mode unsafe { // Open in read/write and append mode let fd = vex_sdk::vexFileOpenWrite(path.as_ptr()); From 7168febcb7a4cb0f0d8f1ea993b2771e92ac3bad Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:32:00 -0600 Subject: [PATCH 61/72] treat all `io::Error`s as non-EBADF in vexos --- library/std/src/sys/pal/vexos/stdio.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/vexos/stdio.rs b/library/std/src/sys/pal/vexos/stdio.rs index d0800682ff7e4..94c834843806f 100644 --- a/library/std/src/sys/pal/vexos/stdio.rs +++ b/library/std/src/sys/pal/vexos/stdio.rs @@ -100,7 +100,7 @@ pub const STDIN_BUF_SIZE: usize = 4096; pub const STDOUT_BUF_SIZE: usize = 2048; pub fn is_ebadf(_err: &io::Error) -> bool { - true + false } pub fn panic_output() -> Option { From 8239a820a464861de428bfc7d5b8cf44ae648b55 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:32:22 -0600 Subject: [PATCH 62/72] adjust error message for `FRESULT::FR_INT_ERR` --- library/std/src/sys/pal/vexos/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index e7f195ec50e55..3087adc7405ca 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -498,7 +498,7 @@ fn map_fresult(fresult: vex_sdk::FRESULT) -> io::Result<()> { )), vex_sdk::FRESULT::FR_INT_ERR => Err(io::Error::new( io::ErrorKind::Uncategorized, - "assertion failed and an insanity is detected in the internal process", + "internal error in filesystem runtime", )), vex_sdk::FRESULT::FR_NOT_READY => Err(io::Error::new( io::ErrorKind::Uncategorized, From 0b7aa158ae839180d9cbc2430ce15fdc41de393f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:34:56 -0600 Subject: [PATCH 63/72] bump `vex-sdk` to 0.26.0 This release of `vex-sdk` notably removes any (previously misguided) usage of `#[no_mangle]` which would be unsuitable to have in `libstd`. --- library/std/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index bbfcc931777b0..bf15c6aeabb6e 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -86,7 +86,7 @@ r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] } r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] } [target.'cfg(target_os = "vexos")'.dependencies] -vex-sdk = { version = "0.23.0", features = ['rustc-dep-of-std'] } +vex-sdk = { version = "0.26.0", features = ['rustc-dep-of-std'] } [features] backtrace = [ From fd8d11071d1de19f9234f05975c0735690461f0c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:00:41 -0600 Subject: [PATCH 64/72] update libstd lockfile --- library/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index 96dd5f42c7fe0..6fc9f4b36da47 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -404,9 +404,9 @@ dependencies = [ [[package]] name = "vex-sdk" -version = "0.23.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cddff1d9785c5e35e031340c0a24afbeb911a654f99fec062c5ec94281c189ed" +checksum = "be1b586dd8546706564cf20c94bae51c8f9e4891d70360d3fb63d563350df3d1" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", From f76ae6f5fffc1df7f1035026143afe7c32871efa Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 31 Dec 2024 16:15:15 -0800 Subject: [PATCH 65/72] fix circular dependency on cc-rs using a temporary patched version of cc-rs --- src/bootstrap/Cargo.lock | 3 +-- src/bootstrap/Cargo.toml | 4 ++++ src/tools/tidy/src/extdeps.rs | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index d2f3c7f36ca86..24b68969f13be 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -88,8 +88,7 @@ dependencies = [ [[package]] name = "cc" version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" +source = "git+https://github.com/rust-lang/cc-rs?rev=6fe995c675dc1178f570752fa8f6de82913a91dc#6fe995c675dc1178f570752fa8f6de82913a91dc" dependencies = [ "shlex", ] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index d7afcc7f27d2e..ea9776bd69a8f 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -96,3 +96,7 @@ debug = 0 [profile.dev.package] # Only use debuginfo=1 to further reduce compile times. bootstrap.debug = 1 + +[patch.crates-io] +# FIXME: remove this once the `armv7a-vex-v5` target is available on nightly and cc-rs is updated with it +cc = { git = "https://github.com/rust-lang/cc-rs", rev = "6fe995c675dc1178f570752fa8f6de82913a91dc" } diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 55f937aeacf50..be19807c7e6a2 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -8,6 +8,8 @@ const ALLOWED_SOURCES: &[&str] = &[ r#""registry+https://github.com/rust-lang/crates.io-index""#, // This is `rust_team_data` used by `site` in src/tools/rustc-perf, r#""git+https://github.com/rust-lang/team#a5260e76d3aa894c64c56e6ddc8545b9a98043ec""#, + // This is temporarily used to bootstrap the `armv7a_vex_v5` target until cc-rs has it in its generated target list. + r#""git+https://github.com/rust-lang/cc-rs?rev=6fe995c675dc1178f570752fa8f6de82913a91dc#6fe995c675dc1178f570752fa8f6de82913a91dc""#, ]; /// Checks for external package sources. `root` is the path to the directory that contains the From c0b087909331fbdc45b27f08545c5f83ed09e1af Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 31 Dec 2024 16:24:01 -0800 Subject: [PATCH 66/72] add unsupported file_lock functions --- library/std/src/sys/pal/vexos/fs.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 3087adc7405ca..2e1fdf1bbcd56 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -257,6 +257,26 @@ impl File { self.flush() } + pub fn lock(&self) -> io::Result<()> { + unsupported() + } + + pub fn lock_shared(&self) -> io::Result<()> { + unsupported() + } + + pub fn try_lock(&self) -> io::Result { + unsupported() + } + + pub fn try_lock_shared(&self) -> io::Result { + unsupported() + } + + pub fn unlock(&self) -> io::Result<()> { + unsupported() + } + pub fn truncate(&self, _size: u64) -> io::Result<()> { unsupported() } From 08ace18d129864addef36b8b663f2ad313cd0d81 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 31 Dec 2024 16:29:01 -0800 Subject: [PATCH 67/72] fix mistakes in fs PAL --- library/std/src/sys/pal/vexos/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/vexos/fs.rs b/library/std/src/sys/pal/vexos/fs.rs index 2e1fdf1bbcd56..1014bab30bb86 100644 --- a/library/std/src/sys/pal/vexos/fs.rs +++ b/library/std/src/sys/pal/vexos/fs.rs @@ -370,7 +370,7 @@ impl File { // we have to calculate the offset from the end of the file ourselves. map_fresult(vex_sdk::vexFileSeek( self.fd.0, - try_convert_offset(self.file_attr().size + offset)?, + try_convert_offset(self.file_attr()?.size as i64 + offset)?, SEEK_SET, ))? } @@ -412,7 +412,7 @@ impl File { impl DirBuilder { pub fn new() -> DirBuilder { - DirBuilder {} + DirBuilder(()) } pub fn mkdir(&self, _p: &Path) -> io::Result<()> { From 9f5c3f7590b5d8cbcd8d2c1aba62053566eac70c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 1 Jan 2025 23:38:50 -0600 Subject: [PATCH 68/72] add `llvm_floatabi` to armv7a-vex-v5 spec --- compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index 837255f6585ed..f8d653e757ef2 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; +use crate::spec::{ + Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions, +}; const LINK_SCRIPT: &str = include_str!("./armv7a_vex_v5_linker_script.ld"); @@ -15,6 +17,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: "arm".into(), options: TargetOptions { + llvm_floatabi: Some(FloatAbi::Hard), os: "vexos".into(), is_like_vexos: true, vendor: "vex".into(), From 2081cf5a12da8eeabda5e8d557fb93a9d8940cd5 Mon Sep 17 00:00:00 2001 From: doinkythederp Date: Thu, 2 Jan 2025 14:25:37 -0800 Subject: [PATCH 69/72] serialize `is_like_vexos` in target json specs --- compiler/rustc_target/src/spec/json.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index 9cdc0801b1f00..04bc7736c3a85 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -571,6 +571,7 @@ impl Target { key!(is_like_msvc, bool); key!(is_like_wasm, bool); key!(is_like_android, bool); + key!(is_like_vexos, bool); key!(default_dwarf_version, u32); key!(allows_weak_linkage, bool); key!(has_rpath, bool); @@ -746,6 +747,7 @@ impl ToJson for Target { target_option_val!(is_like_msvc); target_option_val!(is_like_wasm); target_option_val!(is_like_android); + target_option_val!(is_like_vexos); target_option_val!(default_dwarf_version); target_option_val!(allows_weak_linkage); target_option_val!(has_rpath); From d0d1fd987dbc8a58001d13602cf72a7af1f9a982 Mon Sep 17 00:00:00 2001 From: doinkythederp Date: Thu, 2 Jan 2025 15:57:45 -0800 Subject: [PATCH 70/72] ensure `arm` arch before adjusting VEXos system ABI to `aapcs` --- compiler/rustc_target/src/spec/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index bb58191e358d2..a32138d7e38f9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2821,7 +2821,9 @@ impl Target { Abi::System { unwind } if self.is_like_windows && self.arch == "x86" && !c_variadic => { Abi::Stdcall { unwind } } - Abi::System { unwind } if self.is_like_vexos && !c_variadic => Abi::Aapcs { unwind }, + Abi::System { unwind } if self.is_like_vexos && self.arch == "arm" && !c_variadic => { + Abi::Aapcs { unwind } + } Abi::System { unwind } => Abi::C { unwind }, Abi::EfiApi if self.arch == "arm" => Abi::Aapcs { unwind: false }, Abi::EfiApi if self.arch == "x86_64" => Abi::Win64 { unwind: false }, From ee12faa1bb3986b2259e113d0ad5f724ab4f107f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 25 Jan 2025 08:30:47 -0600 Subject: [PATCH 71/72] bless tests, add `armv7a-vex-v5` to assembly tests --- tests/assembly/targets/targets-elf.rs | 3 +++ tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr | 2 +- tests/ui/check-cfg/exhaustive-names-values.feature.stderr | 2 +- tests/ui/check-cfg/exhaustive-names-values.full.stderr | 2 +- tests/ui/check-cfg/well-known-values.stderr | 6 +++--- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 6bb3389c40959..c659a65a59a9d 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -186,6 +186,9 @@ //@ revisions: armv7a_nuttx_eabihf //@ [armv7a_nuttx_eabihf] compile-flags: --target armv7a-nuttx-eabihf //@ [armv7a_nuttx_eabihf] needs-llvm-components: arm +//@ revisions: armv7a_vex_v5 +//@ [armv7a_vex_v5] compile-flags: --target armv7a-vex-v5 +//@ [armv7a_vex_v5] needs-llvm-components: arm //@ revisions: armv7r_none_eabi //@ [armv7r_none_eabi] compile-flags: --target armv7r-none-eabi //@ [armv7r_none_eabi] needs-llvm-components: arm diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr index 23b6edacce77c..36420cc165074 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr @@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value` LL | #[cfg(target_vendor = "value")] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs` + = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `vex`, `win7`, and `wrs` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr index 804d7fb9163d7..e9e9f540be802 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr @@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value` LL | #[cfg(target_vendor = "value")] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs` + = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `vex`, `win7`, and `wrs` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr index 804d7fb9163d7..e9e9f540be802 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr @@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value` LL | #[cfg(target_vendor = "value")] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs` + = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `vex`, `win7`, and `wrs` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 7a572a30cf421..82d8c1a20b049 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -230,7 +230,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_vendor = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs` + = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `vex`, `win7`, and `wrs` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: 28 warnings emitted From d9a13494d3ae3d9270f9ccb301df80ed3bae1b27 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:25:20 -0600 Subject: [PATCH 72/72] backlink to relevant cleanup issues in FIXMEs --- src/bootstrap/Cargo.toml | 3 ++- src/bootstrap/src/lib.rs | 5 +++-- src/tools/tidy/src/extdeps.rs | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index ea9776bd69a8f..e7a21882eaceb 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -98,5 +98,6 @@ debug = 0 bootstrap.debug = 1 [patch.crates-io] -# FIXME: remove this once the `armv7a-vex-v5` target is available on nightly and cc-rs is updated with it +# FIXME: Remove this once a nightly is published with `armv7a-vex-v5` support, +# see https://github.com/rust-lang/rust/issues/136075 cc = { git = "https://github.com/rust-lang/cc-rs", rev = "6fe995c675dc1178f570752fa8f6de82913a91dc" } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index e3dfac2334adf..d604ea4cb82ec 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -617,8 +617,9 @@ impl Build { if self.config.profiler_enabled(target) { features.insert("profiler"); } - // Generate memcpy, etc. FIXME: Remove this once compiler-builtins - // automatically detects this target. + // Generate memcpy, etc. + // FIXME: Remove this once compiler-builtins automatically detects this target, + // see if target.contains("zkvm") || target.contains("vex") { features.insert("compiler-builtins-mem"); } diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index be19807c7e6a2..8d594db132d34 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -9,6 +9,8 @@ const ALLOWED_SOURCES: &[&str] = &[ // This is `rust_team_data` used by `site` in src/tools/rustc-perf, r#""git+https://github.com/rust-lang/team#a5260e76d3aa894c64c56e6ddc8545b9a98043ec""#, // This is temporarily used to bootstrap the `armv7a_vex_v5` target until cc-rs has it in its generated target list. + // FIXME: Remove this once a nightly is published with `armv7a-vex-v5` support, + // see r#""git+https://github.com/rust-lang/cc-rs?rev=6fe995c675dc1178f570752fa8f6de82913a91dc#6fe995c675dc1178f570752fa8f6de82913a91dc""#, ];