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