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