1use crate::{c_str::CString, platform::types::*};
2use alloc::boxed::Box;
3use core::ptr;
4
5#[repr(C)]
6pub enum RTLDState {
7 RtConsistent,
9 RtAdd,
11 RtDelete,
13}
14
15#[repr(C)]
18pub struct RTLDDebug {
19 r_version: i32,
21 r_map: *mut LinkMap,
23 pub r_brk: extern "C" fn(),
30
31 pub state: RTLDState,
34
35 pub r_ldbase: usize,
37}
38
39impl RTLDDebug {
40 const NEW: Self = RTLDDebug {
41 r_version: 1,
42 r_map: ptr::null_mut::<LinkMap>(),
43 r_brk: _dl_debug_state,
44 state: RTLDState::RtConsistent,
45 r_ldbase: 0,
46 };
47
48 pub fn insert(&mut self, l_addr: usize, name: &str, l_ld: usize) {
49 if self.r_map.is_null() {
50 self.r_map = LinkMap::new_with_args(l_addr, name, l_ld);
51 } else {
52 unsafe { (*self.r_map).add_object(l_addr, name, l_ld) };
53 }
54 }
55 pub fn insert_first(&mut self, l_addr: usize, name: &str, l_ld: usize) {
56 if self.r_map.is_null() {
57 self.r_map = LinkMap::new_with_args(l_addr, name, l_ld);
58 } else {
59 let tmp = self.r_map;
60 self.r_map = LinkMap::new_with_args(l_addr, name, l_ld);
61 unsafe { (*self.r_map).link(&mut *tmp) };
62 }
63 }
64}
65
66unsafe impl Send for RTLDDebug {}
70unsafe impl Sync for RTLDDebug {}
74
75#[repr(C)]
76struct LinkMap {
77 l_addr: usize,
82 l_name: *const c_char,
84 l_ld: usize,
86 l_next: *mut LinkMap,
87 l_prev: *mut LinkMap,
88}
89
90impl LinkMap {
91 fn new() -> *mut Self {
92 let map = Box::new(LinkMap {
93 l_addr: 0,
94 l_name: ptr::null(),
95 l_ld: 0,
96 l_next: ptr::null_mut(),
97 l_prev: ptr::null_mut(),
98 });
99 Box::into_raw(map)
100 }
101 fn link(&mut self, map: &mut LinkMap) {
102 map.l_prev = ptr::from_mut::<LinkMap>(self);
103 self.l_next = ptr::from_mut::<LinkMap>(map);
104 }
105 fn new_with_args(l_addr: usize, name: &str, l_ld: usize) -> *mut Self {
106 let map = LinkMap::new();
107 unsafe {
108 (*map).l_addr = l_addr;
109 (*map).l_ld = l_ld;
110 let c_name = CString::new(name).unwrap();
111 (*map).l_name = c_name.into_raw().cast_const();
112 }
113 map
114 }
115
116 fn add_object(&mut self, l_addr: usize, name: &str, l_ld: usize) {
117 let node = LinkMap::new_with_args(l_addr, name, l_ld);
118 let mut last = self;
119 while !last.l_next.is_null() {
120 last = unsafe { last.l_next.as_mut() }.unwrap();
121 }
122 unsafe {
123 (*node).l_prev = last;
124 last.l_next = node;
125 }
126 }
127}
128
129#[linkage = "weak"]
134#[unsafe(no_mangle)]
135pub extern "C" fn _dl_debug_state() {}
136
137#[unsafe(no_mangle)]
138pub static _r_debug: spin::Mutex<RTLDDebug> = spin::Mutex::new(RTLDDebug::NEW);