abi: update abi docs
This commit is contained in:
parent
34a5f4f0d8
commit
86f4a3f214
@ -18,7 +18,7 @@ pub struct DebugOptions {
|
||||
impl Default for DebugOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
serial_level: LogLevel::Info,
|
||||
serial_level: LogLevel::Debug, // LogLevel::Info,
|
||||
display_level: LogLevel::Info,
|
||||
disable_program_trace: false,
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Architecture-specific ABI implementation details
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub(crate) mod aarch64;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
|
@ -1,39 +1,61 @@
|
||||
//! Debugging functionality
|
||||
use crate::{arch::SavedFrame, io::RawFd};
|
||||
|
||||
/// Describes a debugger operation
|
||||
#[derive(Debug)]
|
||||
pub enum DebugOperation<'a> {
|
||||
/// Attach to a given process
|
||||
Attach(RawFd),
|
||||
/// Detach from the current process
|
||||
Detach,
|
||||
|
||||
/// Send an interrupt to the debugee
|
||||
Interrupt,
|
||||
/// Continue the debugee, `Continue(true)` represents a "single step"
|
||||
Continue(bool),
|
||||
/// Set a breakpoint at a given address
|
||||
SetBreakpoint(usize),
|
||||
|
||||
/// Read data from the debugee memory
|
||||
ReadMemory {
|
||||
/// Address to read the data from
|
||||
address: usize,
|
||||
/// Buffer to place the result into
|
||||
buffer: &'a mut [u8],
|
||||
},
|
||||
/// Write data to the debugee memory
|
||||
WriteMemory {
|
||||
/// Address to write the data to
|
||||
address: usize,
|
||||
/// Buffer to read the data from
|
||||
buffer: &'a [u8],
|
||||
},
|
||||
}
|
||||
|
||||
// TODO fill this
|
||||
/// Represents a debug event
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Debug)]
|
||||
pub enum DebugFrame {
|
||||
/// The debugee has started
|
||||
Startup {
|
||||
/// The address at which the process image is loaded
|
||||
image_base: usize,
|
||||
/// The address by which the instruction pointer is offset (when ASLR is in effect)
|
||||
ip_offset: usize,
|
||||
/// Current instruction pointer
|
||||
ip: usize,
|
||||
},
|
||||
/// The debugee has completed a single instruction step
|
||||
Step {
|
||||
/// Current process state
|
||||
frame: SavedFrame,
|
||||
},
|
||||
/// The debugee has hit a breakpoint
|
||||
HitBreakpoint {
|
||||
/// Current process state
|
||||
frame: SavedFrame,
|
||||
},
|
||||
// TODO exit status
|
||||
/// The debugee has exited
|
||||
Exited,
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
//! Message channel handling
|
||||
use abi_lib::SyscallRegister;
|
||||
|
||||
pub use crate::generated::ChannelPublisherId;
|
||||
@ -56,5 +57,6 @@ impl SyscallRegister for MessageDestination {
|
||||
}
|
||||
|
||||
impl ChannelPublisherId {
|
||||
/// NULL publisher ID, usually represents the publisher which opened the channel
|
||||
pub const ZERO: Self = Self(0);
|
||||
}
|
||||
|
@ -4,12 +4,17 @@ use crate::generated::ProcessGroupId;
|
||||
|
||||
use super::terminal;
|
||||
|
||||
/// Represents a video device framebuffer
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct Framebuffer {
|
||||
/// Width in pixels
|
||||
pub width: u32,
|
||||
/// Height in pixels
|
||||
pub height: u32,
|
||||
/// Amount of bytes to add to move from one row to the next
|
||||
pub stride: usize,
|
||||
/// Size of the framebuffer in bytes
|
||||
pub size: usize,
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
//! Filesystem management functions and structures
|
||||
|
||||
/// Describes an action performed on a filesystem
|
||||
#[derive(Debug)]
|
||||
pub enum FilesystemControl {
|
||||
/// Flushes the filesystem cache
|
||||
FlushCache,
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! I/O-related definitions
|
||||
|
||||
mod channel;
|
||||
mod device;
|
||||
mod file;
|
||||
@ -21,35 +23,45 @@ pub use terminal::{
|
||||
TerminalOutputOptions, TerminalSize,
|
||||
};
|
||||
|
||||
/// Describes a rename/move operation
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Rename<'a> {
|
||||
/// Where to look the source path at
|
||||
pub source_at: Option<RawFd>,
|
||||
/// Source path
|
||||
pub source: &'a str,
|
||||
/// Where to look the destination path at
|
||||
pub destination_at: Option<RawFd>,
|
||||
/// Destination path
|
||||
pub destination: &'a str,
|
||||
}
|
||||
|
||||
impl UserId {
|
||||
/// Returns the `root` user ID
|
||||
pub const fn root() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
/// Returns `true` if the user ID represents a root user
|
||||
pub const fn is_root(&self) -> bool {
|
||||
self.0 == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl GroupId {
|
||||
/// Returns the `root` group ID
|
||||
pub const fn root() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
/// Returns `true` if the group ID represents a root user
|
||||
pub const fn is_root(&self) -> bool {
|
||||
self.0 == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl FileMode {
|
||||
/// Constructs a file mode from a raw [u32]
|
||||
pub const fn new(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
@ -66,12 +78,16 @@ impl FileMode {
|
||||
}
|
||||
|
||||
impl RawFd {
|
||||
/// Default stdin file descriptor
|
||||
pub const STDIN: Self = Self(0);
|
||||
/// Default stdout file descriptor
|
||||
pub const STDOUT: Self = Self(1);
|
||||
/// Default stderr file descriptor
|
||||
pub const STDERR: Self = Self(2);
|
||||
}
|
||||
|
||||
impl OpenOptions {
|
||||
/// Empty set of open options
|
||||
pub const fn default() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
@ -8,8 +8,7 @@
|
||||
stable_features
|
||||
)]
|
||||
#![feature(trace_macros, const_trait_impl, inline_const_pat, ip_in_core)]
|
||||
// TODO temporary
|
||||
#![allow(missing_docs)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
#[cfg(all(any(feature = "alloc", test), not(feature = "rustc-dep-of-std")))]
|
||||
extern crate alloc;
|
||||
@ -21,13 +20,18 @@ pub(crate) mod macros;
|
||||
pub mod util;
|
||||
|
||||
mod generated {
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::{arch::SavedFrame, process::SpawnOption, util::FixedString};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/generated_types.rs"));
|
||||
}
|
||||
|
||||
pub mod error {
|
||||
//! Error type used by the ABI functions/kernel/runtime
|
||||
|
||||
pub use crate::generated::Error;
|
||||
|
||||
// TODO have syscall-generator implement TryFrom<#repr> for #enum
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ impl ExitCode {
|
||||
matches!(self, Self::Exited(0))
|
||||
}
|
||||
|
||||
/// Returns `Some(...)` if the [ExitCode] represents a process killed by a signal
|
||||
pub fn signal(&self) -> Option<Result<Signal, u32>> {
|
||||
match self {
|
||||
Self::BySignal(sig) => Some(*sig),
|
||||
|
@ -19,6 +19,9 @@ pub use thread::ThreadOption;
|
||||
|
||||
// TODO this is ugly
|
||||
pub mod auxv {
|
||||
#![allow(missing_docs)]
|
||||
//! Auxiliary values passed to the executable
|
||||
|
||||
pub const TLS_MASTER_COPY: u64 = 0x80;
|
||||
pub const TLS_FULL_SIZE: u64 = 0x81;
|
||||
pub const TLS_DATA_SIZE: u64 = 0x82;
|
||||
@ -32,38 +35,44 @@ pub mod auxv {
|
||||
pub const NULL: u64 = 0x00;
|
||||
}
|
||||
|
||||
/// Represents a process/group object to wait on
|
||||
#[derive(Debug)]
|
||||
pub enum ProcessWait {
|
||||
/// Wait for a specific process
|
||||
Process(ProcessId),
|
||||
/// Wait for any process in a group
|
||||
Group(ProcessGroupId),
|
||||
/// Wait for any child process
|
||||
AnyChild,
|
||||
}
|
||||
|
||||
/// Represents a process option being set/retrieved
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug)]
|
||||
pub enum ProcessOption {
|
||||
/// Signal entry point address
|
||||
SignalEntry(usize),
|
||||
/// Current working directory
|
||||
Directory(FixedString<4096>),
|
||||
}
|
||||
|
||||
/// Defines an optional argument for controlling process creation
|
||||
#[derive(Debug)]
|
||||
pub enum SpawnOption {
|
||||
/// Copy a file descriptor into the child process and close it in the parent
|
||||
MoveFile {
|
||||
/// Parent file descriptor
|
||||
source: RawFd,
|
||||
/// Child file descriptor
|
||||
child: RawFd,
|
||||
},
|
||||
/// Copy a file descriptor into the child process
|
||||
CopyFile {
|
||||
/// Parent file descriptor
|
||||
source: RawFd,
|
||||
/// Child file descriptor
|
||||
child: RawFd,
|
||||
},
|
||||
// /// Indicates a new process should inherit a file descriptor from its creator
|
||||
// InheritFile {
|
||||
// /// FD on the creator side
|
||||
// source: RawFd,
|
||||
// /// What FD number should be used in the child
|
||||
// child: RawFd,
|
||||
// },
|
||||
/// The new process should be placed in the specified group
|
||||
SetProcessGroup(ProcessGroupId),
|
||||
/// Gain terminal control for the given FD
|
||||
@ -96,33 +105,43 @@ pub enum ProcessInfoElement {
|
||||
Umask(FileMode),
|
||||
}
|
||||
|
||||
/// Process auxiliary value
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct AuxValue {
|
||||
/// Tag part
|
||||
pub tag: u64,
|
||||
/// Value part
|
||||
pub val: u64,
|
||||
}
|
||||
|
||||
/// An iterator over string-like arguments
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct StringArgIter<'a> {
|
||||
ptr: *const *const u8,
|
||||
_pd: PhantomData<&'a ProgramArgumentInner>,
|
||||
}
|
||||
|
||||
/// An iterator over auxiliary values
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct AuxValueIter<'a> {
|
||||
ptr: *const AuxValue,
|
||||
_pd: PhantomData<&'a ProgramArgumentInner>,
|
||||
}
|
||||
|
||||
/// An argument passed from the kernel/loader to the executable
|
||||
#[repr(C)]
|
||||
pub struct ProgramArgumentInner {
|
||||
/// Argument list
|
||||
pub args: *const *const u8,
|
||||
/// Environment variable list
|
||||
pub envs: *const *const u8,
|
||||
/// Auxiliary value list
|
||||
pub auxv: *const AuxValue,
|
||||
}
|
||||
|
||||
impl ProcessId {
|
||||
/// Zero PID
|
||||
pub const ZERO: Self = Self(0);
|
||||
}
|
||||
|
||||
@ -172,6 +191,7 @@ impl<'a> Iterator for AuxValueIter<'a> {
|
||||
}
|
||||
|
||||
impl ProgramArgumentInner {
|
||||
/// Returns an iterator over the arguments
|
||||
pub fn args(&self) -> impl Iterator<Item = &CStr> {
|
||||
StringArgIter {
|
||||
ptr: self.args,
|
||||
@ -179,6 +199,7 @@ impl ProgramArgumentInner {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over the environment variables
|
||||
pub fn envs(&self) -> impl Iterator<Item = &CStr> {
|
||||
StringArgIter {
|
||||
ptr: self.envs,
|
||||
@ -186,6 +207,7 @@ impl ProgramArgumentInner {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over the auxiliary values
|
||||
pub fn auxv(&self) -> impl Iterator<Item = &AuxValue> {
|
||||
AuxValueIter {
|
||||
ptr: self.auxv,
|
||||
@ -195,10 +217,12 @@ impl ProgramArgumentInner {
|
||||
}
|
||||
|
||||
impl Signal {
|
||||
/// Returns `true` if the signal is delivered in synchronous fashion
|
||||
pub fn is_synchronous(&self) -> bool {
|
||||
matches!(self, Self::MemoryAccessViolation)
|
||||
}
|
||||
|
||||
/// Returns `true` if the signal can be handled by an userspace process
|
||||
pub fn is_handleable(&self) -> bool {
|
||||
!matches!(self, Self::Killed)
|
||||
}
|
||||
|
@ -1,6 +1,12 @@
|
||||
//! Thread data structures
|
||||
|
||||
/// Represents a thread option being set/retrieved
|
||||
#[derive(Debug)]
|
||||
pub enum ThreadOption<'a> {
|
||||
/// Thread-local storage base pointer
|
||||
ThreadPointer(usize),
|
||||
/// Thread signal entry stack base and size
|
||||
SignalStack(usize, usize),
|
||||
/// Thread display name
|
||||
Name(&'a str),
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
//! Time handling structures and functions
|
||||
use core::{
|
||||
ops::{Add, Sub},
|
||||
time::Duration,
|
||||
@ -5,19 +6,26 @@ use core::{
|
||||
|
||||
use abi_lib::SyscallRegister;
|
||||
|
||||
/// Number of nanoseconds in each second
|
||||
pub const NANOSECONDS_IN_SECOND: u64 = 1_000_000_000;
|
||||
/// Number of microseconds in each second
|
||||
pub const MICROSECONDS_IN_SECOND: u64 = 1_000_000;
|
||||
/// Number of milliseconds in each second
|
||||
pub const MILLISECONDS_IN_SECOND: u64 = 1_000;
|
||||
|
||||
/// Represents a point of time as measured by some system clock
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct SystemTime {
|
||||
seconds: u64,
|
||||
nanoseconds: u64,
|
||||
}
|
||||
|
||||
/// Represents a certain clock type
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum ClockType {
|
||||
/// Monotonically increasing clock since some arbitrary point in the past
|
||||
Monotonic,
|
||||
/// "Real-world" clock, subject to jumps
|
||||
RealTime,
|
||||
}
|
||||
|
||||
@ -39,11 +47,19 @@ impl SyscallRegister for ClockType {
|
||||
}
|
||||
|
||||
impl SystemTime {
|
||||
/// Zero time, also represents UNIX Epoch for real-world clocks
|
||||
pub const ZERO: Self = Self {
|
||||
seconds: 0,
|
||||
nanoseconds: 0,
|
||||
};
|
||||
|
||||
/// Constructs a new [SystemTime] from seconds and nanoseconds, without performing
|
||||
/// any adjustments.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must guarantee the `nanoseconds` value does not violate the invariant that
|
||||
/// `nanoseconds` is less than [NANOSECONDS_IN_SECOND].
|
||||
pub unsafe fn new_unchecked(seconds: u64, nanoseconds: u64) -> Self {
|
||||
Self {
|
||||
seconds,
|
||||
@ -51,10 +67,18 @@ impl SystemTime {
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new [SystemTime] from seconds and nanoseconds. If `nanoseconds` contains extra
|
||||
/// full seconds, those are converted to seconds (i.e. the time is "normalized").
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if the conversion result overflows [u64] in the `seconds` field.
|
||||
pub fn new(seconds: u64, nanoseconds: u64) -> Self {
|
||||
Self::new_opt(seconds, nanoseconds).unwrap()
|
||||
}
|
||||
|
||||
/// Constructs a new [SystemTime] from seconds and nanoseconds. This function returns `None` if
|
||||
/// conversion fails. See [SystemTime::new].
|
||||
pub fn new_opt(mut seconds: u64, nanoseconds: u64) -> Option<Self> {
|
||||
seconds = seconds.checked_add(nanoseconds / NANOSECONDS_IN_SECOND)?;
|
||||
Some(Self {
|
||||
@ -63,6 +87,7 @@ impl SystemTime {
|
||||
})
|
||||
}
|
||||
|
||||
/// Constructs a [SystemTime] from seconds part only
|
||||
pub fn from_seconds(seconds: u64) -> Self {
|
||||
Self {
|
||||
seconds,
|
||||
@ -70,21 +95,25 @@ impl SystemTime {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of full milliseconds represented by this structure
|
||||
pub fn as_millis(&self) -> u128 {
|
||||
(self.seconds as u128 * MILLISECONDS_IN_SECOND as u128)
|
||||
+ (self.nanoseconds as u128 / 1000000)
|
||||
}
|
||||
|
||||
/// Returns the number of sub-second nanoseconds
|
||||
#[inline(always)]
|
||||
pub fn subsec_nanos(&self) -> u64 {
|
||||
self.nanoseconds
|
||||
}
|
||||
|
||||
/// Returns the number of full seconds
|
||||
#[inline(always)]
|
||||
pub fn seconds(&self) -> u64 {
|
||||
self.seconds
|
||||
}
|
||||
|
||||
/// Adds a [Duration] to this [SystemTime], returns `None` if the addition overflows
|
||||
pub fn checked_add_duration(&self, other: &Duration) -> Option<Self> {
|
||||
let nanoseconds = self.nanoseconds.checked_add(other.subsec_nanos() as u64)?;
|
||||
let seconds = nanoseconds / NANOSECONDS_IN_SECOND;
|
||||
@ -100,6 +129,7 @@ impl SystemTime {
|
||||
})
|
||||
}
|
||||
|
||||
/// Subtracts a [Duration] from this [SystemTime], returns `None` if the subtraction underflows
|
||||
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Self> {
|
||||
let mut seconds = self.seconds.checked_sub(other.as_secs())?;
|
||||
let nanoseconds = if self.nanoseconds < other.subsec_nanos() as u64 {
|
||||
@ -115,6 +145,8 @@ impl SystemTime {
|
||||
})
|
||||
}
|
||||
|
||||
/// Subtracts two [SystemTime]s, returns `Ok(self - other)` if `self >= other`,
|
||||
/// `Err(other - self)` otherwise.
|
||||
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
|
||||
if self >= other {
|
||||
Ok(self.checked_sub_time(other).unwrap())
|
||||
@ -126,6 +158,7 @@ impl SystemTime {
|
||||
}
|
||||
}
|
||||
|
||||
/// Subtracts two [SystemTime]s, returns `None` if the subtraction underflows
|
||||
pub fn checked_sub_time(&self, other: &SystemTime) -> Option<Duration> {
|
||||
let mut seconds = self.seconds.checked_sub(other.seconds)?;
|
||||
let nanoseconds = if self.nanoseconds < other.nanoseconds {
|
||||
|
@ -8,7 +8,7 @@
|
||||
thread_local
|
||||
)]
|
||||
#![no_std]
|
||||
#![deny(missing_docs)]
|
||||
#![warn(missing_docs)]
|
||||
#![allow(nonstandard_style, clippy::new_without_default)]
|
||||
|
||||
// #[cfg(not(feature = "rustc-dep-of-std"))]
|
||||
|
Loading…
x
Reference in New Issue
Block a user