userspace/memory/stack/
arguments.rs

1pub mod entry;
2pub use entry::*;
3
4#[repr(C)]
5#[derive(Debug)]
6pub struct List {
7    pub counter: usize,
8    pub former: *mut Entry,
9    pub latter: *mut Entry,
10}
11
12impl Default for List {
13    fn default() -> List {
14        List {
15            counter: 0,
16            former: core::ptr::null_mut(),
17            latter: core::ptr::null_mut(),
18        }
19    }
20}
21
22impl List {
23    #[rustfmt::skip]
24    pub fn from_pointer(stack_pointer: crate::target::arch::Pointer) -> (List, crate::target::arch::Pointer) {
25        let counter = unsafe { *(stack_pointer.0) } as usize;
26        let argument_pointers = unsafe { (stack_pointer.0).add(1) as *const crate::target::arch::PointerType };
27        let environment_pointer = unsafe { (stack_pointer.0).add(2 + counter) };
28
29        if counter == 0 {
30            return (List::default(), crate::target::arch::Pointer(environment_pointer));
31        }
32
33        let list_pointer = crate::memory::alloc::<Entry>(counter);
34
35        unsafe {
36            // preenche cada Entry in-place
37            for a in 0..counter {
38                let entry_pointer = *(argument_pointers.add(a));
39                let entry = Entry::from_pointer(crate::target::arch::Pointer(entry_pointer));
40                core::ptr::write(list_pointer.add(a), entry);
41            }
42            // liga prev/next
43            for a in 0..counter {
44                let entry = list_pointer.add(a);
45                (*entry).prev = if a == 0 { core::ptr::null_mut() } else { list_pointer.add(a - 1) };
46                (*entry).next = if a + 1 == counter { core::ptr::null_mut() } else { list_pointer.add(a + 1) };
47            }
48        }
49
50        let list = List {
51            counter,
52            former: list_pointer,
53            latter: unsafe { list_pointer.add(counter - 1) },
54        };
55
56        (list, crate::target::arch::Pointer(environment_pointer))
57    }
58
59    pub fn print(&self) {
60        crate::info!("Arguments {{\n");
61        for a in 0..self.counter {
62            if let Some(e) = self.get(a) {
63                crate::info!(
64                    "\t{:?} @ {:?}\n",
65                    unsafe {
66                        crate::target::arch::Pointer(
67                            self.former.add(a) as crate::target::arch::PointerType
68                        )
69                    },
70                    e
71                );
72            }
73        }
74        crate::info!("}} Arguments \n");
75    }
76
77    pub fn print_arguments(&self) {
78        crate::info!("Argument count: {}\n", self.counter);
79        for a in 0..self.counter {
80            if let Some(entry) = self.get(a) {
81                // Assumindo Entry tem campo `value: *crate::target::arch::PointerType` ou similar; ajustar conforme Entry real.
82                // unsafe {
83                // se Entry tiver método para converter a string, use-o aqui
84                crate::info!("Arg {}: '{:?}'\n", a, entry.pointer);
85                // }
86            }
87        }
88    }
89
90    pub fn get(&self, index: usize) -> Option<&Entry> {
91        if index >= self.counter || self.former.is_null() {
92            return None;
93        }
94        unsafe { Some(&*self.former.add(index)) }
95    }
96
97    pub fn get_mut(&mut self, index: usize) -> Option<&mut Entry> {
98        if index >= self.counter || self.former.is_null() {
99            return None;
100        }
101        unsafe { Some(&mut *self.former.add(index)) }
102    }
103
104    pub fn len(&self) -> usize {
105        self.counter
106    }
107
108    pub fn is_empty(&self) -> bool {
109        self.counter == 0
110    }
111}
112
113pub struct Iter<'l> {
114    list: &'l List,
115    index: usize,
116}
117
118impl Drop for List {
119    fn drop(&mut self) {
120        if !self.former.is_null() && self.counter > 0 {
121            unsafe {
122                // primeiro dropar cada Entry in-place (isso chama Drop de Entry, se houver)
123                for a in 0..self.counter {
124                    let entry_ptr = self.former.add(a);
125                    core::ptr::drop_in_place(entry_ptr);
126                }
127
128                // desaloca o bloco que foi alocado por alloc
129                let total_size = core::mem::size_of::<Entry>() * self.counter as usize;
130                let aligned_size =
131                    (total_size + crate::memory::page::SIZE - 1) & !(crate::memory::page::SIZE - 1);
132
133                let _ = crate::target::os::syscall::munmap(self.former as *mut u8, aligned_size);
134                // opcional: limpar para evitar double-drop
135                self.former = core::ptr::null_mut();
136                self.latter = core::ptr::null_mut();
137                self.counter = 0;
138            }
139        }
140    }
141}
142
143impl<'l> Iterator for Iter<'l> {
144    type Item = &'l Entry;
145
146    fn next(&mut self) -> Option<Self::Item> {
147        if self.index >= self.list.counter as usize {
148            return None;
149        }
150        let item = self.list.get(self.index);
151        self.index += 1;
152        item
153    }
154}