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// }