Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions base/cp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "cp"
version = "0.1.0"
edition = "2021"
authors = ["vibix hackers"]
license = "MIT OR Apache-2.0"

[[bin]]
name = "cp"
path = "src/main.rs"

# Standalone package — not part of the main workspace. Built with
# `-Z build-std` against the in-repo std fork (see xtask build).
[workspace]
27 changes: 27 additions & 0 deletions base/cp/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![feature(restricted_std)]

#[cfg(not(test))]
mod syscalls;

use std::env;
use std::fs;
use std::process::ExitCode;

fn main() -> ExitCode {
let args: Vec<String> = env::args().collect();

if args.len() != 3 {
eprintln!("usage: cp <src> <dst>");
return ExitCode::from(1);
}

let src = &args[1];
let dst = &args[2];

if let Err(e) = fs::copy(src, dst) {
eprintln!("cp: {src} -> {dst}: {e}");
return ExitCode::from(1);
}

ExitCode::from(0)
}
50 changes: 50 additions & 0 deletions base/cp/src/syscalls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! C-ABI syscall shims required by the vibix std fork.
//!
//! The in-repo std fork links against POSIX symbols (`close`, etc.) that are
//! not provided by a system libc on vibix. We supply them here via raw
//! syscall instructions, mirroring the approach in `base/sh/src/syscalls.rs`.

use core::arch::asm;

const SYS_CLOSE: u64 = 3;

extern "C" {
fn __errno_location() -> *mut i32;
}

#[inline(always)]
unsafe fn raw1(nr: u64, a0: u64) -> i64 {
let ret: i64;
unsafe {
asm!(
"syscall",
inlateout("rax") nr => ret,
inlateout("rdi") a0 => _,
lateout("rcx") _,
lateout("r11") _,
lateout("rdx") _,
lateout("rsi") _,
lateout("r8") _,
lateout("r9") _,
lateout("r10") _,
options(nostack),
);
}
ret
}

/// Convert raw syscall return to C convention: on error set errno, return -1.
#[inline]
unsafe fn cvt(r: i64) -> i64 {
if r < 0 {
unsafe { *__errno_location() = (-r) as i32 };
-1
} else {
r
}
}

