From a5ccf0ad0dc62fb32e7e912fdc4a134bc2f04055 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 bfe6f4441471..0663c213aa0a 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1946,6 +1946,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 000000000000..bac7747e7d80 --- /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 000000000000..f9436907c7fe --- /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 a149b597094911a41c785faa9da9665510abffec 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 e7f7f38cb415..b9e9fc93597f 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 8dc326a3dde6..e61e59b5fd62 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 9be018c8a531..45c692c805c8 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 000000000000..d57afead5606 --- /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 ed0155622c22..c8e65bc4c79f 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 8405c22aff08..8ee9774488cb 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -641,9 +641,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 4b7ba7fe88dcc24dc1e63c74b28d8bd925612bd5 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 f9436907c7fe..c62b872fd84c 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 dc2b42bb90ae..6e2b29a41a99 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 b9e9fc93597f..7c217e8bcd43 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 000000000000..8ff93fe03335 --- /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 d57afead5606..26423c68a8ca 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 000000000000..eb09b4a5c51d --- /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 ce7fc68073e27ffe0633ebbd3d194e74b68f7b9f 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 c62b872fd84c..ccdd6110e2eb 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 7c217e8bcd43..9dadfc216479 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 26423c68a8ca..41354a20603c 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 45ea8cb230e4082fa94e4946e2ea6c9bc0d76a6f 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 41354a20603c..c077871671c6 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 c2b14c078b7367f109384842c2987b4086eecec4 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 f0a13323ec93..e74e0fe3fc6a 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 75474a5e85ad9c59016866bc1924a45caff11bc5 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 ccdd6110e2eb..a3d45b0a660c 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 8ff93fe03335..f760ebef770f 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 061ac0e864083881a174e75adbc7395f519ad7ab 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 c077871671c6..e0466b90b8a6 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 eb09b4a5c51d..998592e76243 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 a372ca073ac0c333b6258220652909267ca6ef7a 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 e0466b90b8a6..432e041d3cfa 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 000000000000..94699d64d230 --- /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 a95f748ee1917b2766afa0c4f0cd7e2ef3cc2710 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 432e041d3cfa..9189ac2a4792 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 9fd7615d24ce702bca56f2e21b32d1962f4188ed 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 a3d45b0a660c..8ff88f24adf3 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 d9edb32390ad8be04c73f0a3c55bf4f318c8a6c3 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 8ff88f24adf3..37fc390401ea 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 9189ac2a4792..cb80cf675a09 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 8ef0fe54928512b161e8be390d4f908fbf7a28c2 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 bac7747e7d80..bc117b64c230 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 264ea447a1bacaae7307e14dc268b35a57f1097d 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 bc117b64c230..a6a6f542e310 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 70448c0c9918b183aea2ef16226e316f5d48b7fd 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 000000000000..381658cfd342 --- /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 a5682b6c584d74699dbf42028f2d8cb591d16e7e 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 000000000000..005dc2645990 --- /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 cb80cf675a09..bd99234b9e19 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 32ea1c33f6511a5b9bbe159b631693b56cf9e9e7 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 005dc2645990..ba5a704dbb76 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 d48c4226db5d99e5ded51c48c602c7efd25c8bf7 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 ba5a704dbb76..7368eaecf604 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 efd26d98ec0549cbe8b9d8bc38cb73abcd228b19 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 7368eaecf604..95eb9707539f 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 503c7b17d9dc97202d43d4c6fe014c7ad7f5c33e 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 95eb9707539f..aa7e8540292f 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 1f57c2ca43f15c763037a7bc4cd836dd8109cddf 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 aa7e8540292f..a56ea5c4da0d 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 ebcd00ec78a3d90db0b404e709e66daf26e03f26 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 a56ea5c4da0d..2a4c9511d45a 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 d24f0400924ec2f89c7f1a276eeb897cd2eecdfb 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 bd99234b9e19..2469b6fa855e 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 ed278efd027de5a1d8fae1a21d9dd63dc1e90790 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 2a4c9511d45a..785639ad1d34 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 6b3acd6c6b877efc7901fb0d6036d4e596576c7f 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 785639ad1d34..43f637c30ce2 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 7a06d082eb2ac76316df0b9f907fe9f19f1084fd 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 43f637c30ce2..614dfc133df9 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 2cbbabb32bf534d05044735ef63314512cad596c 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 614dfc133df9..0d248f3770b2 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 a5b7a200f046835c412b8d8dade7cdb244a55b88 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 0d248f3770b2..f5cb0a961cf2 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 2469b6fa855e..ab3d2505ec6f 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 998592e76243..a9e05e3537f8 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 2883fb27a07bb04f770167377a89c5645dea6573 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 ab3d2505ec6f..b2f3361ac66c 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 e5018c1942e2090f92b4e6ca15fd2b72ca193cb0 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 1d202402288c..be5aa5a0d509 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 000000000000..897e884c6550 --- /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 71b8640394d0c0e841916a19af187c8881c69eaa 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 207c744ee224..7dc604b49438 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 a9d1f53761cb..e73db243560e 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 9dadfc216479..065ef752d2b3 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 897e884c6550..de009d78cfcb 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 3ec948ebdcad73b0c66100c1e3ee192e17efd9e2 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 f5cb0a961cf2..7d8af80fd94d 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 b2f3361ac66c..6ca3d23f6355 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 f1eaddec180f152a20480ab03941299df3c305ff 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 a6a6f542e310..418bf2a0c5bc 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 be5aa5a0d509..c0f483d359b7 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 5fa6b4c2b0dc59f7f85d60d1d21650b12c29e7ad 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 418bf2a0c5bc..6a5714b02fc6 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 5c0588035da9f5b99d717dfead53cf7489daf713 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 6ca3d23f6355..9c034252b7f9 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 ccf19efe44c13b7024b5c9360c5de2bd280a9e71 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 6a5714b02fc6..f661a5931e7a 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 887ff2d876b9dd7249ac18b8079359284b5573f3 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 9c034252b7f9..69599d03dc1c 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 a9e05e3537f8..57557ead13f6 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 53e5abc7ef8c2fecc9861cface388ed200790204 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 f661a5931e7a..d986132e251d 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 69599d03dc1c..421d4cb2c831 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 94699d64d230..60805ea2759d 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 de009d78cfcb..4a0d82126163 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 729072b777d29bf3413ef6aea42b34496510122b 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 0663c213aa0a..964a793a7aec 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2330,6 +2330,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, @@ -2706,6 +2708,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, @@ -2813,6 +2816,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 d986132e251d..5451c0e12a8e 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 7dc604b49438..8f538d8ec761 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 065ef752d2b3..5d3b0bad0235 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 f760ebef770f..04d13e00a534 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 71875d30769ad1ffc9b89a0ead736051fca5237d 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 37fc390401ea..63bca9d44168 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 421d4cb2c831..43275ba02d75 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 5371b62b07ea865bd5e2f9d656ee2e024691b92e 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 43275ba02d75..84f42d5dab7a 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 e74e0fe3fc6a..30504c0c2b39 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 be3dd7a0079736acacdadb5a2b1c087b6a430070 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 84f42d5dab7a..0fc76a844446 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 f42351deb92c..a406aef53d1e 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 5efc465dd4f546b249f319ec06f9c5347919e6f1 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 2c0b533a5703..1a41fa9f3adf 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 04d13e00a534..e1033f4a62cf 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 e41b73b09a5e956e127981cf75909691bf251fea 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 63bca9d44168..1a7a8d2e38b7 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 7fbb6731b059c65c0d1a0bf5773903a3e6519e29 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 4a0d82126163..e20fd539bb55 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 397702789b20f88cd2ae538ecd3e116e6cf5c9ce 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 8f538d8ec761..f7cd928eca95 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 5d3b0bad0235..0f717dbc6f88 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 b71ce92771ae..33069cddfdb8 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -487,6 +487,7 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ "shlex", "unicode-width", "unwinding", + "vex-sdk", "wasi", "windows-sys", "windows-targets", From 43365245ea7bc21b2c357ff0dd1053914bfa23be 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 --- tests/assembly/targets/targets-elf.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 69b42de9e102..c3bdeb1dc7bc 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -177,6 +177,9 @@ //@ revisions: armv7a_none_eabihf //@ [armv7a_none_eabihf] compile-flags: --target armv7a-none-eabihf //@ [armv7a_none_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 From da8d8047e6c32188d3ce95d13bda2d1cd48bbd11 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Thu, 10 Oct 2024 23:54:17 -0700 Subject: [PATCH 48/72] bless well-known-values test --- library/backtrace | 2 +- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/tools/cargo | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/backtrace b/library/backtrace index f8cc6ac9acc4..230570f2dac8 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit f8cc6ac9acc4e663ecd96f9bcf1ff4542636d1b9 +Subproject commit 230570f2dac80a601f5c0b30da00cc9480bd35eb diff --git a/src/doc/book b/src/doc/book index 04d06dfe5416..ad2011d3bcad 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 04d06dfe541607e6419f3d028c3f9b245f3be4d9 +Subproject commit ad2011d3bcad9f152d034faf7635c22506839d58 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index d56e0f3a0656..bc4ce51e1d4d 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit d56e0f3a0656b7702ca466d4b191e16c28262b82 +Subproject commit bc4ce51e1d4dacb9350a92e95f6159a42de2f8c6 diff --git a/src/doc/nomicon b/src/doc/nomicon index 7ef05b9777c9..97e84a38c94b 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 7ef05b9777c94836bc92f50f23e6e00981521a89 +Subproject commit 97e84a38c94bf9362b11284c20b2cb4adaa1e868 diff --git a/src/doc/reference b/src/doc/reference index acd6794e712d..9f41bc11342d 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit acd6794e712d5e2ef6f5c84fb95688d32a69b816 +Subproject commit 9f41bc11342d46544ae0732caf14ec0bcaf27376 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 093397535b48..76406337f413 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 093397535b48ae13ec76bc526b7e6eb8c096a85c +Subproject commit 76406337f4131253443aea0ed7e7f451b464117c diff --git a/src/tools/cargo b/src/tools/cargo index fd784878cfa8..c86f4b3a1b15 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit fd784878cfa843e3e29a6654ecf564c62fae6735 +Subproject commit c86f4b3a1b153218e6e50861214b0b4b4e695f23 From 3a06fc8ebc63e020b42bb7a77882b3bae2f2b2de Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Fri, 11 Oct 2024 02:12:09 -0700 Subject: [PATCH 49/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 01fabfb39a77..b1cdc08954bf 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 a47c7df43f45472123d0109c35ef9fa64d61652a Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Fri, 11 Oct 2024 10:09:41 -0700 Subject: [PATCH 50/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 964a793a7aec..53716236ef72 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2330,7 +2330,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 b66a0f71984a1022f8a3bd41c234279224493e83 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Fri, 11 Oct 2024 10:29:30 -0700 Subject: [PATCH 51/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 e20fd539bb55..20f90583e5e1 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 73dffc688fc51acb28aa9261c5ca0f1dc858e449 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 52/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 1a7a8d2e38b7..319f29a281d5 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 5a43c3902b01e4812eece79bc198520b7625101e 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 53/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 5451c0e12a8e..af784dcc52cd 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 5c1898a0ae36..7a572a30cf42 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 50cf19a585799885d8aabbc39a51b3919f286e1f 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 54/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 57557ead13f6..d0800682ff7e 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 20f90583e5e1..1cd3e889bd88 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 8a2d12bce185338092ddbde00b58bac6502e0e3b 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 55/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 0fc76a844446..8fab2da5fa5b 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 dba2111330f40962ce33943e6f8432e8b2bcd46b 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 56/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 f7cd928eca95..8e53abb8c7db 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 0f717dbc6f88..3531840017a0 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 8fab2da5fa5b..49b55eb9c7f3 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 8e5361bdbe261c7654af2cb602421cac8545a74f 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 57/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 49b55eb9c7f3..282443046b10 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 000000000000..b355a6bfd72d --- /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 c60ba56770bcb7042808dacea2a29a34fb19d6e5 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 29 Oct 2024 21:21:16 -0700 Subject: [PATCH 58/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 b355a6bfd72d..f00ff9f7b106 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 539baf15de32604e24674c200a84579077575d32 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 59/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 af784dcc52cd..837255f6585e 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 c0c18aacab9b69ef505456b197009a57ad9b1142 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 60/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 7d8af80fd94d..142ec81b84d1 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 d46d9e63f2cf47f66ce450d2d6df69397b1e86b5 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 61/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 142ec81b84d1..e7f195ec50e5 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 53447c9d32cf00a740f3991334315db0b205d6a9 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 62/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 d0800682ff7e..94c834843806 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 70ef480d67aa88d4aa871b887bfc87b609f16752 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 63/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 e7f195ec50e5..3087adc7405c 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 668dfa46770b175620e8fa31c892f69e21287ab5 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 64/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 3531840017a0..fe191c72f4b4 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 1b9d337c16ae612caf6bdadac51ffb8545c0e8a3 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 65/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 8e53abb8c7db..6d4831be304b 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 1e2ba271c09d252680bbcde812c74c0130043b99 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 31 Dec 2024 16:15:15 -0800 Subject: [PATCH 66/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 c9697e670b77..8728ccd78c0d 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -85,8 +85,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 d8775a67e193..8bf90427c568 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -90,3 +90,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 55f937aeacf5..be19807c7e6a 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 82f85a55cb189ca3e3ff1cbc077cc8e7e85fe219 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 31 Dec 2024 16:24:01 -0800 Subject: [PATCH 67/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 3087adc7405c..2e1fdf1bbcd5 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 55869f44b79543476e1b6504c9754524aadda592 Mon Sep 17 00:00:00 2001 From: Max Niederman Date: Tue, 31 Dec 2024 16:29:01 -0800 Subject: [PATCH 68/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 2e1fdf1bbcd5..1014bab30bb8 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 fbd50d7c20eacf1e92f37da269eb69981bd7fe88 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 69/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 837255f6585e..f8d653e757ef 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 952258724b8a93b3979f7cb362e0fad68451b034 Mon Sep 17 00:00:00 2001 From: doinkythederp Date: Thu, 2 Jan 2025 14:25:37 -0800 Subject: [PATCH 70/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 9cdc0801b1f0..04bc7736c3a8 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 3f6b70c3885c2dd6370d943ee735206d2ff45194 Mon Sep 17 00:00:00 2001 From: doinkythederp Date: Thu, 2 Jan 2025 15:57:45 -0800 Subject: [PATCH 71/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 53716236ef72..df5acfba0af6 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2817,7 +2817,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 20144f81bae8370fef56e52e9310f3bd2c5fcc02 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 5 Jan 2025 18:26:30 -0600 Subject: [PATCH 72/72] bless `well-known-values` test again --- 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 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) 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 23b6edacce77..36420cc16507 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 804d7fb9163d..e9e9f540be80 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 804d7fb9163d..e9e9f540be80 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 7a572a30cf42..82d8c1a20b04 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