rv64: static libc for riscv64

This commit is contained in:
Mark Poliakov 2025-02-26 17:52:52 +02:00
parent 72633eb339
commit 3a5a693691
7 changed files with 119 additions and 11 deletions

View File

@ -3,6 +3,7 @@ use core::arch::global_asm;
use abi::{arch::SavedFrame, primitive_enum, process::Signal, SyscallFunction};
use kernel_arch::task::TaskFrame;
use libk::{device::external_interrupt_controller, task::thread::Thread};
use libk_mm::PageFaultKind;
use tock_registers::interfaces::ReadWriteable;
use kernel_arch_riscv64::{mem, registers::STVEC};
@ -59,20 +60,39 @@ pub fn init_smode_exceptions() {
// STVEC.modify(STVEC::MODE::Vectored);
}
impl Cause {
fn is_page_fault(&self) -> bool {
matches!(
self,
Self::LoadPageFault
| Self::StorePageFault
| Self::LoadAccessFault
| Self::StoreAccessFault
| Self::InstructionPageFault
| Self::InstructionAccessFault
)
}
}
unsafe fn umode_exception_handler(frame: &mut TrapFrame) {
let thread = Thread::current();
let cause = Cause::try_from(frame.scause).ok();
let (dump, dump_tval) = match cause {
Some(Cause::LoadPageFault)
| Some(Cause::StorePageFault)
| Some(Cause::LoadAccessFault)
| Some(Cause::StoreAccessFault)
| Some(Cause::InstructionPageFault)
| Some(Cause::InstructionAccessFault) => {
thread.raise_signal(Signal::MemoryAccessViolation);
(true, true)
Some(cause) if cause.is_page_fault() => {
let kind = match cause {
Cause::LoadPageFault => PageFaultKind::TranslationFault { write: false },
Cause::StorePageFault => PageFaultKind::TranslationFault { write: true },
Cause::StoreAccessFault => PageFaultKind::WriteFault,
_ => PageFaultKind::Other,
};
if thread.handle_page_fault(frame.stval, kind).is_ok() {
(false, false)
} else {
thread.raise_signal(Signal::MemoryAccessViolation);
(true, true)
}
}
Some(Cause::EcallUmode) => {
let func = frame.an[0];

View File

@ -86,10 +86,17 @@ fn compile_crt0(arch: &str, output_dir: impl AsRef<Path>) {
.arg("-fPIC")
.arg("-c");
if arch == "i686" {
command.arg("-m32");
match arch {
"i686" => {
command.arg("-m32");
}
"riscv64" => {
command.arg("-march=rv64gc");
}
_ => (),
}
command
.arg("-o")
.arg(output_dir.join("crt0.o"))

View File

@ -0,0 +1,6 @@
extern void __ygglibc_entry(const void *, const void *);
extern int main(int, const char **, const char **);
void _start(const void *arg) {
__ygglibc_entry(main, arg);
}

View File

@ -0,0 +1,33 @@
{
"arch": "riscv64",
"os": "none",
"cpu": "generic-rv64",
"llvm-target": "riscv64",
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
"max-atomic-width": 64,
"target-pointer-width": "64",
"features": "+m,+a,+f,+d,+c",
"disable-redzone": true,
"executables": true,
"panic-strategy": "abort",
"dynamic-linking": true,
"relocation-model": "pic",
"position-independent-executables": true,
"crt-static-allows-dylibs": true,
"crt-static-respected": true,
"has-thread-local": true,
"crt-objects-fallback": "false",
"emit-debug-gdb-scripts": false,
"llvm-abiname": "lp64d",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"pre-link-args": {
"ld.lld": [
"--dynamic-linker=/libexec/dyn-loader"
]
}
}

View File

@ -13,4 +13,9 @@ pub mod aarch64;
#[cfg(any(target_arch = "aarch64", rust_analyzer))]
pub use aarch64::__jmp_buf;
#[cfg(any(target_arch = "riscv64", rust_analyzer))]
pub mod riscv64;
#[cfg(any(target_arch = "riscv64", rust_analyzer))]
pub use riscv64::__jmp_buf;
pub type jmp_buf = __jmp_buf;

View File

@ -0,0 +1,37 @@
use core::ffi::c_int;
pub type __jmp_buf = [usize; 8];
// TODO
#[no_mangle]
#[naked]
unsafe extern "C" fn setjmp(buf: *mut __jmp_buf) -> c_int {
core::arch::naked_asm!(
r#"
j .
"#
);
}
#[no_mangle]
#[naked]
unsafe extern "C" fn _setjmp(buf: *mut __jmp_buf) -> c_int {
core::arch::naked_asm!("j .");
}
#[no_mangle]
#[naked]
unsafe extern "C" fn longjmp(buf: *mut __jmp_buf, val: c_int) -> c_int {
core::arch::naked_asm!(
r#"
j .
"#
)
}
#[no_mangle]
#[naked]
unsafe extern "C" fn _longjmp(buf: *mut __jmp_buf, val: c_int) -> c_int {
core::arch::naked_asm!("j .")
}

View File

@ -216,7 +216,7 @@ pub fn install_llvm_compiler(env: &BuildEnv) -> Result<Llvm, Error> {
}
command
.arg("-DLLVM_TARGETS_TO_BUILD=X86;AArch64")
.arg("-DLLVM_TARGETS_TO_BUILD=X86;AArch64;RISCV")
.arg(&format!("-DCMAKE_INSTALL_PREFIX={}", root.display()))
.arg("-GNinja")
.arg("../llvm");