#[no_mangle]
pub unsafe extern "C" fn close(fd: i32) -> i32 {
unsafe { cvt(raw1(SYS_CLOSE, fd as u64)) as i32 }
Comment on lines +15 to +49
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify how many duplicated syscall shims exist and whether they are identical.
fd -a 'syscalls\.rs$' base | sort | while read -r file; do
  printf '%s  %s\n' "$(sha256sum "$file" | cut -d' ' -f1)" "$file"
done | sort

printf '\n=== raw1 / close definitions across base/*/src/syscalls.rs ===\n'
rg -n -C2 'unsafe fn raw1|pub unsafe extern "C" fn close' base --glob '*/src/syscalls.rs'

Repository: dburkart/vibix

Length of output: 1178


🏁 Script executed:

# First, let's look at the structure of a few syscalls.rs files
echo "=== Content of base/cp/src/syscalls.rs ===" 
head -60 base/cp/src/syscalls.rs

echo -e "\n=== Content of base/mkdir/src/syscalls.rs ===" 
head -60 base/mkdir/src/syscalls.rs

echo -e "\n=== Content of base/cat/src/syscalls.rs ===" 
head -60 base/cat/src/syscalls.rs

Repository: dburkart/vibix

Length of output: 3858


🏁 Script executed:

# Extract the raw1 function's options() call from all syscalls.rs files to check for variations
echo "=== Checking asm! options across all base/*/src/syscalls.rs ==="
for file in base/*/src/syscalls.rs; do
  echo "--- $file ---"
  grep -A 8 'asm!' "$file" | grep 'options('
done

# Also count total lines in each file to see if they differ in content
echo -e "\n=== File line counts ==="
wc -l base/*/src/syscalls.rs | sort -k2

Repository: dburkart/vibix

Length of output: 872


🏁 Script executed:

# Extract the asm! block with options() more carefully
echo "=== Comparing asm! options() calls ==="
for file in base/*/src/syscalls.rs; do
  echo "--- $file ---"
  sed -n '19,29p' "$file" | grep -E '(asm!|options)'
done

# Let's also see the full asm! block for each
echo -e "\n=== Full asm! blocks (lines 19-29) ==="
for file in base/*/src/syscalls.rs; do
  echo "--- $file ---"
  sed -n '19,29p' "$file"
done

Repository: dburkart/vibix

Length of output: 4536


🏁 Script executed:

# Look further down to find the options() lines
echo "=== Looking for options() lines in asm! blocks ==="
for file in base/*/src/syscalls.rs; do
  echo "--- $file ---"
  sed -n '27,32p' "$file" | grep -E 'options|^[[:space:]]*\);'
done

# Also show wider context to catch the exact lines
echo -e "\n=== Exact options() lines with context ==="
rg 'options\(' base --glob '*/src/syscalls.rs' -B1 -A1

Repository: dburkart/vibix

Length of output: 964


Consolidate duplicated syscall shims—inconsistencies have already emerged across copies.

The raw1/cvt/close shim is now duplicated across 10 crates. More critically, these copies have already diverged: cat and ls use options(nostack, preserves_flags) in their asm! blocks, while cp, mkdir, mv, rm, rmdir, stat, touch, and uname use only options(nostack). This inconsistency is exactly the maintainability risk this structure creates—fixes and updates land unevenly and go unnoticed.

Move this shim into a single shared module or helper crate, or have the build system inject it consistently, so ABI-sensitive code like syscall assembly stays synchronized across all utilities.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@base/cp/src/syscalls.rs` around lines 15 - 49, Duplicate and diverging
syscall shim (raw1, cvt, close) across crates must be centralized: extract
unsafe fn raw1, unsafe fn cvt, and the extern "C" close shim (and any SYS_* and
__errno_location uses) into a single shared module or small helper crate and
update all utilities to import that module (or have the build system inject the
same file) so there's a single authoritative implementation; when moving,
standardize the inline asm options to include preserves_flags (use
options(nostack, preserves_flags)) and keep the ABI and symbol names (raw1, cvt,
close, SYS_CLOSE, __errno_location) unchanged so callers stay compatible.

}
14 changes: 14 additions & 0 deletions base/mkdir/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "mkdir"
version = "0.1.0"
edition = "2021"
authors = ["vibix hackers"]
license = "MIT OR Apache-2.0"

[[bin]]
name = "mkdir"
path = "src/main.rs"

# Standalone package — not part of the main workspace. Built with
# `-Z build-std` against the in-repo std fork (see xtask build).
[workspace]
27 changes: 27 additions & 0 deletions base/mkdir/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![feature(restricted_std)]

#[cfg(not(test))]
mod syscalls;

use std::env;
use std::fs;
use std::process::ExitCode;

fn main() -> ExitCode {
let args: Vec<String> = env::args().collect();

if args.len() <= 1 {
eprintln!("mkdir: missing operand");
return ExitCode::from(1);
}

let mut status: u8 = 0;
for path in &args[1..] {
if let Err(e) = fs::create_dir(path) {
eprintln!("mkdir: {path}: {e}");
status = 1;
}
}

ExitCode::from(status)
}
50 changes: 50 additions & 0 deletions base/mkdir/src/syscalls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! C-ABI syscall shims required by the vibix std fork.
//!
//! The in-repo std fork links against POSIX symbols (`close`, etc.) that are
//! not provided by a system libc on vibix. We supply them here via raw
//! syscall instructions, mirroring the approach in `base/sh/src/syscalls.rs`.

use core::arch::asm;

const SYS_CLOSE: u64 = 3;

extern "C" {
fn __errno_location() -> *mut i32;
}

#[inline(always)]
unsafe fn raw1(nr: u64, a0: u64) -> i64 {
let ret: i64;
unsafe {
asm!(
"syscall",
inlateout("rax") nr => ret,
inlateout("rdi") a0 => _,
lateout("rcx") _,
lateout("r11") _,
lateout("rdx") _,
lateout("rsi") _,
lateout("r8") _,
lateout("r9") _,
lateout("r10") _,
options(nostack),
);
}
ret
}

/// Convert raw syscall return to C convention: on error set errno, return -1.
#[inline]
unsafe fn cvt(r: i64) -> i64 {
if r < 0 {
unsafe { *__errno_location() = (-r) as i32 };
-1
} else {
r
}
}

#[no_mangle]
pub unsafe extern "C" fn close(fd: i32) -> i32 {
unsafe { cvt(raw1(SYS_CLOSE, fd as u64)) as i32 }
}
14 changes: 14 additions & 0 deletions base/mv/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "mv"
version = "0.1.0"
edition = "2021"
authors = ["vibix hackers"]
license = "MIT OR Apache-2.0"

[[bin]]
name = "mv"
path = "src/main.rs"

# Standalone package — not part of the main workspace. Built with
# `-Z build-std` against the in-repo std fork (see xtask build).
[workspace]
27 changes: 27 additions & 0 deletions base/mv/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![feature(restricted_std)]

#[cfg(not(test))]
mod syscalls;

use std::env;
use std::fs;
use std::process::ExitCode;

fn main() -> ExitCode {
let args: Vec<String> = env::args().collect();

if args.len() != 3 {
eprintln!("usage: mv <src> <dst>");
return ExitCode::from(1);
}

let src = &args[1];
let dst = &args[2];

if let Err(e) = fs::rename(src, dst) {
eprintln!("mv: {src} -> {dst}: {e}");
return ExitCode::from(1);
}

ExitCode::from(0)
}
50 changes: 50 additions & 0 deletions base/mv/src/syscalls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! C-ABI syscall shims required by the vibix std fork.
//!
//! The in-repo std fork links against POSIX symbols (`close`, etc.) that are
//! not provided by a system libc on vibix. We supply them here via raw
//! syscall instructions, mirroring the approach in `base/sh/src/syscalls.rs`.

use core::arch::asm;

const SYS_CLOSE: u64 = 3;

extern "C" {
fn __errno_location() -> *mut i32;
}

#[inline(always)]
unsafe fn raw1(nr: u64, a0: u64) -> i64 {
let ret: i64;
unsafe {
asm!(
"syscall",
inlateout("rax") nr => ret,
inlateout("rdi") a0 => _,
lateout("rcx") _,
lateout("r11") _,
lateout("rdx") _,
lateout("rsi") _,
lateout("r8") _,
lateout("r9") _,
lateout("r10") _,
options(nostack),
);
}
ret
}

/// Convert raw syscall return to C convention: on error set errno, return -1.
#[inline]
unsafe fn cvt(r: i64) -> i64 {
if r < 0 {
unsafe { *__errno_location() = (-r) as i32 };
-1
} else {
r
}
}

#[no_mangle]
pub unsafe extern "C" fn close(fd: i32) -> i32 {
unsafe { cvt(raw1(SYS_CLOSE, fd as u64)) as i32 }
}
14 changes: 14 additions & 0 deletions base/rm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "rm"
version = "0.1.0"
edition = "2021"
authors = ["vibix hackers"]
license = "MIT OR Apache-2.0"

[[bin]]
name = "rm"
path = "src/main.rs"

# Standalone package — not part of the main workspace. Built with
# `-Z build-std` against the in-repo std fork (see xtask build).
[workspace]
27 changes: 27 additions & 0 deletions base/rm/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![feature(restricted_std)]

#[cfg(not(test))]
mod syscalls;

use std::env;
use std::fs;
use std::process::ExitCode;

fn main() -> ExitCode {
let args: Vec<String> = env::args().collect();

if args.len() <= 1 {
eprintln!("rm: missing operand");
return ExitCode::from(1);
}

let mut status: u8 = 0;
for path in &args[1..] {
if let Err(e) = fs::remove_file(path) {
eprintln!("rm: {path}: {e}");
status = 1;
}
}

ExitCode::from(status)
}
50 changes: 50 additions & 0 deletions base/rm/src/syscalls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! C-ABI syscall shims required by the vibix std fork.
//!
//! The in-repo std fork links against POSIX symbols (`close`, etc.) that are
//! not provided by a system libc on vibix. We supply them here via raw
//! syscall instructions, mirroring the approach in `base/sh/src/syscalls.rs`.

use core::arch::asm;

const SYS_CLOSE: u64 = 3;

extern "C" {
fn __errno_location() -> *mut i32;
}

#[inline(always)]
unsafe fn raw1(nr: u64, a0: u64) -> i64 {
let ret: i64;
unsafe {
asm!(
"syscall",
inlateout("rax") nr => ret,
inlateout("rdi") a0 => _,
lateout("rcx") _,
lateout("r11") _,
lateout("rdx") _,
lateout("rsi") _,
lateout("r8") _,
lateout("r9") _,
lateout("r10") _,
options(nostack),
);
}
ret
}

/// Convert raw syscall return to C convention: on error set errno, return -1.
#[inline]
unsafe fn cvt(r: i64) -> i64 {
if r < 0 {
unsafe { *__errno_location() = (-r) as i32 };
-1
} else {
r
}
}

#[no_mangle]
pub unsafe extern "C" fn close(fd: i32) -> i32 {
unsafe { cvt(raw1(SYS_CLOSE, fd as u64)) as i32 }
}
14 changes: 14 additions & 0 deletions base/rmdir/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "rmdir"
version = "0.1.0"
edition = "2021"
authors = ["vibix hackers"]
license = "MIT OR Apache-2.0"

[[bin]]
name = "rmdir"
path = "src/main.rs"

# Standalone package — not part of the main workspace. Built with
# `-Z build-std` against the in-repo std fork (see xtask build).
[workspace]
Loading
Loading