refactor: implement generated ABI

This commit is contained in:
Mark Poliakov 2024-03-12 13:46:24 +02:00
parent ca4e50d464
commit 1c0212238a
12 changed files with 847 additions and 1871 deletions

1055
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,8 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
opt-level = 3
[dependencies]
abi-lib = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
vfs = { path = "lib/vfs" }
device-api = { path = "lib/device-api", features = ["derive"] }
@ -70,6 +72,11 @@ acpi-system = { git = "https://github.com/alnyan/acpi-system.git" }
ygg_driver_nvme = { path = "driver/block/nvme" }
kernel-arch-x86_64 = { path = "arch/x86_64" }
[build-dependencies]
prettyplease = "0.2.15"
yggdrasil-abi-def = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi-def.git" }
abi-generator = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
[features]
default = ["fb_console"]
fb_console = []

View File

@ -1,10 +1,16 @@
use std::{
env,
env, fs,
io::{self, Write},
path::PathBuf,
path::{Path, PathBuf},
process::Command,
};
use abi_generator::{
abi::{ty::TypeWidth, AbiBuilder},
syntax::UnwrapFancy,
TargetEnv,
};
fn build_x86_64() {
const DEFAULT_8086_AS: &str = "nasm";
const AP_BOOTSTRAP_S: &str = "src/arch/x86_64/boot/ap_boot.S";
@ -33,9 +39,31 @@ fn build_x86_64() {
}
}
fn generate_syscall_dispatcher<P: AsRef<Path>>(out_dir: P) {
let abi: AbiBuilder = AbiBuilder::from_string(
yggdrasil_abi_def::ABI_FILE,
TargetEnv {
thin_pointer_width: TypeWidth::U64,
fat_pointer_width: TypeWidth::U128,
},
)
.unwrap_fancy("");
let generated_dispatcher = out_dir.as_ref().join("generated_dispatcher.rs");
let file = prettyplease::unparse(
&abi.emit_syscall_dispatcher("handle_syscall", "impls")
.unwrap_fancy(""),
);
fs::write(generated_dispatcher, file.as_bytes()).unwrap();
}
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
generate_syscall_dispatcher(&out_dir);
println!("cargo:rerun-if-changed=build.rs");
match arch.as_str() {

View File

@ -148,8 +148,8 @@ impl<A: BlockAllocator> MemoryFilesystem<A> {
let node = self.make_path(&root, path, FileType::Directory, false)?;
assert_eq!(node.ty(), hdr.node_kind());
let uid = UserId::from(usize::from(&hdr.uid) as u32);
let gid = GroupId::from(usize::from(&hdr.gid) as u32);
let uid = unsafe { UserId::from_raw(usize::from(&hdr.uid) as u32) };
let gid = unsafe { GroupId::from_raw(usize::from(&hdr.gid) as u32) };
let mode = convert_mode(usize::from(&hdr.mode))?;
let access = unsafe { AccessToken::authorized() };

View File

@ -10,6 +10,7 @@ libk-util = { path = "../libk-util" }
libk-mm = { path = "../libk-mm" }
libk-device = { path = "../libk-device" }
kernel-arch = { path = "../../arch" }
abi-lib = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }

View File

@ -1,5 +1,6 @@
use core::marker::PhantomData;
use abi_lib::SyscallRegister;
use alloc::{
collections::BTreeMap,
string::String,
@ -17,7 +18,7 @@ use libk_util::{
},
};
use yggdrasil_abi::{
error::{Error, SyscallResult},
error::Error,
process::{ExitCode, Signal, ThreadSpawnOptions},
};
@ -247,12 +248,12 @@ impl<PM: ProcessManager<Process = Self>, IO: ProcessIo> ProcessImpl<PM, IO> {
let src_thread = Thread::current();
let src_process = src_thread.process::<PM>();
let rax = src_process
let value = src_process
.fork_inner(frame)
.map(|ProcessId(p)| p as u32)
.into_syscall_result();
.into_syscall_register();
frame.set_return_value(rax as _);
frame.set_return_value(value as _);
}
/// Replaces the process address space with a new one, loaded from the specified program

View File

@ -11,7 +11,7 @@ use aarch64_cpu::{
};
use abi::{
process::{Signal, SignalEntryData},
syscall::SyscallFunction,
SyscallFunction,
};
use kernel_arch::{task::TaskFrame, Architecture, ArchitectureImpl};
use kernel_arch_aarch64::context::ExceptionFrame;

View File

@ -93,6 +93,7 @@ impl Platform for AArch64 {
}
unsafe fn reset(&self) -> ! {
loop {}
if let Some(reset) = self.reset.try_get() {
reset.reset()
} else {

View File

@ -2,7 +2,7 @@
use core::arch::global_asm;
use abi::{process::SignalEntryData, syscall::SyscallFunction};
use abi::{process::SignalEntryData, SyscallFunction};
use kernel_arch::task::TaskFrame;
use kernel_arch_x86_64::{
context::SyscallFrame,
@ -23,6 +23,7 @@ fn syscall_inner(frame: &mut SyscallFrame) {
return;
}
}
// FIXME: Fork is temporarily disabled
if frame.rax == usize::from(SyscallFunction::Fork) as u64 {
unsafe {
ProcessImpl::raw_fork(frame);

View File

@ -25,7 +25,8 @@
inline_const,
maybe_uninit_uninit_array,
const_maybe_uninit_uninit_array,
never_type
never_type,
trace_macros
)]
#![allow(
clippy::new_without_default,

View File

@ -1,26 +1,19 @@
use abi::io::RawFd;
use libk_thread::{
mem::{validate_user_region, ForeignPointer},
thread::Thread,
};
use libk_thread::{mem::ForeignPointer, thread::Thread};
use yggdrasil_abi::error::Error;
// XXX
pub(super) fn arg_buffer_ref<'a>(base: usize, len: usize) -> Result<&'a [u8], Error> {
pub(super) fn ref_const<'a, T: Sized>(addr: usize) -> Result<&'a T, Error> {
let proc = Thread::current();
validate_user_region(proc.address_space(), base, len, false)?;
Ok(unsafe { core::slice::from_raw_parts(base as *const u8, len) })
let ptr = addr as *const T;
unsafe { ptr.validate_user_ptr(proc.address_space()) }
}
pub(super) fn ref_mut<'a, T: Sized>(addr: usize) -> Result<&'a mut T, Error> {
let proc = Thread::current();
let ptr = addr as *mut T;
unsafe { ptr.validate_user_mut(proc.address_space()) }
}
pub(super) fn arg_buffer_mut<'a>(base: usize, len: usize) -> Result<&'a mut [u8], Error> {
let proc = Thread::current();
validate_user_region(proc.address_space(), base, len, true)?;
Ok(unsafe { core::slice::from_raw_parts_mut(base as *mut u8, len) })
}
pub(super) fn arg_user_str<'a>(base: usize, len: usize) -> Result<&'a str, Error> {
let slice = arg_buffer_ref(base, len)?;
pub(super) fn str_ref<'a>(base: usize, len: usize) -> Result<&'a str, Error> {
let slice = slice_ref(base, len)?;
if slice.contains(&0) {
warnln!("User-supplied string contains NUL characters");
return Err(Error::InvalidArgument);
@ -28,31 +21,13 @@ pub(super) fn arg_user_str<'a>(base: usize, len: usize) -> Result<&'a str, Error
Ok(core::str::from_utf8(slice).unwrap())
}
pub(super) fn arg_user_ref<'a, T: Sized>(addr: usize) -> Result<&'a T, Error> {
pub(super) fn slice_ref<'a, T: Sized>(base: usize, count: usize) -> Result<&'a [T], Error> {
let proc = Thread::current();
let ptr = addr as *const T;
unsafe { ptr.validate_user_ptr(proc.address_space()) }
let ptr = base as *const T;
unsafe { ptr.validate_user_slice(count, proc.address_space()) }
}
pub(super) fn arg_user_mut<'a, T: Sized>(addr: usize) -> Result<&'a mut T, Error> {
let proc = Thread::current();
let ptr = addr as *mut T;
unsafe { ptr.validate_user_mut(proc.address_space()) }
}
pub(super) fn arg_user_slice_mut<'a, T: Sized>(
base: usize,
count: usize,
) -> Result<&'a mut [T], Error> {
pub(super) fn slice_mut<'a, T: Sized>(base: usize, count: usize) -> Result<&'a mut [T], Error> {
let proc = Thread::current();
let ptr = base as *mut T;
unsafe { ptr.validate_user_slice_mut(count, proc.address_space()) }
}
pub(super) fn arg_option_fd(raw: u32) -> Option<RawFd> {
if raw == u32::MAX {
None
} else {
Some(RawFd(raw))
}
}

File diff suppressed because it is too large Load Diff