userspace/memory/stack/
environment.rs

1use crate::info;
2use crate::target::os::syscall;
3
4pub mod entry;
5pub use entry::*;
6
7#[repr(C)]
8#[derive(Debug)]
9pub struct List {
10    pub counter: usize,
11    pub former: *mut Entry,
12    pub latter: *mut Entry,
13}
14
15impl Default for List {
16    fn default() -> List {
17        List {
18            counter: 0,
19            former: core::ptr::null_mut(),
20            latter: core::ptr::null_mut(),
21        }
22    }
23}
24
25use crate::target::arch::{Pointer, PointerType};
26
27impl List {
28    #[rustfmt::skip]
29    pub fn from_pointer(environment_pointer: Pointer) -> (List, Pointer) {
30        let environment_pointer: *mut PointerType = environment_pointer.0 as *mut PointerType;
31
32        let mut counter = 0;
33        unsafe {
34            while !(*environment_pointer.add(counter)).is_null() {
35                counter += 1;
36            }
37        }
38
39        let auxiliary_pointer = unsafe { (environment_pointer as PointerType).add(1 + counter) };
40
41        if counter == 0 {
42            return (List::default(), Pointer(auxiliary_pointer));
43        }
44
45        use crate::memory::heap::Allocating;
46        let list_pointer = Entry::allocate(counter);
47
48        unsafe {
49            // preenche cada Entry in-place
50            for a in 0..counter {
51                let entry_pointer = *(environment_pointer.add(a));
52                let entry = Entry::from_pointer(Pointer(entry_pointer));
53                core::ptr::write(list_pointer.add(a), entry);
54            }
55            // liga prev/next
56            for a in 0..counter {
57                let entry = list_pointer.add(a);
58                (*entry).prev = if a == 0 { core::ptr::null_mut() } else { list_pointer.add(a - 1) };
59                (*entry).next = if a + 1 == counter { core::ptr::null_mut() } else { list_pointer.add(a + 1) };
60            }
61        }
62
63        let list = List {
64            counter,
65            former: list_pointer,
66            latter: unsafe { list_pointer.add(counter - 1) },
67        };
68
69        (list, Pointer(auxiliary_pointer))
70    }
71
72    pub fn print(&self) {
73        info!("Environment {{\n");
74        for a in 0..self.counter {
75            if let Some(e) = self.get(a) {
76                info!(
77                    "\t{:?} @ {:?}\n",
78                    unsafe { Pointer(self.former.add(a) as PointerType) },
79                    e
80                );
81            }
82        }
83        info!("}} Environment \n");
84    }
85
86    pub fn print_arguments(&self) {
87        info!("Environment count: {}\n", self.counter);
88        for a in 0..self.counter {
89            if let Some(entry) = self.get(a) {
90                // Assumindo Entry tem campo `value: *PointerType` ou similar; ajustar conforme Entry real.
91                // unsafe {
92                // se Entry tiver método para converter a string, use-o aqui
93                info!("Arg {}: '{:?}'\n", a, entry.pointer);
94                // }
95            }
96        }
97    }
98
99    pub fn get(&self, index: usize) -> Option<&Entry> {
100        if index >= self.counter || self.former.is_null() {
101            return None;
102        }
103        unsafe { Some(&*self.former.add(index)) }
104    }
105
106    pub fn get_mut(&mut self, index: usize) -> Option<&mut Entry> {
107        if index >= self.counter || self.former.is_null() {
108            return None;
109        }
110        unsafe { Some(&mut *self.former.add(index)) }
111    }
112
113    pub fn len(&self) -> usize {
114        self.counter
115    }
116
117    pub fn is_empty(&self) -> bool {
118        self.counter == 0
119    }
120}
121
122pub struct Iter<'l> {
123    list: &'l List,
124    index: usize,
125}
126
127impl Drop for List {
128    fn drop(&mut self) {
129        if !self.former.is_null() && self.counter > 0 {
130            unsafe {
131                // primeiro dropar cada Entry in-place (isso chama Drop de Entry, se houver)
132                for a in 0..self.counter {
133                    let entry_ptr = self.former.add(a);
134                    core::ptr::drop_in_place(entry_ptr);
135                }
136
137                // desaloca o bloco que foi alocado por alloc
138                let total_size = core::mem::size_of::<Entry>() * self.counter as usize;
139                let aligned_size =
140                    (total_size + crate::memory::page::SIZE - 1) & !(crate::memory::page::SIZE - 1);
141
142                let _ = syscall::munmap(self.former as *mut u8, aligned_size);
143                // opcional: limpar para evitar double-drop
144                self.former = core::ptr::null_mut();
145                self.latter = core::ptr::null_mut();
146                self.counter = 0;
147            }
148        }
149    }
150}
151
152impl<'l> Iterator for Iter<'l> {
153    type Item = &'l Entry;
154
155    fn next(&mut self) -> Option<Self::Item> {
156        if self.index >= self.list.counter as usize {
157            return None;
158        }
159        let item = self.list.get(self.index);
160        self.index += 1;
161        item
162    }
163}
164
165// pub fn from_pointer(environment_pointer: Pointer) -> Self {
166
167//         info!("Environment count: {:?}\n\n", counter);
168
169//         if counter == 0 {
170//             return Self::default();
171//         }
172
173//         // Allocate memory using mmap
174//         let entries_ptr = unsafe {
175//             let size = core::mem::size_of::<Entry<'e>>() * counter;
176
177//             // Align size to page boundary
178//             let page_size = 4096;
179//             let aligned_size = (size + page_size - 1) & !(page_size - 1);
180
181//             // Define mmap constants locally since they're not accessible
182//             const PROT_READ: i32 = 0x1;
183//             const PROT_WRITE: i32 = 0x2;
184//             const MAP_PRIVATE: i32 = 0x02;
185//             const MAP_ANONYMOUS: i32 = 0x20;
186
187//             let result = memory::mmap::mmap(
188//                 ptr::null_mut(),
189//                 aligned_size,
190//                 PROT_READ | PROT_WRITE,
191//                 MAP_PRIVATE | MAP_ANONYMOUS,
192//                 -1,
193//                 0,
194//             );
195
196//             match result {
197//                 Ok(ptr) => ptr as *mut Entry<'e>,
198//                 Err(_) => {
199//                     // Allocation failed, return default vector
200//                     info!("Failed to allocate memory for environment vector\n");
201//                     return Self::default();
202//                 }
203//             }
204//         };
205
206//         // Create entries from the environment pointers
207//         for i in 0..counter {
208//             unsafe {
209//                 let env_ptr = environment_pointer.add(i);
210//                 let entry = Entry::from_pointer(env_ptr, i);
211//                 ptr::write(entries_ptr.add(i), entry);
212//                 // info!("Env {}: {:?}\n", i, (*entries_ptr.add(i)).value);
213//             }
214//         }
215
216//         // Move past the environment array and the NULL terminator
217//         let next_pointer = unsafe { environment_pointer.add(counter + 1) };
218
219//         let environment = Self {
220//             counter,
221//             entries: entries_ptr,
222//         };
223
224//         environment
225//     }