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