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::ffi::{c_void, CStr};
75
76use tracing::warn;
77use twizzler_abi::object::ObjID;
78// core.h
79use 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
144// alloc.h
145
146use 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// thread.h
205
206#[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// Provide this for C, since this will be emitted by the C compiler.
258#[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
288// fd.h
289
290use 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
452// io.h
453use 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
557// object.h
558
559fn 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
689// time.h
690
691use 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
704// debug.h
705
706use 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
738// info.h
739use 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
746// random.h
747
748use 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// additional definitions for C
763
764#[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() {}