feat: add Rust userspace support; fix TLS layout for p_align < 16; kill whole process on sibling-thread faults
This commit is contained in:
1 parent
a81298fb24
commit
f8b8f9610f
31 files changed
+1076
-38
No files matched your search
@@ -0,0 +1,65 @@
|
||||
// Generate syscall numbers and status codes from the C++ headers so Rust
|
||||
// never becomes another hand-maintained copy of the syscall table.
|
||||
//
|
||||
// programs/include/Api/Syscall.hpp -> pub const SYS_*: u64
|
||||
// kernel/src/Common/StatusCodes.hpp -> pub enum Status (positive values,
|
||||
// matching montauk/statuscodes.h)
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let manifest = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let repo = manifest.join("../../..");
|
||||
let syscall_hpp = repo.join("programs/include/Api/Syscall.hpp");
|
||||
let status_hpp = repo.join("kernel/src/Common/StatusCodes.hpp");
|
||||
println!("cargo:rerun-if-changed={}", syscall_hpp.display());
|
||||
println!("cargo:rerun-if-changed={}", status_hpp.display());
|
||||
|
||||
let mut out = String::from("// @generated by montauk-rt/build.rs - do not edit.\n\n");
|
||||
|
||||
// static constexpr uint64_t SYS_NAME = 123; (decimal literals only)
|
||||
let syscalls = fs::read_to_string(&syscall_hpp).expect("read Syscall.hpp");
|
||||
let mut count = 0;
|
||||
for line in syscalls.lines() {
|
||||
let line = line.trim();
|
||||
let Some(rest) = line.strip_prefix("static constexpr uint64_t SYS_") else { continue };
|
||||
let Some((name, value)) = rest.split_once('=') else { continue };
|
||||
let value = value.split(';').next().unwrap_or("").trim();
|
||||
if value.is_empty() || !value.bytes().all(|b| b.is_ascii_digit()) {
|
||||
continue;
|
||||
}
|
||||
out.push_str(&format!("pub const SYS_{}: u64 = {};\n", name.trim(), value));
|
||||
count += 1;
|
||||
}
|
||||
assert!(count > 100, "parsed only {count} syscalls from {}", syscall_hpp.display());
|
||||
|
||||
// enum StatusCodes { Success = 0, GenericFailure = -1, ... };
|
||||
let status = fs::read_to_string(&status_hpp).expect("read StatusCodes.hpp");
|
||||
let body = status
|
||||
.split_once("enum StatusCodes")
|
||||
.and_then(|(_, rest)| rest.split_once('{'))
|
||||
.and_then(|(_, rest)| rest.split_once('}'))
|
||||
.map(|(body, _)| body)
|
||||
.expect("enum StatusCodes not found");
|
||||
out.push_str("\n/// Kernel status codes, stored positive like montauk/statuscodes.h.\n");
|
||||
out.push_str("/// The kernel returns them negated; see [`Status::from_result`].\n");
|
||||
out.push_str("#[derive(Clone, Copy, Debug, PartialEq, Eq)]\n#[repr(i32)]\npub enum Status {\n");
|
||||
let mut variants = Vec::new();
|
||||
for entry in body.split(',') {
|
||||
let entry = entry.split("//").next().unwrap_or("").trim();
|
||||
let Some((name, value)) = entry.split_once('=') else { continue };
|
||||
let value: i32 = value.trim().parse().expect("status value");
|
||||
out.push_str(&format!(" {} = {},\n", name.trim(), -value));
|
||||
variants.push((name.trim().to_string(), -value));
|
||||
}
|
||||
out.push_str("}\n\nimpl Status {\n pub const fn from_code(code: i32) -> Status {\n match code {\n");
|
||||
for (name, value) in &variants {
|
||||
out.push_str(&format!(" {} => Status::{},\n", value, name));
|
||||
}
|
||||
out.push_str(" _ => Status::GenericFailure,\n }\n }\n}\n");
|
||||
|
||||
let dest = PathBuf::from(env::var("OUT_DIR").unwrap()).join("abi.rs");
|
||||
fs::write(dest, out).expect("write abi.rs");
|
||||
}
|
||||
Reference in new issue
Block a user