Initial commit
This commit is contained in:
commit
7ed747351a
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "yggdrasil-abi"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
||||
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
||||
compiler_builtins = { version = "0.1", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
rustc-dep-of-std = ["core", "alloc", "compiler_builtins/rustc-dep-of-std"]
|
130
src/error.rs
Normal file
130
src/error.rs
Normal file
@ -0,0 +1,130 @@
|
||||
use crate::io::RawFd;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
OutOfMemory = 1,
|
||||
InvalidMemoryOperation,
|
||||
AlreadyExists,
|
||||
TimedOut,
|
||||
InvalidArgument,
|
||||
DoesNotExist,
|
||||
IsADirectory,
|
||||
InvalidFile,
|
||||
}
|
||||
|
||||
pub trait FromSyscallResult: Sized {
|
||||
fn from_syscall_result(value: usize) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
pub trait IntoSyscallResult {
|
||||
fn into_syscall_result(self) -> usize;
|
||||
}
|
||||
|
||||
pub trait SyscallError {
|
||||
fn from_syscall_error(value: usize) -> Self;
|
||||
fn into_syscall_error(self) -> usize;
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for Error {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u32) -> Result<Self, ()> {
|
||||
match value {
|
||||
1 => Ok(Self::OutOfMemory),
|
||||
2 => Ok(Self::InvalidMemoryOperation),
|
||||
3 => Ok(Self::AlreadyExists),
|
||||
4 => Ok(Self::TimedOut),
|
||||
5 => Ok(Self::InvalidArgument),
|
||||
6 => Ok(Self::DoesNotExist),
|
||||
7 => Ok(Self::IsADirectory),
|
||||
8 => Ok(Self::InvalidFile),
|
||||
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for u32 {
|
||||
fn from(value: Error) -> Self {
|
||||
match value {
|
||||
Error::OutOfMemory => 1,
|
||||
Error::InvalidMemoryOperation => 2,
|
||||
Error::AlreadyExists => 3,
|
||||
Error::TimedOut => 4,
|
||||
Error::InvalidArgument => 5,
|
||||
Error::DoesNotExist => 6,
|
||||
Error::IsADirectory => 7,
|
||||
Error::InvalidFile => 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SyscallError for Error {
|
||||
fn from_syscall_error(value: usize) -> Self {
|
||||
Error::try_from((-(value as isize)) as u32).unwrap_or(Error::InvalidArgument)
|
||||
}
|
||||
|
||||
fn into_syscall_error(self) -> usize {
|
||||
(-((self as u32) as isize)) as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoSyscallResult> IntoSyscallResult for Result<T, Error> {
|
||||
fn into_syscall_result(self) -> usize {
|
||||
match self {
|
||||
Ok(t) => t.into_syscall_result(),
|
||||
Err(e) => e.into_syscall_error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSyscallResult for () {
|
||||
fn from_syscall_result(value: usize) -> Result<Self, Error> {
|
||||
if (value as isize) < 0 {
|
||||
Err(Error::from_syscall_error(value))
|
||||
} else {
|
||||
// TODO assert value == 0
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoSyscallResult for () {
|
||||
fn into_syscall_result(self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSyscallResult for usize {
|
||||
fn from_syscall_result(value: usize) -> Result<Self, Error> {
|
||||
if (value as isize) < 0 {
|
||||
Err(Error::from_syscall_error(value))
|
||||
} else {
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoSyscallResult for usize {
|
||||
fn into_syscall_result(self) -> usize {
|
||||
assert!((self as isize) >= 0);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSyscallResult for RawFd {
|
||||
fn from_syscall_result(value: usize) -> Result<Self, Error> {
|
||||
if (value as isize) < 0 {
|
||||
Err(Error::from_syscall_error(value))
|
||||
} else {
|
||||
// TODO assert value < u32::MAX
|
||||
Ok(RawFd(value as u32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoSyscallResult for RawFd {
|
||||
fn into_syscall_result(self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
}
|
48
src/io.rs
Normal file
48
src/io.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use core::fmt;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug, PartialOrd, Ord, Eq)]
|
||||
pub struct RawFd(pub u32);
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct OpenFlags(pub u32);
|
||||
|
||||
const O_READ: u32 = 1 << 0;
|
||||
const O_WRITE: u32 = 1 << 1;
|
||||
|
||||
impl RawFd {
|
||||
pub const STDOUT: Self = Self(1);
|
||||
pub const STDERR: Self = Self(2);
|
||||
}
|
||||
|
||||
impl OpenFlags {
|
||||
pub fn new() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
pub const fn read(mut self) -> Self {
|
||||
self.0 |= O_READ;
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn write(mut self) -> Self {
|
||||
self.0 |= O_WRITE;
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn is_read(self) -> bool {
|
||||
self.0 & O_READ != 0
|
||||
}
|
||||
|
||||
pub const fn is_write(self) -> bool {
|
||||
self.0 & O_WRITE != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for OpenFlags {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("OpenFlags")
|
||||
.field("read", &(self.is_read()))
|
||||
.field("write", &(self.is_write()))
|
||||
.finish()
|
||||
}
|
||||
}
|
57
src/lib.rs
Normal file
57
src/lib.rs
Normal file
@ -0,0 +1,57 @@
|
||||
#![no_std]
|
||||
|
||||
pub mod error;
|
||||
pub mod io;
|
||||
pub mod path;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum SyscallFunction {
|
||||
Exit = 1,
|
||||
Nanosleep = 2,
|
||||
MapMemory = 3,
|
||||
UnmapMemory = 4,
|
||||
Write = 5,
|
||||
Read = 6,
|
||||
Open = 7,
|
||||
Close = 8,
|
||||
|
||||
DebugTrace = 128,
|
||||
}
|
||||
|
||||
impl TryFrom<usize> for SyscallFunction {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: usize) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
1 => Ok(Self::Exit),
|
||||
2 => Ok(Self::Nanosleep),
|
||||
3 => Ok(Self::MapMemory),
|
||||
4 => Ok(Self::UnmapMemory),
|
||||
5 => Ok(Self::Write),
|
||||
6 => Ok(Self::Read),
|
||||
7 => Ok(Self::Open),
|
||||
8 => Ok(Self::Close),
|
||||
|
||||
128 => Ok(Self::DebugTrace),
|
||||
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SyscallFunction> for usize {
|
||||
fn from(value: SyscallFunction) -> Self {
|
||||
match value {
|
||||
SyscallFunction::Exit => 1,
|
||||
SyscallFunction::Nanosleep => 2,
|
||||
SyscallFunction::MapMemory => 3,
|
||||
SyscallFunction::UnmapMemory => 4,
|
||||
SyscallFunction::Write => 5,
|
||||
SyscallFunction::Read => 6,
|
||||
SyscallFunction::Open => 7,
|
||||
SyscallFunction::Close => 8,
|
||||
|
||||
SyscallFunction::DebugTrace => 128,
|
||||
}
|
||||
}
|
||||
}
|
21
src/path.rs
Normal file
21
src/path.rs
Normal file
@ -0,0 +1,21 @@
|
||||
pub const PARENT_NAME: &'static str = "..";
|
||||
pub const SELF_NAME: &'static str = ".";
|
||||
|
||||
pub const SEPARATOR_STR: &'static str = "/";
|
||||
pub const SEPARATOR: char = '/';
|
||||
|
||||
pub fn split_left(path: &str) -> (&str, &str) {
|
||||
if let Some((left, right)) = path.split_once(SEPARATOR) {
|
||||
(left, right.trim_start_matches(SEPARATOR))
|
||||
} else {
|
||||
(path, "")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split_right(path: &str) -> (&str, &str) {
|
||||
if let Some((left, right)) = path.trim_end_matches(SEPARATOR).rsplit_once(SEPARATOR) {
|
||||
(left.trim_end_matches(SEPARATOR), right)
|
||||
} else {
|
||||
("", path)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user