userspace/memory/stack/
arguments.rs1pub 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 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 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 crate::info!("Arg {}: '{:?}'\n", a, entry.pointer);
85 }
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 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 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 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}