1use core::mem::size_of;
3use core::ptr;
4
5use alloc::vec::Vec;
6use riscv::register::sstatus;
7
8use crate::arch::constant::STACK_ALIGN_MASK;
9
10pub fn setup_stack_layout(
13 sp: usize,
14 argv: &[&str],
15 envp: &[&str],
16 phdr_addr: usize,
17 phnum: usize,
18 phent: usize,
19 entry_point: usize,
20) -> (usize, usize, usize, usize) {
21 let mut sp = sp;
22 let mut arg_ptrs: Vec<usize> = Vec::with_capacity(argv.len());
23 let mut env_ptrs: Vec<usize> = Vec::with_capacity(envp.len());
24 unsafe {
25 sstatus::set_sum();
26 }
27
28 for &env in envp.iter().rev() {
29 let bytes = env.as_bytes();
30 sp -= bytes.len() + 1; unsafe {
32 ptr::copy_nonoverlapping(bytes.as_ptr(), sp as *mut u8, bytes.len());
33 (sp as *mut u8).add(bytes.len()).write(0); }
35 env_ptrs.push(sp); }
37
38 for &arg in argv.iter().rev() {
40 let bytes = arg.as_bytes();
41 sp -= bytes.len() + 1; unsafe {
43 ptr::copy_nonoverlapping(bytes.as_ptr(), sp as *mut u8, bytes.len());
44 (sp as *mut u8).add(bytes.len()).write(0); }
46 arg_ptrs.push(sp); }
48
49 sp &= !(size_of::<usize>() - 1);
51
52 let random_bytes = [
59 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45,
60 0x67,
61 ];
62 let random_ptr = sp - 16;
63 unsafe { ptr::copy_nonoverlapping(random_bytes.as_ptr(), random_ptr as *mut u8, 16) };
64 sp = random_ptr;
65
66 let platform = "riscv64\0";
68 let platform_len = platform.len();
69 sp -= platform_len;
70 unsafe { ptr::copy_nonoverlapping(platform.as_ptr(), sp as *mut u8, platform_len) };
71 let platform_ptr = sp;
72
73 sp &= !(size_of::<usize>() * 2 - 1); let execfn = if !arg_ptrs.is_empty() { arg_ptrs[0] } else { 0 };
78
79 let auxv = [
80 (3, phdr_addr), (4, phent), (5, phnum), (6, 4096), (7, 0), (8, 0), (9, entry_point), (11, 0), (12, 0), (13, 0), (14, 0), (15, platform_ptr), (16, 0), (17, 100), (23, 0), (25, random_ptr), (31, execfn), (0, 0), ];
99
100 for (i, (k, v)) in auxv.iter().enumerate() {
102 crate::pr_debug!("auxv[{}]: type={}, val={:#x}", i, k, v);
103 }
104 crate::pr_debug!(
105 "setup_stack_layout: sp={:#x}, random_ptr={:#x}, phdr_addr={:#x}, entry={:#x}",
106 sp,
107 random_ptr,
108 phdr_addr,
109 entry_point
110 );
111
112 let total_size = auxv.len() * 2 * size_of::<usize>()
115 + size_of::<usize>() + env_ptrs.len() * size_of::<usize>()
117 + size_of::<usize>() + arg_ptrs.len() * size_of::<usize>()
119 + size_of::<usize>(); let sp_final = (sp - total_size) & !STACK_ALIGN_MASK;
123 sp = sp_final + total_size;
124
125 for (type_, val) in auxv.iter().rev() {
126 sp -= size_of::<usize>();
127 unsafe { ptr::write(sp as *mut usize, *val) };
128 sp -= size_of::<usize>();
129 unsafe { ptr::write(sp as *mut usize, *type_) };
130 }
131
132 sp -= size_of::<usize>();
134 unsafe {
135 ptr::write(sp as *mut usize, 0);
136 }
137
138 for &p in env_ptrs.iter() {
141 sp -= size_of::<usize>();
142 unsafe {
143 ptr::write(sp as *mut usize, p);
144 }
145 }
146 let envp_vec_ptr = sp; sp -= size_of::<usize>();
150 unsafe {
151 ptr::write(sp as *mut usize, 0);
152 }
153
154 for &p in arg_ptrs.iter() {
157 sp -= size_of::<usize>();
158 unsafe {
159 ptr::write(sp as *mut usize, p);
160 }
161 }
162 let argv_vec_ptr = sp; let argc = argv.len();
166 sp -= size_of::<usize>();
167 unsafe {
168 ptr::write(sp as *mut usize, argc);
169 }
170
171 unsafe {
173 sstatus::clear_sum();
174 }
175
176 (sp, argc, argv_vec_ptr, envp_vec_ptr)
179}