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 ($f1:ident, _, _, _, _, _, _, _) => {
73 paste::paste! {
74 #[allow(dead_code, unused_variables, unused_assignments)]
75 fn [<__tc_ffi_ $f1>]() {
76 let mut x: unsafe extern "C-unwind" fn(_, _, _, _, _, _, _) -> _ = $f1;
77 x = twizzler_rt_abi::bindings::$f1;
78 }
79 }
80 };
81}
82
83use std::{
84 alloc::GlobalAlloc,
85 ffi::{c_void, CStr},
86};
87
88use tracing::warn;
89use twizzler_abi::{
90 object::{ObjID, MAX_SIZE},
91 syscall::ObjectCreate,
92};
93use twizzler_rt_abi::bindings::{
95 binding_info, endpoint, fd_set, io_ctx, name_resolver, name_root, object_cmd, object_create,
96 object_source, object_tie, option_exit_code, release_flags, twz_error, u32_result, wait_kind,
97};
98use twizzler_rt_abi::error::{ArgumentError, RawTwzError, TwzError};
99
100use crate::{runtime::OUR_RUNTIME, set_upcall_handler};
101
102#[no_mangle]
103pub unsafe extern "C-unwind" fn twz_rt_abort() {
104 OUR_RUNTIME.abort();
105}
106check_ffi_type!(twz_rt_abort);
107
108#[no_mangle]
109pub unsafe extern "C-unwind" fn twz_rt_exit(code: i32) {
110 OUR_RUNTIME.exit(code);
111}
112check_ffi_type!(twz_rt_exit, _);
113
114#[no_mangle]
115pub unsafe extern "C-unwind" fn twz_rt_pre_main_hook() -> option_exit_code {
116 match OUR_RUNTIME.pre_main_hook() {
117 Some(ec) => option_exit_code {
118 is_some: 1,
119 value: ec,
120 },
121 None => option_exit_code {
122 is_some: 0,
123 value: 0,
124 },
125 }
126}
127check_ffi_type!(twz_rt_pre_main_hook);
128
129#[no_mangle]
130pub unsafe extern "C-unwind" fn twz_rt_post_main_hook() {
131 OUR_RUNTIME.post_main_hook()
132}
133check_ffi_type!(twz_rt_post_main_hook);
134
135#[no_mangle]
136pub unsafe extern "C-unwind" fn twz_rt_runtime_entry(
137 arg: *const twizzler_rt_abi::bindings::runtime_info,
138 std_entry: core::option::Option<
139 unsafe extern "C-unwind" fn(
140 arg1: twizzler_rt_abi::bindings::basic_aux,
141 ) -> twizzler_rt_abi::bindings::basic_return,
142 >,
143 main: usize,
144) {
145 OUR_RUNTIME.runtime_entry(arg, std_entry.unwrap_unchecked(), main)
146}
147check_ffi_type!(twz_rt_runtime_entry, _, _, _);
148
149#[no_mangle]
150pub unsafe extern "C-unwind" fn twz_rt_cross_compartment_entry() -> bool {
151 OUR_RUNTIME.cross_compartment_entry().is_ok()
152}
153check_ffi_type!(twz_rt_cross_compartment_entry);
154
155#[no_mangle]
156pub unsafe extern "C-unwind" fn twz_rt_set_upcall_handler(
157 handler: Option<unsafe extern "C-unwind" fn(frame: *mut c_void, data: *const c_void)>,
158) {
159 let _ = set_upcall_handler(handler);
160}
161check_ffi_type!(twz_rt_set_upcall_handler, _);
162
163use twizzler_rt_abi::bindings::{alloc_flags, ZERO_MEMORY};
166#[no_mangle]
167pub unsafe extern "C-unwind" fn twz_rt_malloc(
168 sz: usize,
169 align: usize,
170 flags: alloc_flags,
171) -> *mut ::core::ffi::c_void {
172 let Ok(layout) = core::alloc::Layout::from_size_align(sz, align) else {
173 return core::ptr::null_mut();
174 };
175 if flags & ZERO_MEMORY != 0 {
176 OUR_RUNTIME.alloc_zeroed(layout).cast()
177 } else {
178 OUR_RUNTIME.alloc(layout).cast()
179 }
180}
181check_ffi_type!(twz_rt_malloc, _, _, _);
182
183#[no_mangle]
184pub unsafe extern "C-unwind" fn twz_rt_dealloc(
185 ptr: *mut ::core::ffi::c_void,
186 sz: usize,
187 align: usize,
188 flags: twizzler_rt_abi::bindings::alloc_flags,
189) {
190 let Ok(layout) = core::alloc::Layout::from_size_align(sz, align) else {
191 return;
192 };
193 if flags & ZERO_MEMORY != 0 {
194 let slice = unsafe { core::slice::from_raw_parts_mut(ptr.cast::<u8>(), sz) };
195 slice.fill(0);
196 core::hint::black_box(slice);
197 }
198 OUR_RUNTIME.dealloc(ptr.cast(), layout);
199}
200check_ffi_type!(twz_rt_dealloc, _, _, _, _);
201
202#[no_mangle]
203pub unsafe extern "C-unwind" fn twz_rt_realloc(
204 ptr: *mut ::core::ffi::c_void,
205 sz: usize,
206 align: usize,
207 new_size: usize,
208 flags: twizzler_rt_abi::bindings::alloc_flags,
209) -> *mut ::core::ffi::c_void {
210 let Ok(layout) = core::alloc::Layout::from_size_align(sz, align) else {
211 return core::ptr::null_mut();
212 };
213 if flags & ZERO_MEMORY != 0 {
214 todo!()
215 }
216 OUR_RUNTIME.realloc(ptr.cast(), layout, new_size).cast()
217}
218check_ffi_type!(twz_rt_realloc, _, _, _, _, _);
219
220#[no_mangle]
223pub unsafe extern "C-unwind" fn twz_rt_futex_wait(
224 ptr: *mut u32,
225 expected: twizzler_rt_abi::bindings::futex_word,
226 timeout: twizzler_rt_abi::bindings::option_duration,
227) -> twizzler_rt_abi::bindings::twz_error {
228 if timeout.is_some != 0 {
229 OUR_RUNTIME.futex_wait(&*ptr.cast(), expected, Some(timeout.dur.into()))
230 } else {
231 OUR_RUNTIME.futex_wait(&*ptr.cast(), expected, None)
232 }
233}
234check_ffi_type!(twz_rt_futex_wait, _, _, _);
235
236#[no_mangle]
237pub unsafe extern "C-unwind" fn twz_rt_futex_wake(
238 ptr: *mut u32,
239 max: i64,
240) -> twizzler_rt_abi::bindings::twz_error {
241 OUR_RUNTIME.futex_wake(&*ptr.cast(), max as usize)
242}
243check_ffi_type!(twz_rt_futex_wake, _, _);
244
245#[no_mangle]
246pub unsafe extern "C-unwind" fn twz_rt_yield_now() {
247 OUR_RUNTIME.yield_now();
248}
249check_ffi_type!(twz_rt_yield_now);
250
251#[no_mangle]
252pub unsafe extern "C-unwind" fn twz_rt_set_name(name: *const ::core::ffi::c_char) {
253 unsafe {
254 OUR_RUNTIME.set_name(core::ffi::CStr::from_ptr(name));
255 }
256}
257check_ffi_type!(twz_rt_set_name, _);
258
259#[no_mangle]
260pub unsafe extern "C-unwind" fn twz_rt_get_name(
261 tcb: *const c_void,
262 name: *mut core::ffi::c_char,
263 len: *mut usize,
264) {
265 unsafe {
266 *len = OUR_RUNTIME.get_name(tcb, core::slice::from_raw_parts_mut(name.cast(), *len));
267 }
268}
269check_ffi_type!(twz_rt_get_name, _, _, _);
270
271#[no_mangle]
272pub unsafe extern "C-unwind" fn twz_rt_sleep(dur: twizzler_rt_abi::bindings::duration) {
273 OUR_RUNTIME.sleep(dur.into());
274}
275check_ffi_type!(twz_rt_sleep, _);
276
277#[no_mangle]
278pub unsafe extern "C-unwind" fn twz_rt_tls_get_addr(
279 index: *mut twizzler_rt_abi::bindings::tls_index,
280) -> *mut ::core::ffi::c_void {
281 OUR_RUNTIME
282 .tls_get_addr(unsafe { &*index })
283 .unwrap_or(core::ptr::null_mut())
284 .cast()
285}
286check_ffi_type!(twz_rt_tls_get_addr, _);
287
288#[no_mangle]
290pub unsafe extern "C-unwind" fn __tls_get_addr(
291 index: *mut twizzler_rt_abi::bindings::tls_index,
292) -> *mut ::core::ffi::c_void {
293 twz_rt_tls_get_addr(index)
294}
295
296#[no_mangle]
297pub unsafe extern "C-unwind" fn twz_rt_spawn_thread(
298 args: twizzler_rt_abi::bindings::spawn_args,
299) -> twizzler_rt_abi::bindings::spawn_result {
300 OUR_RUNTIME.spawn(args).into()
301}
302check_ffi_type!(twz_rt_spawn_thread, _);
303#[no_mangle]
304pub unsafe extern "C-unwind" fn twz_rt_join_thread(
305 id: twizzler_rt_abi::bindings::thread_id,
306 timeout: twizzler_rt_abi::bindings::option_duration,
307) -> twizzler_rt_abi::bindings::twz_error {
308 match if timeout.is_some != 0 {
309 OUR_RUNTIME.join(id, Some(timeout.dur.into()))
310 } else {
311 OUR_RUNTIME.join(id, None)
312 } {
313 Ok(_) => RawTwzError::success().raw(),
314 Err(e) => e.raw(),
315 }
316}
317check_ffi_type!(twz_rt_join_thread, _, _);
318
319use twizzler_rt_abi::bindings::{descriptor, open_kind, open_result};
322#[no_mangle]
323pub unsafe extern "C-unwind" fn twz_rt_fd_open(
324 kind: open_kind,
325 flags: u32,
326 bind_info: *mut c_void,
327 bind_info_len: usize,
328) -> open_result {
329 let Ok(kind) = kind.try_into() else {
330 return Err(ArgumentError::InvalidArgument.into()).into();
331 };
332 OUR_RUNTIME
333 .open(None, kind, flags.into(), bind_info, bind_info_len, true)
334 .into()
335}
336check_ffi_type!(twz_rt_fd_open, _, _, _, _);
337
338#[no_mangle]
339pub unsafe extern "C-unwind" fn twz_rt_fd_reopen(
340 fd: descriptor,
341 kind: open_kind,
342 flags: u32,
343 bind_info: *mut c_void,
344 bind_info_len: usize,
345) -> twz_error {
346 let Ok(kind) = kind.try_into() else {
347 return TwzError::INVALID_ARGUMENT.raw();
348 };
349 match OUR_RUNTIME.open(Some(fd), kind, flags.into(), bind_info, bind_info_len, true) {
350 Ok(_) => RawTwzError::success().raw(),
351 Err(e) => e.raw(),
352 }
353}
354check_ffi_type!(twz_rt_fd_reopen, _, _, _, _, _);
355
356#[no_mangle]
357pub unsafe extern "C-unwind" fn twz_rt_fd_read_binds(
358 binds: *mut binding_info,
359 len: usize,
360) -> usize {
361 let binds = unsafe { core::slice::from_raw_parts_mut(binds, len) };
362 OUR_RUNTIME.read_binds(binds)
363}
364check_ffi_type!(twz_rt_fd_read_binds, _, _);
365
366use core::ffi::c_char;
367
368#[no_mangle]
369pub unsafe extern "C-unwind" fn twz_rt_fd_remove(name: *const c_char, len: usize) -> twz_error {
370 let name = unsafe { core::slice::from_raw_parts(name.cast(), len) };
371 let name = core::str::from_utf8(name).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
372 match name {
373 Ok(name) => match OUR_RUNTIME.remove(name) {
374 Ok(_) => RawTwzError::success().raw(),
375 Err(e) => e.raw(),
376 },
377 Err(e) => e,
378 }
379}
380check_ffi_type!(twz_rt_fd_remove, _, _);
381
382#[no_mangle]
383pub unsafe extern "C-unwind" fn twz_rt_fd_close(fd: descriptor) {
384 OUR_RUNTIME.close(fd);
385}
386check_ffi_type!(twz_rt_fd_close, _);
387
388#[no_mangle]
389pub unsafe extern "C-unwind" fn twz_rt_fd_get_info(
390 fd: descriptor,
391 fd_info: *mut twizzler_rt_abi::bindings::fd_info,
392) -> bool {
393 match OUR_RUNTIME.fd_get_info(fd) {
394 Some(info) => {
395 fd_info.write(info);
396 true
397 }
398 None => false,
399 }
400}
401check_ffi_type!(twz_rt_fd_get_info, _, _);
402
403#[no_mangle]
404pub unsafe extern "C-unwind" fn twz_rt_fd_cmd(
405 fd: descriptor,
406 cmd: twizzler_rt_abi::bindings::fd_cmd,
407 arg: *mut ::core::ffi::c_void,
408 ret: *mut ::core::ffi::c_void,
409) -> twz_error {
410 match OUR_RUNTIME.fd_cmd(fd, cmd, arg.cast(), ret.cast()) {
411 Ok(_) => RawTwzError::success().raw(),
412 Err(e) => e.raw(),
413 }
414}
415check_ffi_type!(twz_rt_fd_cmd, _, _, _, _);
416
417#[no_mangle]
418pub unsafe extern "C-unwind" fn twz_rt_fd_waitpoint(
419 fd: descriptor,
420 kind: wait_kind,
421 point: *mut *mut u64,
422 val: *mut u64,
423 ready: *mut bool,
424) -> twz_error {
425 match OUR_RUNTIME.fd_waitpoint(fd, kind) {
426 Ok((ts, is_ready)) => {
427 point.write(
428 ts.reference
429 .address()
430 .unwrap_or(core::ptr::null_mut())
431 .cast(),
432 );
433 val.write(ts.value);
434 ready.write(is_ready);
435 RawTwzError::success().raw()
436 }
437 Err(e) => e.raw(),
438 }
439}
440check_ffi_type!(twz_rt_fd_waitpoint, _, _, _, _, _);
441
442#[no_mangle]
443pub unsafe extern "C-unwind" fn twz_rt_fd_select(
444 nfds: usize,
445 readfds: *mut fd_set,
446 writefds: *mut fd_set,
447 exceptfds: *mut fd_set,
448 timeout: twizzler_rt_abi::bindings::option_duration,
449) -> io_result {
450 match OUR_RUNTIME.select(
451 nfds,
452 readfds,
453 writefds,
454 exceptfds,
455 if timeout.is_some != 0 {
456 Some(timeout.dur.into())
457 } else {
458 None
459 },
460 ) {
461 Ok(result) => io_result {
462 err: TwzError::SUCCESS.raw(),
463 val: result,
464 },
465 Err(e) => io_result {
466 err: e.raw(),
467 val: 0,
468 },
469 }
470}
471check_ffi_type!(twz_rt_fd_select, _, _, _, _, _);
472
473#[no_mangle]
474pub unsafe extern "C-unwind" fn twz_rt_fd_poll(
475 fds: *mut twizzler_rt_abi::bindings::pollfd,
476 nfds: usize,
477 timeout: twizzler_rt_abi::bindings::option_duration,
478) -> io_result {
479 let fd_slice = unsafe { core::slice::from_raw_parts_mut(fds, nfds) };
480 match OUR_RUNTIME.ppoll(
481 fd_slice,
482 if timeout.is_some != 0 {
483 Some(timeout.dur.into())
484 } else {
485 None
486 },
487 core::ptr::null(),
488 ) {
489 Ok(result) => io_result {
490 err: TwzError::SUCCESS.raw(),
491 val: result,
492 },
493 Err(e) => io_result {
494 err: e.raw(),
495 val: 0,
496 },
497 }
498}
499check_ffi_type!(twz_rt_fd_poll, _, _, _);
500
501#[no_mangle]
502pub unsafe extern "C-unwind" fn twz_rt_fd_enumerate_names(
503 fd: descriptor,
504 buf: *mut twizzler_rt_abi::bindings::name_entry,
505 len: ::core::ffi::c_size_t,
506 off: ::core::ffi::c_size_t,
507) -> io_result {
508 OUR_RUNTIME
509 .fd_enumerate(
510 fd,
511 unsafe { core::slice::from_raw_parts_mut(buf, len) },
512 off,
513 )
514 .into()
515}
516check_ffi_type!(twz_rt_fd_enumerate_names, _, _, _, _);
517
518#[no_mangle]
519pub unsafe extern "C-unwind" fn twz_rt_fd_mkns(name: *const c_char, len: usize) -> twz_error {
520 let name = unsafe { core::slice::from_raw_parts(name.cast(), len) };
521 let name = core::str::from_utf8(name).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
522 match name {
523 Ok(name) => match OUR_RUNTIME.mkns(name) {
524 Ok(_) => RawTwzError::success().raw(),
525 Err(e) => e.raw(),
526 },
527 Err(e) => e,
528 }
529}
530check_ffi_type!(twz_rt_fd_mkns, _, _);
531
532#[no_mangle]
533pub unsafe extern "C-unwind" fn twz_rt_fd_symlink(
534 name: *const c_char,
535 len: usize,
536 target: *const c_char,
537 target_len: usize,
538) -> twz_error {
539 let name = unsafe { core::slice::from_raw_parts(name.cast(), len) };
540 let name = core::str::from_utf8(name).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
541 let target = unsafe { core::slice::from_raw_parts(target.cast(), target_len) };
542 let Ok(target) = core::str::from_utf8(target).map_err(|_| TwzError::INVALID_ARGUMENT.raw())
543 else {
544 return TwzError::INVALID_ARGUMENT.into();
545 };
546 match name {
547 Ok(name) => match OUR_RUNTIME.symlink(name, target) {
548 Ok(_) => RawTwzError::success().raw(),
549 Err(e) => e.raw(),
550 },
551 Err(e) => e,
552 }
553}
554check_ffi_type!(twz_rt_fd_symlink, _, _, _, _);
555
556#[no_mangle]
557pub unsafe extern "C-unwind" fn twz_rt_get_thread_info(
558 id: twizzler_rt_abi::bindings::thread_id,
559) -> twizzler_rt_abi::bindings::thread_info {
560 let id = if id == twizzler_rt_abi::bindings::TWZ_RT_THREAD_ID_SELF {
561 None
562 } else {
563 Some(id)
564 };
565 OUR_RUNTIME.thread_get_info(id)
566}
567check_ffi_type!(twz_rt_get_thread_info, _);
568
569#[no_mangle]
570pub unsafe extern "C-unwind" fn twz_rt_fd_rename(
571 old_name: *const c_char,
572 old_len: usize,
573 new_name: *const c_char,
574 new_len: usize,
575) -> twz_error {
576 let old = unsafe { core::slice::from_raw_parts(old_name.cast(), old_len) };
577 let old = core::str::from_utf8(old).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
578 let new = unsafe { core::slice::from_raw_parts(new_name.cast(), new_len) };
579 let Ok(new) = core::str::from_utf8(new).map_err(|_| TwzError::INVALID_ARGUMENT.raw()) else {
580 return TwzError::INVALID_ARGUMENT.into();
581 };
582 match old {
583 Ok(old) => match OUR_RUNTIME.rename(old, new) {
584 Ok(_) => RawTwzError::success().raw(),
585 Err(e) => e.raw(),
586 },
587 Err(e) => e,
588 }
589}
590check_ffi_type!(twz_rt_fd_rename, _, _, _, _);
591
592#[no_mangle]
593pub unsafe extern "C-unwind" fn twz_rt_fd_readlink(
594 name: *const c_char,
595 len: usize,
596 target: *mut c_char,
597 target_len: usize,
598 read_len: *mut u64,
599) -> twz_error {
600 let name = unsafe { core::slice::from_raw_parts(name.cast(), len) };
601 let name = core::str::from_utf8(name).map_err(|_| TwzError::INVALID_ARGUMENT.raw());
602 let target = unsafe { core::slice::from_raw_parts_mut(target.cast(), target_len) };
603 match name {
604 Ok(name) => match OUR_RUNTIME.readlink(name, target, unsafe { read_len.as_mut().unwrap() })
605 {
606 Ok(_) => RawTwzError::success().raw(),
607 Err(e) => e.raw(),
608 },
609 Err(e) => e,
610 }
611}
612check_ffi_type!(twz_rt_fd_readlink, _, _, _, _, _);
613
614#[no_mangle]
615pub unsafe extern "C-unwind" fn twz_rt_get_nameroot(
616 root: name_root,
617 path: *mut c_char,
618 len: usize,
619) -> io_result {
620 let slice = unsafe { core::slice::from_raw_parts_mut(path.cast::<u8>(), len) };
621 OUR_RUNTIME.get_nameroot(root.into(), slice).into()
622}
623check_ffi_type!(twz_rt_get_nameroot, _, _, _);
624
625#[no_mangle]
626pub unsafe extern "C-unwind" fn twz_rt_set_nameroot(
627 root: name_root,
628 path: *const c_char,
629 len: usize,
630) -> twz_error {
631 let slice = unsafe { core::slice::from_raw_parts(path.cast::<u8>(), len) };
632 match OUR_RUNTIME.set_nameroot(root.into(), slice) {
633 Ok(_) => RawTwzError::success().raw(),
634 Err(e) => e.raw(),
635 }
636}
637check_ffi_type!(twz_rt_set_nameroot, _, _, _);
638
639use twizzler_rt_abi::bindings::{io_result, iovec, whence};
641#[no_mangle]
642pub unsafe extern "C-unwind" fn twz_rt_fd_pread(
643 fd: descriptor,
644 buf: *mut ::core::ffi::c_void,
645 len: usize,
646 ctx: *mut io_ctx,
647) -> io_result {
648 let slice = unsafe { core::slice::from_raw_parts_mut(buf.cast::<u8>(), len) };
649 OUR_RUNTIME.fd_pread(fd, slice, ctx).into()
650}
651check_ffi_type!(twz_rt_fd_pread, _, _, _, _);
652
653#[no_mangle]
654pub unsafe extern "C-unwind" fn twz_rt_fd_pwrite(
655 fd: descriptor,
656 buf: *const ::core::ffi::c_void,
657 len: usize,
658 ctx: *mut io_ctx,
659) -> io_result {
660 let slice = unsafe { core::slice::from_raw_parts(buf.cast::<u8>(), len) };
661 OUR_RUNTIME.fd_pwrite(fd, slice, ctx).into()
662}
663check_ffi_type!(twz_rt_fd_pwrite, _, _, _, _);
664
665#[no_mangle]
666pub unsafe extern "C-unwind" fn twz_rt_fd_pwrite_to(
667 fd: descriptor,
668 buf: *const ::core::ffi::c_void,
669 len: usize,
670 ctx: *mut io_ctx,
671 ep: *const endpoint,
672) -> io_result {
673 let slice = unsafe { core::slice::from_raw_parts(buf.cast::<u8>(), len) };
674 OUR_RUNTIME.fd_pwrite_to(fd, slice, ctx, ep).into()
675}
676check_ffi_type!(twz_rt_fd_pwrite_to, _, _, _, _, _);
677
678#[no_mangle]
679pub unsafe extern "C-unwind" fn twz_rt_fd_pread_from(
680 fd: descriptor,
681 buf: *mut ::core::ffi::c_void,
682 len: usize,
683 ctx: *mut io_ctx,
684 ep: *mut endpoint,
685) -> io_result {
686 let slice = unsafe { core::slice::from_raw_parts_mut(buf.cast::<u8>(), len) };
687 OUR_RUNTIME.fd_pread_from(fd, slice, ctx, ep).into()
688}
689check_ffi_type!(twz_rt_fd_pread_from, _, _, _, _, _);
690
691use twizzler_rt_abi::io::SeekFrom;
692
693fn twz_sf_to_std_sf(sf: SeekFrom) -> std::io::SeekFrom {
694 match sf {
695 SeekFrom::Start(pos) => std::io::SeekFrom::Start(pos),
696 SeekFrom::End(pos) => std::io::SeekFrom::End(pos),
697 SeekFrom::Current(pos) => std::io::SeekFrom::Current(pos),
698 }
699}
700
701#[no_mangle]
702pub unsafe extern "C-unwind" fn twz_rt_fd_seek(
703 fd: descriptor,
704 whence: whence,
705 offset: i64,
706) -> io_result {
707 let seek = match whence {
708 twizzler_rt_abi::bindings::WHENCE_START => SeekFrom::Start(offset as u64),
709 twizzler_rt_abi::bindings::WHENCE_END => SeekFrom::End(offset),
710 twizzler_rt_abi::bindings::WHENCE_CURRENT => SeekFrom::Current(offset),
711 _ => {
712 return io_result {
713 val: 0,
714 err: TwzError::INVALID_ARGUMENT.raw(),
715 }
716 }
717 };
718 OUR_RUNTIME.seek(fd, twz_sf_to_std_sf(seek)).into()
719}
720check_ffi_type!(twz_rt_fd_seek, _, _, _);
721
722#[no_mangle]
723pub unsafe extern "C-unwind" fn twz_rt_fd_preadv(
724 fd: descriptor,
725 iovs: *const iovec,
726 nr_iovs: usize,
727 ctx: *mut io_ctx,
728) -> io_result {
729 let slice = unsafe { core::slice::from_raw_parts(iovs, nr_iovs) };
730 OUR_RUNTIME.fd_preadv(fd, slice, ctx).into()
731}
732check_ffi_type!(twz_rt_fd_preadv, _, _, _, _);
733
734#[no_mangle]
735pub unsafe extern "C-unwind" fn twz_rt_fd_pwritev(
736 fd: descriptor,
737 iovs: *const iovec,
738 nr_iovs: usize,
739 ctx: *mut io_ctx,
740) -> io_result {
741 let slice = unsafe { core::slice::from_raw_parts(iovs, nr_iovs) };
742 OUR_RUNTIME.fd_pwritev(fd, slice, ctx).into()
743}
744check_ffi_type!(twz_rt_fd_pwritev, _, _, _, _);
745
746#[no_mangle]
747pub unsafe extern "C-unwind" fn twz_rt_fd_get_config(
748 fd: descriptor,
749 reg: u32,
750 val: *mut c_void,
751 val_len: usize,
752) -> twz_error {
753 match OUR_RUNTIME.fd_get_config(fd, reg, val, val_len) {
754 Ok(_) => RawTwzError::success().raw(),
755 Err(e) => e.raw(),
756 }
757}
758check_ffi_type!(twz_rt_fd_get_config, _, _, _, _);
759
760#[no_mangle]
761pub unsafe extern "C-unwind" fn twz_rt_fd_set_config(
762 fd: descriptor,
763 reg: u32,
764 val: *const c_void,
765 val_len: usize,
766) -> twz_error {
767 match OUR_RUNTIME.fd_set_config(fd, reg, val, val_len) {
768 Ok(_) => RawTwzError::success().raw(),
769 Err(e) => e.raw(),
770 }
771}
772check_ffi_type!(twz_rt_fd_set_config, _, _, _, _);
773
774#[no_mangle]
775pub unsafe extern "C-unwind" fn twz_rt_resolve_name(
776 resolver: name_resolver,
777 name: *const c_char,
778 name_len: usize,
779) -> objid_result {
780 let slice = unsafe { core::slice::from_raw_parts(name as *const u8, name_len) };
781 result_id_to_bindings(OUR_RUNTIME.resolve_name(resolver.into(), slice))
782}
783check_ffi_type!(twz_rt_resolve_name, _, _, _);
784
785#[no_mangle]
786pub unsafe extern "C-unwind" fn twz_rt_canon_name(
787 resolver: name_resolver,
788 name: *const c_char,
789 name_len: usize,
790 out: *mut c_char,
791 out_len: *mut usize,
792) -> twz_error {
793 let slice = unsafe { core::slice::from_raw_parts(name as *const u8, name_len) };
794 let out_slice = unsafe { core::slice::from_raw_parts_mut(out as *mut u8, out_len.read()) };
795 match OUR_RUNTIME.canon_name(resolver.into(), slice, out_slice) {
796 Ok(len) => {
797 out_len.write(len);
798 RawTwzError::success().raw()
799 }
800 Err(e) => e.raw(),
801 }
802}
803check_ffi_type!(twz_rt_canon_name, _, _, _, _, _);
804
805fn result_id_to_bindings(value: Result<ObjID, TwzError>) -> objid_result {
808 match value {
809 Ok(id) => objid_result {
810 err: RawTwzError::success().raw(),
811 __bindgen_padding_0: 0,
812 val: id.raw(),
813 },
814 Err(err) => objid_result {
815 err: err.raw(),
816 __bindgen_padding_0: 0,
817 val: 0,
818 },
819 }
820}
821
822use twizzler_rt_abi::{
823 bindings::{map_flags, map_result, object_handle, objid, objid_result},
824 object::MapFlags,
825};
826#[no_mangle]
827pub unsafe extern "C-unwind" fn twz_rt_create_rtobj() -> objid_result {
828 result_id_to_bindings(OUR_RUNTIME.create_rtobj())
829}
830check_ffi_type!(twz_rt_create_rtobj);
831
832#[unsafe(no_mangle)]
833pub unsafe extern "C-unwind" fn twz_rt_create_object(
834 spec: *const object_create,
835 src: *const object_source,
836 src_len: usize,
837 ties: *const object_tie,
838 tie_len: usize,
839 name: *const c_char,
840 namelen: usize,
841) -> objid_result {
842 let spec = spec.as_ref().unwrap();
843 let src = if !src.is_null() {
844 core::slice::from_raw_parts(src, src_len)
845 } else {
846 &[]
847 };
848 let ties = if !ties.is_null() {
849 core::slice::from_raw_parts(ties, tie_len)
850 } else {
851 &[]
852 };
853 let name_slice = if !name.is_null() {
854 Some(core::slice::from_raw_parts(name.cast(), namelen))
855 } else {
856 None
857 };
858 let name = name_slice.and_then(|name_slice| str::from_utf8(name_slice).ok());
859 result_id_to_bindings(OUR_RUNTIME.create_object(&ObjectCreate::from(*spec), src, ties, name))
860}
861check_ffi_type!(twz_rt_create_object, _, _, _, _, _, _, _);
862
863#[no_mangle]
864pub unsafe extern "C-unwind" fn twz_rt_map_object(id: objid, flags: map_flags) -> map_result {
865 OUR_RUNTIME
866 .map_object(id.into(), MapFlags::from_bits_truncate(flags))
867 .into()
868}
869check_ffi_type!(twz_rt_map_object, _, _);
870
871#[no_mangle]
872pub unsafe extern "C-unwind" fn twz_rt_release_handle(
873 handle: *mut object_handle,
874 flags: release_flags,
875) {
876 OUR_RUNTIME.release_handle(handle, flags)
877}
878check_ffi_type!(twz_rt_release_handle, _, _);
879
880#[no_mangle]
881pub unsafe extern "C-unwind" fn twz_rt_object_cmd(
882 handle: *mut object_handle,
883 cmd: object_cmd,
884 arg: *mut c_void,
885) -> twz_error {
886 match OUR_RUNTIME.object_cmd(handle, cmd, arg) {
887 Ok(_) => 0,
888 Err(e) => e.raw(),
889 }
890}
891check_ffi_type!(twz_rt_object_cmd, _, _, _);
892
893#[no_mangle]
894pub unsafe extern "C-unwind" fn twz_rt_update_handle(handle: *mut object_handle) -> twz_error {
895 match OUR_RUNTIME.update_handle(handle) {
896 Ok(_) => 0,
897 Err(e) => e.raw(),
898 }
899}
900check_ffi_type!(twz_rt_update_handle, _);
901
902#[no_mangle]
903pub unsafe extern "C-unwind" fn twz_rt_get_object_handle(ptr: *mut c_void) -> object_handle {
904 OUR_RUNTIME
905 .get_object_handle_from_ptr(ptr.cast())
906 .unwrap_or(object_handle::default())
907}
908check_ffi_type!(twz_rt_get_object_handle, _);
909
910#[no_mangle]
911pub unsafe extern "C-unwind" fn twz_rt_insert_fot(
912 handle: *mut object_handle,
913 fote: *mut c_void,
914) -> u32_result {
915 OUR_RUNTIME.insert_fot(handle, fote.cast()).into()
916}
917check_ffi_type!(twz_rt_insert_fot, _, _);
918
919#[no_mangle]
920pub unsafe extern "C-unwind" fn twz_rt_resolve_fot(
921 handle: *mut object_handle,
922 idx: u64,
923 valid_len: usize,
924 map_flags: map_flags,
925) -> map_result {
926 OUR_RUNTIME
927 .resolve_fot(
928 handle,
929 idx,
930 valid_len,
931 MapFlags::from_bits_truncate(map_flags),
932 )
933 .into()
934}
935check_ffi_type!(twz_rt_resolve_fot, _, _, _, _);
936
937#[no_mangle]
938pub unsafe extern "C-unwind" fn twz_rt_resolve_fot_local(
939 ptr: *mut c_void,
940 idx: u64,
941 valid_len: usize,
942 map_flags: map_flags,
943) -> *mut c_void {
944 OUR_RUNTIME
945 .resolve_fot_local(
946 ptr.cast(),
947 idx,
948 valid_len,
949 MapFlags::from_bits_truncate(map_flags),
950 )
951 .cast()
952}
953check_ffi_type!(twz_rt_resolve_fot_local, _, _, _, _);
954
955#[no_mangle]
956pub unsafe extern "C-unwind" fn __twz_rt_map_two_objects(
957 id_1: objid,
958 flags_1: map_flags,
959 id_2: objid,
960 flags_2: map_flags,
961 res_1: *mut map_result,
962 res_2: *mut map_result,
963) {
964 unsafe {
965 match OUR_RUNTIME.map_two_objects(
966 id_1.into(),
967 MapFlags::from_bits_truncate(flags_1),
968 id_2.into(),
969 MapFlags::from_bits_truncate(flags_2),
970 ) {
971 Ok((r1, r2)) => {
972 res_1.write(Ok(r1).into());
973 res_2.write(Ok(r2).into());
974 }
975 Err(e) => {
976 res_1.write(Err(e).into());
977 res_2.write(Err(e).into());
978 }
979 }
980 }
981}
982check_ffi_type!(__twz_rt_map_two_objects, _, _, _, _, _, _);
983
984use twizzler_rt_abi::bindings::duration;
987#[no_mangle]
988pub unsafe extern "C-unwind" fn twz_rt_get_monotonic_time() -> duration {
989 OUR_RUNTIME.get_monotonic().into()
990}
991check_ffi_type!(twz_rt_get_monotonic_time);
992
993#[no_mangle]
994pub unsafe extern "C-unwind" fn twz_rt_get_system_time() -> duration {
995 OUR_RUNTIME.get_system_time().into()
996}
997check_ffi_type!(twz_rt_get_system_time);
998
999use twizzler_rt_abi::bindings::{dl_phdr_info, loaded_image, loaded_image_id};
1002#[no_mangle]
1003pub unsafe extern "C-unwind" fn twz_rt_get_loaded_image(
1004 id: loaded_image_id,
1005 li: *mut loaded_image,
1006) -> bool {
1007 let Some(image_info) = OUR_RUNTIME.get_image_info(id) else {
1008 return false;
1009 };
1010 unsafe {
1011 li.write(image_info);
1012 }
1013 true
1014}
1015check_ffi_type!(twz_rt_get_loaded_image, _, _);
1016
1017#[no_mangle]
1018pub unsafe extern "C-unwind" fn twz_rt_iter_phdr(
1019 cb: ::core::option::Option<
1020 unsafe extern "C-unwind" fn(
1021 arg1: *const dl_phdr_info,
1022 size: usize,
1023 data: *mut ::core::ffi::c_void,
1024 ) -> ::core::ffi::c_int,
1025 >,
1026 data: *mut ::core::ffi::c_void,
1027) -> ::core::ffi::c_int {
1028 OUR_RUNTIME
1029 .iterate_phdr(&mut |info| cb.unwrap()(&info, core::mem::size_of::<dl_phdr_info>(), data))
1030}
1031check_ffi_type!(twz_rt_iter_phdr, _, _);
1032
1033use twizzler_rt_abi::bindings::system_info;
1035#[no_mangle]
1036pub unsafe extern "C-unwind" fn twz_rt_get_sysinfo() -> system_info {
1037 OUR_RUNTIME.sysinfo()
1038}
1039check_ffi_type!(twz_rt_get_sysinfo);
1040
1041#[no_mangle]
1044pub unsafe extern "C-unwind" fn twz_rt_exec_spawn(
1045 args: *const twizzler_rt_abi::bindings::exec_spawn_args,
1046) -> open_result {
1047 OUR_RUNTIME.exec_spawn(args.as_ref().unwrap()).into()
1048}
1049check_ffi_type!(twz_rt_exec_spawn, _);
1050
1051use twizzler_rt_abi::bindings::get_random_flags;
1054#[no_mangle]
1055pub unsafe extern "C-unwind" fn twz_rt_get_random(
1056 buf: *mut ::core::ffi::c_char,
1057 len: usize,
1058 flags: get_random_flags,
1059) -> usize {
1060 OUR_RUNTIME.get_random(
1061 unsafe { core::slice::from_raw_parts_mut(buf.cast(), len) },
1062 flags.into(),
1063 )
1064}
1065check_ffi_type!(twz_rt_get_random, _, _, _);
1066
1067#[linkage = "weak"]
1069#[no_mangle]
1070pub unsafe extern "C-unwind" fn malloc(len: usize) -> *mut core::ffi::c_void {
1071 warn!("called c:malloc with len = {}: not yet implemented", len);
1072 core::ptr::null_mut()
1073}
1074
1075#[linkage = "weak"]
1076#[no_mangle]
1077pub unsafe extern "C-unwind" fn free(ptr: *mut core::ffi::c_void) {
1078 warn!("called c:free with ptr = {:p}: not yet implemented", ptr);
1079}
1080
1081#[linkage = "weak"]
1082#[no_mangle]
1083pub unsafe extern "C-unwind" fn getenv(name: *const core::ffi::c_char) -> *const core::ffi::c_char {
1084 let n = unsafe { CStr::from_ptr(name.cast()) };
1085 OUR_RUNTIME.cgetenv(n)
1086}
1087
1088#[no_mangle]
1089pub unsafe extern "C-unwind" fn dl_iterate_phdr(
1090 cb: ::core::option::Option<
1091 unsafe extern "C-unwind" fn(
1092 arg1: *const dl_phdr_info,
1093 size: usize,
1094 data: *mut ::core::ffi::c_void,
1095 ) -> ::core::ffi::c_int,
1096 >,
1097 data: *mut core::ffi::c_void,
1098) -> i32 {
1099 twz_rt_iter_phdr(cb, data)
1100}
1101
1102#[linkage = "weak"]
1103#[no_mangle]
1104pub unsafe extern "C-unwind" fn fwrite(
1105 ptr: *const core::ffi::c_void,
1106 len: usize,
1107 nitems: usize,
1108 file: *const core::ffi::c_void,
1109) -> usize {
1110 twz_rt_fd_pwrite(1, ptr, len * nitems, core::ptr::null_mut());
1111 len * nitems
1112}
1113
1114#[linkage = "weak"]
1115#[unsafe(no_mangle)]
1116pub unsafe extern "C-unwind" fn fprintf(
1117 file: *const core::ffi::c_void,
1118 fmt: *const core::ffi::c_char,
1119 args: ...
1120) -> i32 {
1121 use printf_compat::{format, output};
1122 let mut s = String::new();
1123 let bytes_written = format(fmt.cast(), args, output::fmt_write(&mut s));
1124 twz_rt_fd_pwrite(
1125 1,
1126 s.as_bytes().as_ptr().cast(),
1127 s.as_bytes().len(),
1128 core::ptr::null_mut(),
1129 );
1130 bytes_written
1131}
1132
1133#[no_mangle]
1134pub unsafe extern "C-unwind" fn __monitor_get_slot() -> isize {
1135 match OUR_RUNTIME.allocate_slot() {
1136 Some(s) => s.try_into().unwrap_or(-1),
1137 None => -1,
1138 }
1139}
1140
1141#[no_mangle]
1142pub unsafe extern "C-unwind" fn __monitor_release_slot(slot: usize) {
1143 OUR_RUNTIME.release_slot(slot);
1144}
1145
1146#[no_mangle]
1147pub unsafe extern "C-unwind" fn __monitor_release_pair(one: usize, two: usize) {
1148 OUR_RUNTIME.release_pair((one, two));
1149}
1150
1151#[no_mangle]
1152pub unsafe extern "C-unwind" fn __monitor_get_slot_pair(one: *mut usize, two: *mut usize) -> bool {
1153 let Some((a, b)) = OUR_RUNTIME.allocate_pair() else {
1154 return false;
1155 };
1156 one.write(a);
1157 two.write(b);
1158 true
1159}
1160
1161#[no_mangle]
1162pub unsafe extern "C-unwind" fn __monitor_ready() {
1163 OUR_RUNTIME.set_runtime_ready();
1164}
1165
1166#[no_mangle]
1167pub unsafe extern "C-unwind" fn __is_monitor_ready() -> bool {
1168 OUR_RUNTIME.state().contains(crate::RuntimeState::READY)
1169}
1170
1171#[no_mangle]
1172pub unsafe extern "C-unwind" fn __is_monitor() -> *mut c_void {
1173 OUR_RUNTIME.is_monitor().unwrap_or(core::ptr::null_mut())
1174}
1175
1176#[linkage = "weak"]
1177#[no_mangle]
1178pub unsafe extern "C-unwind" fn _ZdlPv() {}
1179
1180#[linkage = "weak"]
1181#[no_mangle]
1182pub unsafe extern "C-unwind" fn _ZdlPvj() {}
1183
1184#[linkage = "weak"]
1185#[no_mangle]
1186pub unsafe extern "C-unwind" fn _ZdlPvm() {}
1187
1188#[linkage = "weak"]
1189#[unsafe(no_mangle)]
1190pub unsafe extern "C" fn __dlapi_error() -> *const c_char {
1191 take_dl_error()
1192}
1193
1194use core::ffi::c_int;
1195use std::cell::RefCell;
1196
1197#[thread_local]
1198static DLAPI_ERROR: RefCell<Option<std::ffi::CString>> = const { RefCell::new(None) };
1199
1200fn set_dl_error(msg: impl Into<Vec<u8>>) {
1201 *DLAPI_ERROR.borrow_mut() = std::ffi::CString::new(msg).ok();
1202}
1203
1204fn take_dl_error() -> *const c_char {
1205 DLAPI_ERROR
1206 .borrow_mut()
1207 .take()
1208 .map(|s| s.into_raw() as *const c_char)
1209 .unwrap_or(core::ptr::null())
1210}
1211
1212#[repr(C)]
1214struct DlapiSymbol {
1215 file: *const c_char,
1216 base: *mut c_void,
1217 symbol: *const c_char,
1218 address: *mut c_void,
1219 elf_symbol: *const c_void,
1220 link_map: *mut c_void,
1221}
1222
1223fn desc_to_handle(desc: secgate::util::Descriptor) -> *mut c_void {
1225 (desc as usize + 1) as *mut c_void
1226}
1227
1228fn handle_to_desc(handle: *const c_void) -> Option<secgate::util::Descriptor> {
1230 let v = handle as usize;
1231 if v == 0 {
1232 None
1233 } else {
1234 Some((v - 1) as secgate::util::Descriptor)
1235 }
1236}
1237
1238#[linkage = "weak"]
1239#[unsafe(no_mangle)]
1240pub unsafe extern "C" fn __dlapi_open(
1241 filename: *const c_char,
1242 _flags: c_int,
1243 _return_addr: *const c_void,
1244) -> *mut c_void {
1245 if filename.is_null() {
1247 return core::ptr::null_mut(); }
1249 let name = match unsafe { std::ffi::CStr::from_ptr(filename) }.to_str() {
1250 Ok(s) => s,
1251 Err(_) => {
1252 set_dl_error("dlopen: invalid UTF-8 in filename");
1253 return core::ptr::null_mut();
1254 }
1255 };
1256 let id = OUR_RUNTIME
1257 .resolve_name(twizzler_rt_abi::fd::NameResolver::Default, name.as_bytes())
1258 .ok();
1259 match monitor_api::LibraryLoader::new(name, id).load() {
1260 Ok(desc) => desc_to_handle(desc.into_raw()),
1261 Err(e) => {
1262 set_dl_error(format!("dlopen: library '{}' not found: {:?}", name, e));
1263 core::ptr::null_mut()
1264 }
1265 }
1266}
1267
1268#[linkage = "weak"]
1269#[unsafe(no_mangle)]
1270pub unsafe extern "C" fn __dlapi_resolve(
1271 handle: *const c_void,
1272 symbol: *const c_char,
1273 _return_addr: *const c_void,
1274 _version: *const c_char,
1275) -> *mut c_void {
1276 let sym_name = match unsafe { std::ffi::CStr::from_ptr(symbol) }.to_str() {
1277 Ok(s) => s,
1278 Err(_) => {
1279 set_dl_error("dlsym: invalid UTF-8 in symbol name");
1280 return core::ptr::null_mut();
1281 }
1282 };
1283 let lib_desc = handle_to_desc(handle);
1284 match monitor_api::lookup_symbol_by_name(lib_desc, sym_name) {
1285 Ok(addr) if addr != 0 => addr as *mut c_void,
1286 Ok(_) => {
1287 set_dl_error(format!("dlsym: symbol '{}' resolved to NULL", sym_name));
1288 core::ptr::null_mut()
1289 }
1290 Err(e) => {
1291 set_dl_error(format!("dlsym: symbol '{}' not found: {:?}", sym_name, e));
1292 core::ptr::null_mut()
1293 }
1294 }
1295}
1296
1297#[linkage = "weak"]
1298#[unsafe(no_mangle)]
1299pub unsafe extern "C" fn __dlapi_reverse(
1300 ptr: *const c_void,
1301 out: *mut c_void, ) -> c_int {
1303 if out.is_null() {
1305 return 1;
1306 }
1307 let out = unsafe { &mut *(out as *mut DlapiSymbol) };
1308
1309 let mut lib_n: usize = 0;
1312 loop {
1313 let desc = match monitor_api::monitor_rt_get_library_handle(None, lib_n) {
1314 Ok(d) => d,
1315 Err(_) => break,
1316 };
1317 let raw = match monitor_api::monitor_rt_get_library_info(desc) {
1318 Ok(r) => r,
1319 Err(_) => {
1320 let _ = monitor_api::monitor_rt_drop_library_handle(desc);
1321 break;
1322 }
1323 };
1324 let lib_info = monitor_api::LibraryInfo::from_raw(raw);
1325 let base = lib_info.dl_info.addr as *const u8;
1326 let len = lib_info.len;
1327
1328 if !base.is_null()
1329 && (ptr as usize) >= (base as usize)
1330 && (ptr as usize) < (base as usize + MAX_SIZE * 2)
1331 {
1332 let name_cstring = std::ffi::CString::new(lib_info.name.clone()).unwrap_or_default();
1334 let name_ptr: *const c_char = name_cstring.into_raw();
1335 let _ = monitor_api::monitor_rt_drop_library_handle(desc);
1336 out.file = name_ptr;
1337 out.base = base as *mut c_void;
1338 out.symbol = core::ptr::null();
1339 out.address = core::ptr::null_mut();
1340 out.elf_symbol = core::ptr::null();
1341 out.link_map = lib_info.link_map.0.ld.cast();
1342 return 0;
1343 }
1344
1345 let _ = monitor_api::monitor_rt_drop_library_handle(desc);
1346 lib_n += 1;
1347 }
1348 1 }
1350
1351#[linkage = "weak"]
1352#[unsafe(no_mangle)]
1353pub unsafe extern "C" fn __dlapi_close(handle: *const c_void) -> c_int {
1354 if handle.is_null() {
1355 return 0;
1356 }
1357 let Some(desc) = handle_to_desc(handle) else {
1358 return 0;
1359 };
1360 match monitor_api::monitor_rt_drop_library_handle(desc) {
1361 Ok(()) => 0,
1362 Err(_) => 1,
1363 }
1364}
1365
1366#[linkage = "weak"]
1367#[unsafe(no_mangle)]
1368pub unsafe extern "C" fn __dlapi_find_object() -> *const c_char {
1369 twizzler_abi::klog_println!("called __dlapi_find_object: not yet implemented");
1370 core::ptr::null()
1371}
1372
1373#[linkage = "weak"]
1374#[unsafe(no_mangle)]
1375pub unsafe extern "C" fn __dlapi_get_tls() -> *const c_char {
1376 twizzler_abi::klog_println!("called __dlapi_get_tls: not yet implemented");
1377 core::ptr::null()
1378}