refactor: implement generated ABI
This commit is contained in:
parent
ca4e50d464
commit
1c0212238a
1055
Cargo.lock
generated
1055
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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 = []
|
||||
|
32
build.rs
32
build.rs
@ -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() {
|
||||
|
@ -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() };
|
||||
|
@ -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" }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -93,6 +93,7 @@ impl Platform for AArch64 {
|
||||
}
|
||||
|
||||
unsafe fn reset(&self) -> ! {
|
||||
loop {}
|
||||
if let Some(reset) = self.reset.try_get() {
|
||||
reset.reset()
|
||||
} else {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
1276
src/syscall/mod.rs
1276
src/syscall/mod.rs
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user