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 use crate::memory::heap::Allocating;
34 let list_pointer = Entry::allocate(counter);
35
36 unsafe {
37 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 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 crate::info!("Arg {}: '{:?}'\n", a, entry.pointer);
86 }
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 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 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 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}