1#![no_std]
27#![feature(linkage)]
28
29#[macro_use]
31pub mod error;
32pub use error::*;
33
34#[doc(hidden)]
37pub const MOTO_SYS_CUSTOM_USERSPACE_REGION_START: u64 = (1_u64 << 45) + (1_u64 << 40);
38#[doc(hidden)]
39const MOTO_SYS_CUSTOM_USERSPACE_REGION_END: u64 =
40 MOTO_SYS_CUSTOM_USERSPACE_REGION_START + (1_u64 << 40);
41#[doc(hidden)]
42const MOTO_SYS_PAGE_SIZE_SMALL: u64 = 4096;
43
44#[doc(hidden)]
46pub const RT_VDSO_START: u64 = MOTO_SYS_CUSTOM_USERSPACE_REGION_END - (1_u64 << 32); #[doc(hidden)]
52pub const RT_VDSO_BYTES_ADDR: u64 = RT_VDSO_START - (1_u64 << 32); #[doc(hidden)]
56pub const RT_VDSO_VTABLE_VADDR: u64 = RT_VDSO_START - MOTO_SYS_PAGE_SIZE_SMALL;
57
58#[cfg(any(feature = "libc", feature = "rustc-dep-of-std"))]
61pub mod libc;
62
63#[cfg(not(feature = "base"))]
64pub mod alloc;
65#[cfg(not(feature = "base"))]
66pub mod fs;
67#[cfg(not(feature = "base"))]
68pub mod futex;
69#[cfg(not(feature = "base"))]
70pub mod mutex;
71#[cfg(not(feature = "base"))]
72pub mod net;
73
74#[cfg(not(feature = "base"))]
75#[allow(nonstandard_style)]
76pub mod netc;
77
78#[cfg(not(feature = "base"))]
79pub mod poll;
80#[cfg(not(feature = "base"))]
81pub mod process;
82#[cfg(not(feature = "base"))]
83pub mod thread;
84#[cfg(not(feature = "base"))]
85pub mod time;
86#[cfg(not(feature = "base"))]
87pub mod tls;
88
89pub mod spinlock;
90
91#[cfg(not(feature = "base"))]
92pub use futex::*;
93
94#[cfg(not(feature = "base"))]
95use core::sync::atomic::{AtomicU64, Ordering};
96
97#[cfg(not(feature = "base"))]
101pub type RtFd = i32;
102#[cfg(not(feature = "base"))]
104pub const FD_STDIN: RtFd = 0;
105#[cfg(not(feature = "base"))]
106pub const FD_STDOUT: RtFd = 1;
107#[cfg(not(feature = "base"))]
108pub const FD_STDERR: RtFd = 2;
109
110#[cfg(not(feature = "base"))]
111pub const RT_VERSION: u64 = 10;
112
113#[cfg(not(feature = "base"))]
120#[doc(hidden)]
121#[repr(C)]
122pub struct RtVdsoVtable {
123 pub vdso_entry: AtomicU64,
127
128 pub vdso_bytes_sz: AtomicU64,
131
132 pub log_to_kernel: AtomicU64,
134 pub log_backtrace: AtomicU64,
135 pub fill_random_bytes: AtomicU64,
136 pub num_cpus: AtomicU64,
137 pub internal_helper: AtomicU64,
138
139 pub alloc: AtomicU64,
141 pub alloc_zeroed: AtomicU64,
142 pub realloc: AtomicU64,
143 pub dealloc: AtomicU64,
144 pub release_handle: AtomicU64,
145
146 pub time_instant_now: AtomicU64,
148 pub time_ticks_to_nanos: AtomicU64,
149 pub time_nanos_to_ticks: AtomicU64,
150 pub time_ticks_in_sec: AtomicU64,
151 pub time_abs_ticks_to_nanos: AtomicU64,
152
153 pub futex_wait: AtomicU64,
155 pub futex_wake: AtomicU64,
156 pub futex_wake_all: AtomicU64,
157
158 pub proc_args: AtomicU64,
160 pub proc_get_full_env: AtomicU64,
161 pub proc_getenv: AtomicU64,
162 pub proc_setenv: AtomicU64,
163 pub proc_spawn: AtomicU64,
164 pub proc_kill: AtomicU64,
165 pub proc_wait: AtomicU64,
166 pub proc_status: AtomicU64,
167 pub proc_exit: AtomicU64,
168
169 pub tls_create: AtomicU64,
171 pub tls_set: AtomicU64,
172 pub tls_get: AtomicU64,
173 pub tls_destroy: AtomicU64,
174
175 pub thread_spawn: AtomicU64,
177 pub thread_sleep: AtomicU64,
178 pub thread_yield: AtomicU64,
179 pub thread_set_name: AtomicU64,
180 pub thread_join: AtomicU64,
181
182 pub fs_is_terminal: AtomicU64,
184 pub fs_open: AtomicU64,
185 pub fs_close: AtomicU64,
186 pub fs_get_file_attr: AtomicU64,
187 pub fs_fsync: AtomicU64,
188 pub fs_datasync: AtomicU64,
189 pub fs_truncate: AtomicU64,
190 pub fs_read: AtomicU64,
191 pub fs_read_vectored: AtomicU64,
192 pub fs_write: AtomicU64,
193 pub fs_write_vectored: AtomicU64,
194 pub fs_flush: AtomicU64,
195 pub fs_seek: AtomicU64,
196 pub fs_mkdir: AtomicU64,
197 pub fs_unlink: AtomicU64,
198 pub fs_rename: AtomicU64,
199 pub fs_rmdir: AtomicU64,
200 pub fs_rmdir_all: AtomicU64,
201 pub fs_set_perm: AtomicU64,
202 pub fs_set_file_perm: AtomicU64,
203 pub fs_stat: AtomicU64,
204 pub fs_canonicalize: AtomicU64,
205 pub fs_copy: AtomicU64,
206 pub fs_opendir: AtomicU64,
207 pub fs_closedir: AtomicU64,
208 pub fs_readdir: AtomicU64,
209 pub fs_getcwd: AtomicU64,
210 pub fs_chdir: AtomicU64,
211 pub fs_duplicate: AtomicU64,
212
213 pub dns_lookup: AtomicU64,
215 pub net_bind: AtomicU64,
216 pub net_listen: AtomicU64,
217 pub net_accept: AtomicU64,
218 pub net_tcp_connect: AtomicU64,
219 pub net_udp_connect: AtomicU64,
220 pub net_socket_addr: AtomicU64,
221 pub net_peer_addr: AtomicU64,
222 pub net_setsockopt: AtomicU64,
223 pub net_getsockopt: AtomicU64,
224 pub net_peek: AtomicU64,
225 pub net_udp_recv_from: AtomicU64,
226 pub net_udp_peek_from: AtomicU64,
227 pub net_udp_send_to: AtomicU64,
228
229 pub poll_new: AtomicU64,
231 pub poll_add: AtomicU64,
232 pub poll_set: AtomicU64,
233 pub poll_del: AtomicU64,
234 pub poll_wait: AtomicU64,
235 pub poll_wake: AtomicU64,
236}
237
238#[cfg(not(feature = "base"))]
239const _SIZE_CHECK: () = assert!(size_of::<RtVdsoVtable>() <= 4096);
240
241#[cfg(not(feature = "base"))]
242#[doc(hidden)]
243impl RtVdsoVtable {
244 pub fn get() -> &'static Self {
245 unsafe {
247 (RT_VDSO_VTABLE_VADDR as usize as *const RtVdsoVtable)
248 .as_ref()
249 .unwrap_unchecked()
250 }
251 }
252}
253
254#[cfg(not(feature = "base"))]
255#[doc(hidden)]
256pub fn init() {
257 assert_ne!(0, RtVdsoVtable::get().vdso_entry.load(Ordering::Acquire));
258 let vdso_entry: extern "C" fn(u64) = unsafe {
259 core::mem::transmute(
260 RtVdsoVtable::get().vdso_entry.load(Ordering::Relaxed) as usize as *const (),
261 )
262 };
263
264 vdso_entry(RT_VERSION)
265}
266
267#[cfg(not(feature = "base"))]
268#[linkage = "weak"]
269#[no_mangle]
270pub extern "C" fn moturus_runtime_start() {
271 init();
276}
277
278#[cfg(not(feature = "base"))]
279#[doc(hidden)]
280pub fn start() {
281 moturus_runtime_start();
284}
285
286#[cfg(not(feature = "base"))]
287pub fn fill_random_bytes(bytes: &mut [u8]) {
288 let vdso_fill_random_bytes: extern "C" fn(*mut u8, usize) = unsafe {
289 core::mem::transmute(
290 RtVdsoVtable::get()
291 .fill_random_bytes
292 .load(Ordering::Relaxed) as usize as *const (),
293 )
294 };
295
296 vdso_fill_random_bytes(bytes.as_mut_ptr(), bytes.len())
297}
298
299#[cfg(not(feature = "base"))]
301pub fn num_cpus() -> usize {
302 let vdso_num_cpus: extern "C" fn() -> usize = unsafe {
307 core::mem::transmute(
308 RtVdsoVtable::get().num_cpus.load(Ordering::Relaxed) as usize as *const (),
309 )
310 };
311
312 vdso_num_cpus()
313}
314
315#[cfg(not(feature = "base"))]
316#[doc(hidden)]
317pub fn internal_helper(a0: u64, a1: u64, a2: u64, a3: u64, a4: u64, a5: u64) -> u64 {
318 let vdso_internal_helper: extern "C" fn(u64, u64, u64, u64, u64, u64) -> u64 = unsafe {
324 core::mem::transmute(
325 RtVdsoVtable::get().internal_helper.load(Ordering::Relaxed) as usize as *const (),
326 )
327 };
328
329 vdso_internal_helper(a0, a1, a2, a3, a4, a5)
330}
331
332#[cfg(not(test))]
333#[cfg(feature = "rustc-dep-of-std")]
334#[panic_handler]
335fn _panic(info: &core::panic::PanicInfo<'_>) -> ! {
336 error::log_panic(info);
337 crate::thread::sleep_until(crate::time::Instant::now() + core::time::Duration::from_micros(100));
339 process::exit(-1)
340}