twz_rt/
syms.rs

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