Skip to content

Commit 5f9c6bb

Browse files
vm: handle the case of shebang
Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 4ea02df commit 5f9c6bb

File tree

4 files changed

+52
-9
lines changed

4 files changed

+52
-9
lines changed

base-files/shebang_test.sh

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/aero_kernel/src/arch/x86_64/task.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,9 @@ impl ArchTask {
255255
AddressSpace::new()?
256256
};
257257

258-
let loaded_binary = vm.load_bin(executable).expect("exec: failed to load ELF");
258+
let loaded_binary = vm
259+
.load_bin(executable, argv, envv)
260+
.expect("exec: failed to load ELF");
259261

260262
// a kernel task can only execute a user executable
261263
self.user = true;
@@ -289,8 +291,13 @@ impl ArchTask {
289291
let mut envp = Vec::new();
290292
let mut argp = Vec::new();
291293

292-
envv.map(|envv| envp = envv.push_into_stack(&mut stack));
293-
argv.map(|argv| argp = argv.push_into_stack(&mut stack));
294+
loaded_binary
295+
.envv
296+
.map(|envv| envp = envv.push_into_stack(&mut stack));
297+
298+
loaded_binary
299+
.argv
300+
.map(|argv| argp = argv.push_into_stack(&mut stack));
294301

295302
stack.align_down();
296303

src/aero_kernel/src/syscall/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,22 @@ pub use time::*;
9393

9494
use crate::utils::StackHelper;
9595

96+
#[derive(Default)]
9697
pub struct ExecArgs {
97-
inner: Vec<Box<[u8]>>,
98+
pub inner: Vec<Box<[u8]>>,
9899
}
99100

100101
impl ExecArgs {
102+
pub fn push(&mut self, arg: &[u8]) {
103+
self.inner.push(arg.into());
104+
}
105+
106+
pub fn extend(&mut self, args: &[Box<[u8]>]) {
107+
for arg in args {
108+
self.push(arg);
109+
}
110+
}
111+
101112
pub fn push_into_stack(&self, stack: &mut StackHelper) -> Vec<u64> {
102113
let mut tops = Vec::with_capacity(self.inner.len());
103114

@@ -124,6 +135,7 @@ pub fn exec_args_from_slice(args: usize, size: usize) -> ExecArgs {
124135
let data = args as *const [usize; 2];
125136
let slice = unsafe { core::slice::from_raw_parts(data, size) };
126137

138+
// todo(andy): use `with_capacity` to avoid reallocation.
127139
let mut result = Vec::new();
128140

129141
for inner in slice {

src/aero_kernel/src/userland/vm.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use crate::mem;
4040
use crate::mem::paging::*;
4141
use crate::mem::AddressSpace;
4242

43+
use crate::syscall::ExecArgs;
4344
use crate::utils::sync::Mutex;
4445

4546
const ELF_HEADER_MAGIC: [u8; 4] = [0x7f, b'E', b'L', b'F'];
@@ -321,6 +322,9 @@ pub struct LoadedBinary<'header> {
321322

322323
pub entry_point: VirtAddr,
323324
pub base_addr: VirtAddr,
325+
326+
pub argv: Option<ExecArgs>,
327+
pub envv: Option<ExecArgs>,
324328
}
325329

326330
#[derive(Clone)]
@@ -874,6 +878,8 @@ impl VmProtected {
874878
fn load_bin<'header>(
875879
&mut self,
876880
bin: DirCacheItem,
881+
argv: Option<ExecArgs>,
882+
envv: Option<ExecArgs>,
877883
) -> Result<LoadedBinary<'header>, ElfLoadError> {
878884
// check for a shebang before proceeding.
879885
if let Some(shebang) = parse_shebang(bin.clone())? {
@@ -883,7 +889,18 @@ impl VmProtected {
883889
shebang.argument
884890
);
885891

886-
unimplemented!()
892+
let mut largv = ExecArgs::default();
893+
894+
largv.push(shebang.interpreter.absolute_path_str().as_bytes());
895+
896+
if !shebang.argument.is_empty() {
897+
largv.push(shebang.argument.as_bytes());
898+
}
899+
900+
largv.push(bin.absolute_path_str().as_bytes());
901+
argv.map(|argv| largv.extend(&argv.inner[1..]));
902+
903+
return self.load_bin(shebang.interpreter, Some(largv), envv);
887904
}
888905

889906
let elf = Elf::new(bin.clone())?;
@@ -1000,7 +1017,7 @@ impl VmProtected {
10001017
} else if header_type == xmas_elf::program::Type::Interp {
10011018
let ld = fs::lookup_path(fs::Path::new("/usr/lib/ld.so")).unwrap();
10021019

1003-
let res = self.load_bin(ld)?;
1020+
let res = self.load_bin(ld, None, None)?;
10041021
entry_point = res.entry_point;
10051022
}
10061023
}
@@ -1010,6 +1027,9 @@ impl VmProtected {
10101027
entry_point,
10111028

10121029
base_addr,
1030+
1031+
argv,
1032+
envv,
10131033
})
10141034
}
10151035

@@ -1107,8 +1127,13 @@ impl Vm {
11071127
}
11081128

11091129
/// Mapping the provided `bin` file into the VM.
1110-
pub fn load_bin(&self, bin: DirCacheItem) -> Result<LoadedBinary, ElfLoadError> {
1111-
self.inner.lock().load_bin(bin)
1130+
pub fn load_bin(
1131+
&self,
1132+
bin: DirCacheItem,
1133+
argv: Option<ExecArgs>,
1134+
envv: Option<ExecArgs>,
1135+
) -> Result<LoadedBinary, ElfLoadError> {
1136+
self.inner.lock().load_bin(bin, argv, envv)
11121137
}
11131138

11141139
/// Clears and unmaps all of the mappings in the VM.

0 commit comments

Comments
 (0)