From 89cca032655659b769ac28512e3717a01ba51ed2 Mon Sep 17 00:00:00 2001 From: Rafal Mielniczuk Date: Sun, 12 Nov 2023 22:21:03 +0000 Subject: [PATCH] Improve shebang line handling Add libffi/libexpat ports --- cykusz-rs/src/kernel/task/mod.rs | 20 +++++----- cykusz-rs/src/kernel/task/vm.rs | 29 +++++++++++--- sysroot/build.sh | 65 ++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 16 deletions(-) diff --git a/cykusz-rs/src/kernel/task/mod.rs b/cykusz-rs/src/kernel/task/mod.rs index 1971eaad..d26894d5 100644 --- a/cykusz-rs/src/kernel/task/mod.rs +++ b/cykusz-rs/src/kernel/task/mod.rs @@ -188,25 +188,25 @@ impl Task { pub fn exec( &self, mut exe: DirEntryItem, - mut args: Option, + args: Option, envs: Option, ) -> Result { logln5!("exec task {} {}", self.pid(), exe.full_path()); + let mut args = args.unwrap_or(ExeArgs::new()); + let vm = VM::new(); let (base_addr, entry, elf_hdr, tls_vm, interpreter) = vm.load_bin(exe.clone()).ok_or(SyscallError::EINVAL)?; - if let Some(interp) = interpreter { + if let Some((interp, additional_args)) = interpreter { // got a shebang interpreter line?? replace exe and pass script as a first param - if let Some(args) = &mut args { - args.push_front(Box::from(exe.full_path().as_bytes())) - } else { - args = { - let mut a = ExeArgs::new(); - a.push_back(Box::from(exe.full_path().as_bytes())); - Some(a) + args.push_front(Box::from(exe.full_path().as_bytes())); + + if let Some(aa) = additional_args { + for (idx, a) in aa.iter().enumerate() { + args.insert(idx + 1, a.clone()); } } exe = interp; @@ -235,7 +235,7 @@ impl Task { self.vm(), tls_vm, exe.full_path(), - args, + Some(args), envs, ) } diff --git a/cykusz-rs/src/kernel/task/vm.rs b/cykusz-rs/src/kernel/task/vm.rs index 81d40e49..4693d91e 100644 --- a/cykusz-rs/src/kernel/task/vm.rs +++ b/cykusz-rs/src/kernel/task/vm.rs @@ -1,9 +1,12 @@ +use alloc::boxed::Box; use alloc::collections::linked_list::CursorMut; use alloc::collections::LinkedList; +use alloc::vec::Vec; use core::ops::Range; use syscall_defs::{MMapFlags, MMapProt}; +use syscall_defs::exec::ExeArgs; use crate::arch::mm::{MMAP_USER_ADDR, PAGE_SIZE}; use crate::arch::raw::mm::UserAddr; @@ -681,7 +684,7 @@ impl VMData { VirtAddr, ElfHeader, Option, - Option, + Option<(DirEntryItem, Option)>, )> { let mut base_addr = VirtAddr(0); @@ -704,14 +707,28 @@ impl VMData { .find(|(_, &e)| e == b'\n') .and_then(|(idx, _)| Some(&data[2..idx]))?; - let path = core::str::from_utf8(interp).ok()?; - logln5!("got interp line {}", path); + let path = core::str::from_utf8(interp).ok()?.split_whitespace().collect::>(); - let interp = lookup_by_path(&Path::new(path), LookupMode::None).ok()?; + if path.is_empty() { + return None; + } + logln5!("got interp line {}", path[0]); + + let interp = lookup_by_path(&Path::new(path[0]), LookupMode::None).ok()?; let (base_addr, entry, elf, tls, _) = self.load_bin(interp.clone())?; - return Some((base_addr, entry, elf, tls, Some(interp))); + let exe_args = if path.len() > 1 { + let mut ea = ExeArgs::new(); + for p in &path[1..] { + ea.push_back(Box::from(p.as_bytes())) + } + Some(ea) + } else { + None + }; + + return Some((base_addr, entry, elf, tls, Some((interp, exe_args)))); } let hdr = hdr.unwrap(); @@ -973,7 +990,7 @@ impl VM { VirtAddr, ElfHeader, Option, - Option, + Option<(DirEntryItem, Option)>, )> { self.data.lock().load_bin(exe) } diff --git a/sysroot/build.sh b/sysroot/build.sh index baa302f7..f3c5b01c 100755 --- a/sysroot/build.sh +++ b/sysroot/build.sh @@ -32,6 +32,8 @@ PCRE2_SRC_DIR=$SRC_DIR/pcre2 LIBUNISTRING_SRC_DIR=$SRC_DIR/libunistring LIBICONV_SRC_DIR=$SRC_DIR/libiconv LIBIDN2_SRC_DIR=$SRC_DIR/libidn2 +LIBFFI_SRC_DIR=$SRC_DIR/libffi +LIBEXPAT_SRC_DIR=$SRC_DIR/libexpat BUILD_DIR=$CYKUSZ_DIR/sysroot/build BINUTILS_BUILD_DIR=$BUILD_DIR/binutils-gdb @@ -55,6 +57,8 @@ PCRE2_CYKUSZ_BUILD_DIR=$BUILD_DIR/cykusz-pcre2 LIBUNISTRING_CYKUSZ_BUILD_DIR=$BUILD_DIR/cykusz-libunistring LIBICONV_CYKUSZ_BUILD_DIR=$BUILD_DIR/cykusz-libiconv LIBIDN2_CYKUSZ_BUILD_DIR=$BUILD_DIR/cykusz-libidn2 +LIBFFI_CYKUSZ_BUILD_DIR=$BUILD_DIR/cykusz-libffi +LIBEXPAT_CYKUSZ_BUILD_DIR=$BUILD_DIR/cykusz-libexpat GCC_BUILD_DIR=$BUILD_DIR/gcc MLIBC_BUILD_DIR=$BUILD_DIR/mlibc @@ -179,6 +183,31 @@ function _prepare_libunistring { fi } +function _prepare_libffi { + if [ ! -d $LIBFFI_SRC_DIR ]; then + mkdir -p $SRC_DIR + git clone --depth 1 -b cykusz https://github.com/rafalmiel/libffi.git $LIBFFI_SRC_DIR + + pushd . + cd $LIBFFI_SRC_DIR + ./autogen.sh + popd + fi +} + +function _prepare_libexpat { + if [ ! -d $LIBEXPAT_SRC_DIR ]; then + mkdir -p $SRC_DIR + git clone --depth 1 -b cykusz https://github.com/rafalmiel/libexpat.git $LIBFFI_SRC_DIR + + pushd . + cd $LIBEXPAT_SRC_DIR/expat + ./buildconf.sh + cp config.sub.cykusz conftools/config.sub + popd + fi +} + function _prepare_libiconv { if [ ! -d $LIBICONV_SRC_DIR ]; then mkdir -p $SRC_DIR @@ -655,6 +684,40 @@ function _cykusz_libunistring { popd } +function _cykusz_libffi { + _prepare_libffi + + mkdir -p $LIBFFI_CYKUSZ_BUILD_DIR + + pushd . + + cd $LIBFFI_CYKUSZ_BUILD_DIR + + CFLAGS="-fPIC" $LIBFFI_SRC_DIR/configure --host=$TRIPLE --prefix=/usr --with-sysroot=$SYSROOT --disable-static + + make DESTDIR=$SYSROOT -j4 + make DESTDIR=$SYSROOT install + + popd +} + +function _cykusz_libexpat { + _prepare_libexpat + + mkdir -p $LIBEXPAT_CYKUSZ_BUILD_DIR + + pushd . + + cd $LIBEXPAT_CYKUSZ_BUILD_DIR + + $LIBEXPAT_SRC_DIR/expat/configure --host=$TRIPLE --prefix=/usr --with-sysroot=$SYSROOT --without-xmlwf + + make DESTDIR=$SYSROOT -j4 + make DESTDIR=$SYSROOT install + + popd +} + function _cykusz_libiconv { _prepare_libiconv @@ -824,6 +887,8 @@ function _cykusz_python { make -j6 DESTDIR=$SYSROOT make DESTDIR=$SYSROOT install + ln -sf python3 $SYSROOT/usr/bin/python + popd }