1#![allow(unused_variables)]
2#![allow(non_snake_case)]
3#![allow(improper_ctypes_definitions)]
4
5macro_rules! check_ffi_type {
9 ($f1:ident) => {
10 paste::paste! {
11 #[allow(dead_code, unused_variables, unused_assignments)]
12 fn [<__tc_ffi_ $f1>]() {
13 let mut x: unsafe extern "C-unwind" fn() -> _ = $f1;
14 x = twizzler_rt_abi::bindings::$f1;
15 }
16 }
17 };
18 ($f1:ident, _) => {
19 paste::paste! {
20 #[allow(dead_code, unused_variables, unused_assignments)]
21 fn [<__tc_ffi_ $f1>]() {
22 let mut x: unsafe extern "C-unwind" fn(_) -> _ = $f1;
23 x = twizzler_rt_abi::bindings::$f1;
24 }
25 }
26 };
27 ($f1:ident, _, _) => {
28 paste::paste! {
29 #[allow(dead_code, unused_variables, unused_assignments)]
30 fn [<__tc_ffi_ $f1>]() {
31 let mut x: unsafe extern "C-unwind" fn(_, _) -> _ = $f1;
32 x = twizzler_rt_abi::bindings::$f1;
33 }
34 }
35 };
36 ($f1:ident, _, _, _) => {
37 paste::paste! {
38 #[allow(dead_code, unused_variables, unused_assignments)]
39 fn [<__tc_ffi_ $f1>]() {
40 let mut x: unsafe extern "C-unwind" fn(_, _, _) -> _ = $f1;
41 x = twizzler_rt_abi::bindings::$f1;
42 }
43 }
44 };
45 ($f1:ident, _, _, _, _) => {
46 paste::paste! {
47 #[allow(dead_code, unused_variables, unused_assignments)]
48 fn [<__tc_ffi_ $f1>]() {
49 let mut x: unsafe extern "C-unwind" fn(_, _, _, _) -> _ = $f1;
50 x = twizzler_rt_abi::bindings::$f1;
51 }
52 }
53 };
54 ($f1:ident, _, _, _, _, _) => {
55 paste::paste! {
56 #[allow(dead_code, unused_variables, unused_assignments)]
57 fn [<__tc_ffi_ $f1>]() {
58 let mut x: unsafe extern "C-unwind" fn(_, _, _, _, _) -> _ = $f1;
59 x = twizzler_rt_abi::bindings::$f1;
60 }
61 }
62 };
63 ($f1:ident, _, _, _, _, _, _) => {
64 paste::paste! {
65 #[allow(dead_code, unused_variables, unused_assignments)]
66 fn [<__tc_ffi_ $f1>]() {
67 let mut x: unsafe extern "C-unwind" fn(_, _, _, _, _, _) -> _ = $f1;
68 x = twizzler_rt_abi::bindings::$f1;
69 }
70 }
71 };
72}
73
74use std::ffi::{c_void, CStr};
75
76use tracing::warn;
77use twizzler_abi::object::ObjID;
78use twizzler_rt_abi::bindings::{endpoint, io_ctx, option_exit_code, twz_error, u32_result};
80use twizzler_rt_abi::error::{ArgumentError, RawTwzError, TwzError};
81
82use crate::{runtime::OUR_RUNTIME, set_upcall_handler};
83
84#[no_mangle]
85pub unsafe extern "C-unwind" fn twz_rt_abort() {
86 OUR_RUNTIME.abort();
87}
88check_ffi_type!(twz_rt_abort);
89
90#[no_mangle]
91pub unsafe extern "C-unwind" fn twz_rt_exit(code: i32) {
92 OUR_RUNTIME.exit(code);
93}
94check_ffi_type!(twz_rt_exit, _);
95
96#[no_mangle]
97pub unsafe extern "C-unwind" fn twz_rt_pre_main_hook() -> option_exit_code {
98 match OUR_RUNTIME.pre_main_hook() {
99 Some(ec) => option_exit_code {
100 is_some: 1,
101 value: ec,
102 },
103 None => option_exit_code {
104 is_some: 0,
105 value: 0,
106 },
107 }
108}
109check_ffi_type!(twz_rt_pre_main_hook);
110
111#[no_mangle]
112pub unsafe extern "C-unwind" fn twz_rt_post_main_hook() {
113 OUR_RUNTIME.post_main_hook()
114}
115check_ffi_type!(twz_rt_post_main_hook);
116
117#[no_mangle]
118pub unsafe extern "C-unwind" fn twz_rt_runtime_entry(
119 arg: *const twizzler_rt_abi::bindings::runtime_info,
120 std_entry: core::option::Option<
121 unsafe extern "C-unwind" fn(
122 arg1: twizzler_rt_abi::bindings::basic_aux,
123 ) -> twizzler_rt_abi::bindings::basic_return,
124 >,
125) {
126 OUR_RUNTIME.runtime_entry(arg, std_entry.unwrap_unchecked())
127}
128check_ffi_type!(twz_rt_runtime_entry, _, _);
129
130#[no_mangle]
131pub unsafe extern "C-unwind" fn twz_rt_cross_compartment_entry() -> bool {
132 OUR_RUNTIME.cross_compartment_entry().is_ok()
133}
134check_ffi_type!(twz_rt_cross_compartment_entry);
135
136#[no_mangle]
137pub unsafe extern "C-unwind" fn twz_rt_set_upcall_handler(
138 handler: Option<unsafe extern "C-unwind" fn(frame: *mut c_void, data: *const c_void)>,
139) {
140 let _ = set_upcall_handler(handler);
141}
142check_ffi_type!(twz_rt_set_upcall_handler, _);
143
144use twizzler_rt_abi::bindings::{alloc_flags, ZERO_MEMORY};
147#[no_mangle]
148pub unsafe extern "C-unwind" fn twz_rt_malloc(
149 sz: usize,
150 align: usize,
151 flags: alloc_flags,
152) -> *mut ::core::ffi::c_void {
153 let Ok(layout) = core::alloc::Layout::from_size_align(sz, align) else {
154 return core::ptr::null_mut();
155 };
156 if flags & ZERO_MEMORY != 0 {
157 OUR_RUNTIME.default_allocator().alloc_zeroed(layout).cast()
158 } else {
159 OUR_RUNTIME.default_allocator().alloc(layout).cast()
160 }
161}
162check_ffi_type!(twz_rt_malloc, _, _, _);
163
164#[no_mangle]
165pub unsafe extern "C-unwind" fn twz_rt_dealloc(
166 ptr: *mut ::core::ffi::c_void,
167 sz: usize,
168 align: usize,
169 flags: twizzler_rt_abi::bindings::alloc_flags,
170) {
171 let Ok(layout) = core::alloc::Layout::from_size_align(sz, align) else {
172 return;
173 };
174 if flags & ZERO_MEMORY != 0 {
175 let slice = unsafe { core::slice::from_raw_parts_mut(ptr.cast::<u8>(), sz) };
176 slice.fill(0);
177 core::hint::black_box(slice);
178 }
179 OUR_RUNTIME.default_allocator().dealloc(ptr.cast(), layout);
180}
181check_ffi_type!(twz_rt_dealloc, _, _, _, _);
182
183#[no_mangle]
184pub unsafe extern "C-unwind" fn twz_rt_realloc(
185 ptr: *mut ::core::ffi::c_void,
186 sz: usize,
187 align: usize,
188 new_size: usize,
189 flags: twizzler_rt_abi::bindings::alloc_flags,
190) -> *mut ::core::ffi::c_void {
191 let Ok(layout) = core::alloc::Layout::from_size_align(sz, align) else {
192 return core::ptr::null_mut();
193 };
194 if flags & ZERO_MEMORY != 0 {
195 todo!()
196 }
197 OUR_RUNTIME
198 .default_allocator()
199 .realloc(ptr.cast(), layout, new_size)
200 .cast()
201}
202check_ffi_type!(twz_rt_realloc, _, _, _, _, _);
203
204#[no_mangle]
207pub unsafe extern "C-unwind" fn twz_rt_futex_wait(
208 ptr: *mut u32,
209 expected: twizzler_rt_abi::bindings::futex_word,
210 timeout: twizzler_rt_abi::bindings::option_duration,
211) -> bool {
212 if timeout.is_some != 0 {
213 OUR_RUNTIME.futex_wait(&*ptr.cast(), expected, Some(timeout.dur.into()))
214 } else {
215 OUR_RUNTIME.futex_wait(&*ptr.cast(), expected, None)
216 }
217}
218check_ffi_type!(twz_rt_futex_wait, _, _, _);
219
220#[no_mangle]
221pub unsafe extern "C-unwind" fn twz_rt_futex_wake(ptr: *mut u32, max: i64) -> bool {
222 OUR_RUNTIME.futex_wake(&*ptr.cast(), max as usize)
223}
224check_ffi_type!(twz_rt_futex_wake, _, _);
225
226#[no_mangle]
227pub unsafe extern "C-unwind" fn twz_rt_yield_now() {
228 OUR_RUNTIME.yield_now();
229}
230check_ffi_type!(twz_rt_yield_now);
231
232#[no_mangle]
233pub unsafe extern "C-unwind" fn twz_rt_set_name(name: *const ::core::ffi::c_char) {
234 unsafe {
235 OUR_RUNTIME.set_name(core::ffi::CStr::from_ptr(name));
236 }
237}
238check_ffi_type!(twz_rt_set_name, _);
239
240#[no_mangle]
241pub unsafe extern "C-unwind" fn twz_rt_sleep(dur: twizzler_rt_abi::bindings::duration) {
242 OUR_RUNTIME.sleep(dur.into());
243}
244check_ffi_type!(twz_rt_sleep, _);
245
246#[no_mangle]
247pub unsafe extern "C-unwind" fn twz_rt_tls_get_addr(
248 index: *mut twizzler_rt_abi::bindings::tls_index,
249) -> *mut ::core::ffi::c_void {
250 OUR_RUNTIME
251 .tls_get_addr(unsafe { &*index })
252 .unwrap_or(core::ptr::null_mut())
253 .cast()
254}
255check_ffi_type!(twz_rt_tls_get_addr, _);
256
257#[no_mangle]
259pub unsafe extern "C-unwind" fn __tls_get_addr(
260 index: *mut twizzler_rt_abi::bindings::tls_index,
261) -> *mut ::core::ffi::c_void {
262 twz_rt_tls_get_addr(index)
263}
264
265#[no_mangle]
266pub unsafe extern "C-unwind" fn twz_rt_spawn_thread(
267 args: twizzler_rt_abi::bindings::spawn_args,
268) -> twizzler_rt_abi::bindings::spawn_result {
269 OUR_RUNTIME.spawn(args).into()
270}
271check_ffi_type!(twz_rt_spawn_thread, _);
272#[no_mangle]
273pub unsafe extern "C-unwind" fn twz_rt_join_thread(
274 id: twizzler_rt_abi::bindings::thread_id,
275 timeout: twizzler_rt_abi::bindings::option_duration,
276) -> twizzler_rt_abi::bindings::twz_error {
277 match if timeout.is_some != 0 {
278 OUR_RUNTIME.join(id, Some(timeout.dur.into()))
279 } else {
280 OUR_RUNTIME.join(id, None)
281 } {
282 Ok(_) => RawTwzError::success().raw(),
283 Err(e) => e.raw(),
284 }
285}
286check_ffi_type!(twz_rt_join_thread, _, _);
287
288use twizzler_rt_abi::bindings::{descriptor, open_anon_kind, open_info, open_result};
291#[no_mangle]
292pub unsafe extern "C-unwind" fn twz_rt_fd_open_anon(
293 kind: open_anon_kind,
294 flags: u32,
295 bind_info: *mut c_void,
296 bind_info_len: usize,
297) -> open_result {
298 let Ok(kind) = kind.try_into() else {
299 return Err(ArgumentError::InvalidArgument.into()).into();
300 };
301 OUR_RUNTIME
302 .open_anon(kind, flags.into(), bind_info, bind_info_len)
303 .into()
304}
305check_ffi_type!(twz_rt_fd_open_anon, _, _, _, _);
306
307#[no_mangle]
308pub unsafe extern "C-unwind" fn twz_rt_fd_open(info: open_info) -> open_result {
309 let name = unsafe { core::slice::from_raw_parts(info.name.cast(), info.len) };
310 let name = core::str::from_utf8(name)
311 .map_err(|_| twizzler_rt_abi::error::ArgumentError::InvalidArgument);
312 match name {
313 Ok(name) => OUR_RUNTIME
314 .open(name, info.create.into(), info.flags.into())
315 .into(),
316 Err(e) => open_result {
317 err: TwzError::from(e).raw(),
318 fd: 0,
319 },
320 }
321}
322check_ffi_type!(twz_rt_fd_open, _);
323
324use core::ffi::c_char;
325
326#[no_mangle]
327pub unsafe extern "C-unwind" fn twz_rt_fd_remove(name: *const c_char, len: usize) -> twz_error {
328 let name = unsafe { core::slice::from_raw_parts(name.cast(), len) };
329 let name = core::str::from_utf8(name).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
330 match name {
331 Ok(name) => match OUR_RUNTIME.remove(name) {
332 Ok(_) => RawTwzError::success().raw(),
333 Err(e) => e.raw(),
334 },
335 Err(e) => e,
336 }
337}
338check_ffi_type!(twz_rt_fd_remove, _, _);
339
340#[no_mangle]
341pub unsafe extern "C-unwind" fn twz_rt_fd_close(fd: descriptor) {
342 OUR_RUNTIME.close(fd);
343}
344check_ffi_type!(twz_rt_fd_close, _);
345
346#[no_mangle]
347pub unsafe extern "C-unwind" fn twz_rt_fd_get_info(
348 fd: descriptor,
349 fd_info: *mut twizzler_rt_abi::bindings::fd_info,
350) -> bool {
351 match OUR_RUNTIME.fd_get_info(fd) {
352 Some(info) => {
353 fd_info.write(info);
354 true
355 }
356 None => false,
357 }
358}
359check_ffi_type!(twz_rt_fd_get_info, _, _);
360
361#[no_mangle]
362pub unsafe extern "C-unwind" fn twz_rt_fd_cmd(
363 fd: descriptor,
364 cmd: twizzler_rt_abi::bindings::fd_cmd,
365 arg: *mut ::core::ffi::c_void,
366 ret: *mut ::core::ffi::c_void,
367) -> twz_error {
368 match OUR_RUNTIME.fd_cmd(fd, cmd, arg.cast(), ret.cast()) {
369 Ok(_) => RawTwzError::success().raw(),
370 Err(e) => e.raw(),
371 }
372}
373check_ffi_type!(twz_rt_fd_cmd, _, _, _, _);
374
375#[no_mangle]
376pub unsafe extern "C-unwind" fn twz_rt_fd_enumerate_names(
377 fd: descriptor,
378 buf: *mut twizzler_rt_abi::bindings::name_entry,
379 len: ::core::ffi::c_size_t,
380 off: ::core::ffi::c_size_t,
381) -> io_result {
382 OUR_RUNTIME
383 .fd_enumerate(
384 fd,
385 unsafe { core::slice::from_raw_parts_mut(buf, len) },
386 off,
387 )
388 .into()
389}
390check_ffi_type!(twz_rt_fd_enumerate_names, _, _, _, _);
391
392#[no_mangle]
393pub unsafe extern "C-unwind" fn twz_rt_fd_mkns(name: *const c_char, len: usize) -> twz_error {
394 let name = unsafe { core::slice::from_raw_parts(name.cast(), len) };
395 let name = core::str::from_utf8(name).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
396 match name {
397 Ok(name) => match OUR_RUNTIME.mkns(name) {
398 Ok(_) => RawTwzError::success().raw(),
399 Err(e) => e.raw(),
400 },
401 Err(e) => e,
402 }
403}
404check_ffi_type!(twz_rt_fd_mkns, _, _);
405
406#[no_mangle]
407pub unsafe extern "C-unwind" fn twz_rt_fd_symlink(
408 name: *const c_char,
409 len: usize,
410 target: *const c_char,
411 target_len: usize,
412) -> twz_error {
413 let name = unsafe { core::slice::from_raw_parts(name.cast(), len) };
414 let name = core::str::from_utf8(name).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
415 let target = unsafe { core::slice::from_raw_parts(target.cast(), target_len) };
416 let Ok(target) = core::str::from_utf8(target).map_err(|_| TwzError::INVALID_ARGUMENT.raw())
417 else {
418 return TwzError::INVALID_ARGUMENT.into();
419 };
420 match name {
421 Ok(name) => match OUR_RUNTIME.symlink(name, target) {
422 Ok(_) => RawTwzError::success().raw(),
423 Err(e) => e.raw(),
424 },
425 Err(e) => e,
426 }
427}
428check_ffi_type!(twz_rt_fd_symlink, _, _, _, _);
429
430#[no_mangle]
431pub unsafe extern "C-unwind" fn twz_rt_fd_readlink(
432 name: *const c_char,
433 len: usize,
434 target: *mut c_char,
435 target_len: usize,
436 read_len: *mut u64,
437) -> twz_error {
438 let name = unsafe { core::slice::from_raw_parts(name.cast(), len) };
439 let name = core::str::from_utf8(name).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
440 let target = unsafe { core::slice::from_raw_parts_mut(target.cast(), target_len) };
441 match name {
442 Ok(name) => match OUR_RUNTIME.readlink(name, target, unsafe { read_len.as_mut().unwrap() })
443 {
444 Ok(_) => RawTwzError::success().raw(),
445 Err(e) => e.raw(),
446 },
447 Err(e) => e,
448 }
449}
450check_ffi_type!(twz_rt_fd_readlink, _, _, _, _, _);
451
452use twizzler_rt_abi::bindings::{io_result, io_vec, whence};
454#[no_mangle]
455pub unsafe extern "C-unwind" fn twz_rt_fd_pread(
456 fd: descriptor,
457 buf: *mut ::core::ffi::c_void,
458 len: usize,
459 ctx: *mut io_ctx,
460) -> io_result {
461 let slice = unsafe { core::slice::from_raw_parts_mut(buf.cast::<u8>(), len) };
462 OUR_RUNTIME.fd_pread(fd, slice, ctx).into()
463}
464check_ffi_type!(twz_rt_fd_pread, _, _, _, _);
465
466#[no_mangle]
467pub unsafe extern "C-unwind" fn twz_rt_fd_pwrite(
468 fd: descriptor,
469 buf: *const ::core::ffi::c_void,
470 len: usize,
471 ctx: *mut io_ctx,
472) -> io_result {
473 let slice = unsafe { core::slice::from_raw_parts(buf.cast::<u8>(), len) };
474 OUR_RUNTIME.fd_pwrite(fd, slice, ctx).into()
475}
476check_ffi_type!(twz_rt_fd_pwrite, _, _, _, _);
477
478#[no_mangle]
479pub unsafe extern "C-unwind" fn twz_rt_fd_pwrite_to(
480 fd: descriptor,
481 buf: *const ::core::ffi::c_void,
482 len: usize,
483 ctx: *mut io_ctx,
484 ep: *const endpoint,
485) -> io_result {
486 todo!()
487}
488check_ffi_type!(twz_rt_fd_pwrite_to, _, _, _, _, _);
489
490#[no_mangle]
491pub unsafe extern "C-unwind" fn twz_rt_fd_pread_from(
492 fd: descriptor,
493 buf: *mut ::core::ffi::c_void,
494 len: usize,
495 ctx: *mut io_ctx,
496 ep: *mut endpoint,
497) -> io_result {
498 todo!()
499}
500check_ffi_type!(twz_rt_fd_pread_from, _, _, _, _, _);
501
502use twizzler_rt_abi::io::SeekFrom;
503
504fn twz_sf_to_std_sf(sf: SeekFrom) -> std::io::SeekFrom {
505 match sf {
506 SeekFrom::Start(pos) => std::io::SeekFrom::Start(pos),
507 SeekFrom::End(pos) => std::io::SeekFrom::End(pos),
508 SeekFrom::Current(pos) => std::io::SeekFrom::Current(pos),
509 }
510}
511
512#[no_mangle]
513pub unsafe extern "C-unwind" fn twz_rt_fd_seek(
514 fd: descriptor,
515 whence: whence,
516 offset: i64,
517) -> io_result {
518 let seek = match whence {
519 twizzler_rt_abi::bindings::WHENCE_START => SeekFrom::Start(offset as u64),
520 twizzler_rt_abi::bindings::WHENCE_END => SeekFrom::End(offset),
521 twizzler_rt_abi::bindings::WHENCE_CURRENT => SeekFrom::Current(offset),
522 _ => {
523 return io_result {
524 val: 0,
525 err: TwzError::INVALID_ARGUMENT.raw(),
526 }
527 }
528 };
529 OUR_RUNTIME.seek(fd, twz_sf_to_std_sf(seek)).into()
530}
531check_ffi_type!(twz_rt_fd_seek, _, _, _);
532
533#[no_mangle]
534pub unsafe extern "C-unwind" fn twz_rt_fd_preadv(
535 fd: descriptor,
536 iovs: *const io_vec,
537 nr_iovs: usize,
538 ctx: *mut io_ctx,
539) -> io_result {
540 let slice = unsafe { core::slice::from_raw_parts(iovs, nr_iovs) };
541 OUR_RUNTIME.fd_preadv(fd, slice, ctx).into()
542}
543check_ffi_type!(twz_rt_fd_preadv, _, _, _, _);
544
545#[no_mangle]
546pub unsafe extern "C-unwind" fn twz_rt_fd_pwritev(
547 fd: descriptor,
548 iovs: *const io_vec,
549 nr_iovs: usize,
550 ctx: *mut io_ctx,
551) -> io_result {
552 let slice = unsafe { core::slice::from_raw_parts(iovs, nr_iovs) };
553 OUR_RUNTIME.fd_pwritev(fd, slice, ctx).into()
554}
555check_ffi_type!(twz_rt_fd_pwritev, _, _, _, _);
556
557fn result_id_to_bindings(value: Result<ObjID, TwzError>) -> objid_result {
560 match value {
561 Ok(id) => objid_result {
562 err: RawTwzError::success().raw(),
563 __bindgen_padding_0: 0,
564 val: id.raw(),
565 },
566 Err(err) => objid_result {
567 err: err.raw(),
568 __bindgen_padding_0: 0,
569 val: 0,
570 },
571 }
572}
573
574use twizzler_rt_abi::{
575 bindings::{map_flags, map_result, object_handle, objid, objid_result},
576 object::MapFlags,
577};
578#[no_mangle]
579pub unsafe extern "C-unwind" fn twz_rt_create_rtobj() -> objid_result {
580 result_id_to_bindings(OUR_RUNTIME.create_rtobj())
581}
582check_ffi_type!(twz_rt_create_rtobj);
583
584#[no_mangle]
585pub unsafe extern "C-unwind" fn twz_rt_map_object(id: objid, flags: map_flags) -> map_result {
586 OUR_RUNTIME
587 .map_object(id.into(), MapFlags::from_bits_truncate(flags))
588 .into()
589}
590check_ffi_type!(twz_rt_map_object, _, _);
591
592#[no_mangle]
593pub unsafe extern "C-unwind" fn twz_rt_release_handle(handle: *mut object_handle) {
594 OUR_RUNTIME.release_handle(handle)
595}
596check_ffi_type!(twz_rt_release_handle, _);
597
598#[no_mangle]
599pub unsafe extern "C-unwind" fn twz_rt_update_handle(handle: *mut object_handle) -> twz_error {
600 match OUR_RUNTIME.update_handle(handle) {
601 Ok(_) => 0,
602 Err(e) => e.raw(),
603 }
604}
605check_ffi_type!(twz_rt_update_handle, _);
606
607#[no_mangle]
608pub unsafe extern "C-unwind" fn twz_rt_get_object_handle(ptr: *mut c_void) -> object_handle {
609 OUR_RUNTIME
610 .get_object_handle_from_ptr(ptr.cast())
611 .unwrap_or(object_handle::default())
612}
613check_ffi_type!(twz_rt_get_object_handle, _);
614
615#[no_mangle]
616pub unsafe extern "C-unwind" fn twz_rt_insert_fot(
617 handle: *mut object_handle,
618 fote: *mut c_void,
619) -> u32_result {
620 OUR_RUNTIME.insert_fot(handle, fote.cast()).into()
621}
622check_ffi_type!(twz_rt_insert_fot, _, _);
623
624#[no_mangle]
625pub unsafe extern "C-unwind" fn twz_rt_resolve_fot(
626 handle: *mut object_handle,
627 idx: u64,
628 valid_len: usize,
629 map_flags: map_flags,
630) -> map_result {
631 OUR_RUNTIME
632 .resolve_fot(
633 handle,
634 idx,
635 valid_len,
636 MapFlags::from_bits_truncate(map_flags),
637 )
638 .into()
639}
640check_ffi_type!(twz_rt_resolve_fot, _, _, _, _);
641
642#[no_mangle]
643pub unsafe extern "C-unwind" fn twz_rt_resolve_fot_local(
644 ptr: *mut c_void,
645 idx: u64,
646 valid_len: usize,
647 map_flags: map_flags,
648) -> *mut c_void {
649 OUR_RUNTIME
650 .resolve_fot_local(
651 ptr.cast(),
652 idx,
653 valid_len,
654 MapFlags::from_bits_truncate(map_flags),
655 )
656 .cast()
657}
658check_ffi_type!(twz_rt_resolve_fot_local, _, _, _, _);
659
660#[no_mangle]
661pub unsafe extern "C-unwind" fn __twz_rt_map_two_objects(
662 id_1: objid,
663 flags_1: map_flags,
664 id_2: objid,
665 flags_2: map_flags,
666 res_1: *mut map_result,
667 res_2: *mut map_result,
668) {
669 unsafe {
670 match OUR_RUNTIME.map_two_objects(
671 id_1.into(),
672 MapFlags::from_bits_truncate(flags_1),
673 id_2.into(),
674 MapFlags::from_bits_truncate(flags_2),
675 ) {
676 Ok((r1, r2)) => {
677 res_1.write(Ok(r1).into());
678 res_2.write(Ok(r2).into());
679 }
680 Err(e) => {
681 res_1.write(Err(e).into());
682 res_2.write(Err(e).into());
683 }
684 }
685 }
686}
687check_ffi_type!(__twz_rt_map_two_objects, _, _, _, _, _, _);
688
689use twizzler_rt_abi::bindings::duration;
692#[no_mangle]
693pub unsafe extern "C-unwind" fn twz_rt_get_monotonic_time() -> duration {
694 OUR_RUNTIME.get_monotonic().into()
695}
696check_ffi_type!(twz_rt_get_monotonic_time);
697
698#[no_mangle]
699pub unsafe extern "C-unwind" fn twz_rt_get_system_time() -> duration {
700 OUR_RUNTIME.get_system_time().into()
701}
702check_ffi_type!(twz_rt_get_system_time);
703
704use twizzler_rt_abi::bindings::{dl_phdr_info, loaded_image, loaded_image_id};
707#[no_mangle]
708pub unsafe extern "C-unwind" fn twz_rt_get_loaded_image(
709 id: loaded_image_id,
710 li: *mut loaded_image,
711) -> bool {
712 let Some(image_info) = OUR_RUNTIME.get_image_info(id) else {
713 return false;
714 };
715 unsafe {
716 li.write(image_info);
717 }
718 true
719}
720check_ffi_type!(twz_rt_get_loaded_image, _, _);
721
722#[no_mangle]
723pub unsafe extern "C-unwind" fn twz_rt_iter_phdr(
724 cb: ::core::option::Option<
725 unsafe extern "C-unwind" fn(
726 arg1: *const dl_phdr_info,
727 size: usize,
728 data: *mut ::core::ffi::c_void,
729 ) -> ::core::ffi::c_int,
730 >,
731 data: *mut ::core::ffi::c_void,
732) -> ::core::ffi::c_int {
733 OUR_RUNTIME
734 .iterate_phdr(&mut |info| cb.unwrap()(&info, core::mem::size_of::<dl_phdr_info>(), data))
735}
736check_ffi_type!(twz_rt_iter_phdr, _, _);
737
738use twizzler_rt_abi::bindings::system_info;
740#[no_mangle]
741pub unsafe extern "C-unwind" fn twz_rt_get_sysinfo() -> system_info {
742 OUR_RUNTIME.sysinfo()
743}
744check_ffi_type!(twz_rt_get_sysinfo);
745
746use twizzler_rt_abi::bindings::get_random_flags;
749#[no_mangle]
750pub unsafe extern "C-unwind" fn twz_rt_get_random(
751 buf: *mut ::core::ffi::c_char,
752 len: usize,
753 flags: get_random_flags,
754) -> usize {
755 OUR_RUNTIME.get_random(
756 unsafe { core::slice::from_raw_parts_mut(buf.cast(), len) },
757 flags.into(),
758 )
759}
760check_ffi_type!(twz_rt_get_random, _, _, _);
761
762#[linkage = "weak"]
765#[no_mangle]
766pub unsafe extern "C-unwind" fn malloc(len: usize) -> *mut core::ffi::c_void {
767 warn!("called c:malloc with len = {}: not yet implemented", len);
768 core::ptr::null_mut()
769}
770
771#[linkage = "weak"]
772#[no_mangle]
773pub unsafe extern "C-unwind" fn free(ptr: *mut core::ffi::c_void) {
774 warn!("called c:free with ptr = {:p}: not yet implemented", ptr);
775}
776
777#[linkage = "weak"]
778#[no_mangle]
779pub unsafe extern "C-unwind" fn getenv(name: *const core::ffi::c_char) -> *const core::ffi::c_char {
780 let n = unsafe { CStr::from_ptr(name.cast()) };
781 OUR_RUNTIME.cgetenv(n)
782}
783
784#[no_mangle]
785pub unsafe extern "C-unwind" fn dl_iterate_phdr(
786 cb: ::core::option::Option<
787 unsafe extern "C-unwind" fn(
788 arg1: *const dl_phdr_info,
789 size: usize,
790 data: *mut ::core::ffi::c_void,
791 ) -> ::core::ffi::c_int,
792 >,
793 data: *mut core::ffi::c_void,
794) -> i32 {
795 twz_rt_iter_phdr(cb, data)
796}
797
798#[linkage = "weak"]
799#[no_mangle]
800pub unsafe extern "C-unwind" fn fwrite(
801 ptr: *const core::ffi::c_void,
802 len: usize,
803 nitems: usize,
804 file: *const core::ffi::c_void,
805) -> usize {
806 twz_rt_fd_pwrite(1, ptr, len * nitems, core::ptr::null_mut());
807 len * nitems
808}
809
810#[linkage = "weak"]
811#[no_mangle]
812pub unsafe extern "C-unwind" fn fprintf(
813 file: *const core::ffi::c_void,
814 fmt: *const core::ffi::c_char,
815 mut args: ...
816) -> i32 {
817 use printf_compat::{format, output};
818 let mut s = String::new();
819 let bytes_written = format(fmt.cast(), args.as_va_list(), output::fmt_write(&mut s));
820 twz_rt_fd_pwrite(
821 1,
822 s.as_bytes().as_ptr().cast(),
823 s.as_bytes().len(),
824 core::ptr::null_mut(),
825 );
826 bytes_written
827}
828
829#[no_mangle]
830pub unsafe extern "C-unwind" fn __monitor_get_slot() -> isize {
831 match OUR_RUNTIME.allocate_slot() {
832 Some(s) => s.try_into().unwrap_or(-1),
833 None => -1,
834 }
835}
836
837#[no_mangle]
838pub unsafe extern "C-unwind" fn __monitor_release_slot(slot: usize) {
839 OUR_RUNTIME.release_slot(slot);
840}
841
842#[no_mangle]
843pub unsafe extern "C-unwind" fn __monitor_release_pair(one: usize, two: usize) {
844 OUR_RUNTIME.release_pair((one, two));
845}
846
847#[no_mangle]
848pub unsafe extern "C-unwind" fn __monitor_get_slot_pair(one: *mut usize, two: *mut usize) -> bool {
849 let Some((a, b)) = OUR_RUNTIME.allocate_pair() else {
850 return false;
851 };
852 one.write(a);
853 two.write(b);
854 true
855}
856
857#[no_mangle]
858pub unsafe extern "C-unwind" fn __monitor_ready() {
859 OUR_RUNTIME.set_runtime_ready();
860}
861
862#[no_mangle]
863pub unsafe extern "C-unwind" fn __is_monitor_ready() -> bool {
864 OUR_RUNTIME.state().contains(crate::RuntimeState::READY)
865}
866
867#[no_mangle]
868pub unsafe extern "C-unwind" fn __is_monitor() -> *mut c_void {
869 OUR_RUNTIME.is_monitor().unwrap_or(core::ptr::null_mut())
870}
871
872#[linkage = "weak"]
873#[no_mangle]
874pub unsafe extern "C-unwind" fn _ZdlPv() {}
875
876#[linkage = "weak"]
877#[no_mangle]
878pub unsafe extern "C-unwind" fn _ZdlPvj() {}
879
880#[linkage = "weak"]
881#[no_mangle]
882pub unsafe extern "C-unwind" fn _ZdlPvm() {}