Browse Source

重构一下start部分,修复rust程序不能获取参数问题 (#26)

GnoCiYeH 1 year ago
parent
commit
2b0c8c1731

+ 2 - 2
dlibc/src/unix/ld_so/access.rs

@@ -5,7 +5,7 @@ use crate::unix::c_str::CString;
 #[cfg(target_os = "redox")]
 use crate::unix::header::unistd::{F_OK, R_OK, W_OK, X_OK};
 
-pub fn accessible(path: &str, mode: ::c_int) -> ::c_int {
+pub fn accessible(path: &str, mode: crate::c_int) -> crate::c_int {
     let path_c = CString::new(path.as_bytes()).unwrap(); /*.map_err(|err| {
                                                              Error::Malformed(format!("invalid path '{}': {}", path, err))
                                                          })?;*/
@@ -19,7 +19,7 @@ unsafe fn access(path: *const ::c_char, mode: ::c_int) -> ::c_int {
 }
 
 #[cfg(target_os = "dragonos")]
-unsafe fn access(_path: *const ::c_char, _mode: ::c_int) -> ::c_int {
+unsafe fn access(_path: *const crate::c_char, _mode: crate::c_int) -> crate::c_int {
     // let path = CStr::from_ptr(path);
     // syscall!(ACCESS, (path).as_ptr(), mode) as ::c_int
     return -1;

+ 9 - 9
dlibc/src/unix/ld_so/dso.rs

@@ -3,10 +3,17 @@ use super::{
     linker::Symbol,
     tcb::{round_up, Master},
 };
-use errno;
-use unix::header::errno::STR_ERROR;
+use crate::errno;
+use crate::unix::header::errno::STR_ERROR;
 
+use crate::mmap;
+use crate::munmap;
 use crate::trace;
+use crate::MAP_ANONYMOUS;
+use crate::MAP_FIXED_NOREPLACE;
+use crate::MAP_PRIVATE;
+use crate::PROT_READ;
+use crate::PROT_WRITE;
 use alloc::{
     collections::BTreeMap,
     string::{String, ToString},
@@ -36,13 +43,6 @@ use goblin::{
     elf::Elf,
     error::{Error, Result},
 };
-use mmap;
-use munmap;
-use MAP_ANONYMOUS;
-use MAP_FIXED_NOREPLACE;
-use MAP_PRIVATE;
-use PROT_READ;
-use PROT_WRITE;
 
 /// Use to represent a library as well as all the symbols that is loaded withen it.
 #[derive(Default)]

+ 6 - 6
dlibc/src/unix/ld_so/linker.rs

@@ -29,15 +29,15 @@ use super::{
     ExpectTlsFree, PATH_SEP,
 };
 
-use O_CLOEXEC;
-use O_RDONLY;
+use crate::O_CLOEXEC;
+use crate::O_RDONLY;
 
 use crate::trace;
-use PROT_EXEC;
+use crate::PROT_EXEC;
 
-use mprotect;
-use PROT_READ;
-use PROT_WRITE;
+use crate::mprotect;
+use crate::PROT_READ;
+use crate::PROT_WRITE;
 
 #[derive(Clone, Copy, Debug)]
 pub struct Symbol {

+ 1 - 1
dlibc/src/unix/ld_so/mod.rs

@@ -1,10 +1,10 @@
 use core::{mem, ptr};
 use goblin::elf::program_header::{self, program_header32, program_header64, ProgramHeader};
 
+use self::start::Stack;
 use self::tcb::{Master, Tcb};
 use crate::eprintln;
 use crate::unix::platform;
-use crate::unix::start::Stack;
 
 #[cfg(target_os = "redox")]
 pub const PATH_SEP: char = ';';

+ 33 - 8
dlibc/src/unix/ld_so/start.rs

@@ -8,30 +8,55 @@ use alloc::{
     vec::Vec,
 };
 
-use unix::platform::allocator::new_mspace;
+use crate::unix::platform::allocator::new_mspace;
 
 use super::platform;
 use crate::eprintln;
 use crate::println;
 
-use unix::{
+use crate::unix::{
     allocator::ALLOCATOR,
     c_str::CStr,
     header::unistd,
     platform::{get_auxv, get_auxvs},
-    start::Stack,
     sync::mutex::Mutex,
 };
 
 use super::{access::accessible, debug::_r_debug, linker::Linker, tcb::Tcb, PATH_SEP};
 use goblin::elf::header::header64::SIZEOF_EHDR;
 
+#[repr(C)]
+pub struct Stack {
+    pub argc: isize,
+    pub argv0: *const ::c_char,
+}
+
+impl Stack {
+    pub fn argv(&self) -> *const *const ::c_char {
+        &self.argv0 as *const _
+    }
+
+    pub fn envp(&self) -> *const *const ::c_char {
+        unsafe { self.argv().offset(self.argc + 1) }
+    }
+
+    pub fn auxv(&self) -> *const (usize, usize) {
+        unsafe {
+            let mut envp = self.envp();
+            while !(*envp).is_null() {
+                envp = envp.add(1);
+            }
+            envp.add(1) as *const (usize, usize)
+        }
+    }
+}
+
 unsafe fn get_argv(mut ptr: *const usize) -> (Vec<String>, *const usize) {
     //traverse the stack and collect argument vector
     let mut argv = Vec::new();
     while *ptr != 0 {
         let arg = *ptr;
-        match CStr::from_ptr(arg as *const ::c_char).to_str() {
+        match CStr::from_ptr(arg as *const crate::c_char).to_str() {
             Ok(arg_str) => argv.push(arg_str.to_owned()),
             _ => {
                 eprintln!("ld.so: failed to parse argv[{}]", argv.len());
@@ -49,7 +74,7 @@ unsafe fn get_env(mut ptr: *const usize) -> (BTreeMap<String, String>, *const us
     let mut envs = BTreeMap::new();
     while *ptr != 0 {
         let env = *ptr;
-        if let Ok(arg_str) = CStr::from_ptr(env as *const ::c_char).to_str() {
+        if let Ok(arg_str) = CStr::from_ptr(env as *const crate::c_char).to_str() {
             let mut parts = arg_str.splitn(2, '=');
             if let Some(key) = parts.next() {
                 if let Some(value) = parts.next() {
@@ -85,7 +110,7 @@ unsafe fn adjust_stack(sp: &'static mut Stack) {
         if arg == 0 {
             break;
         }
-        if let Ok(arg_str) = CStr::from_ptr(arg as *const ::c_char).to_str() {
+        if let Ok(arg_str) = CStr::from_ptr(arg as *const crate::c_char).to_str() {
             let mut parts = arg_str.splitn(2, '=');
             if let Some(key) = parts.next() {
                 if let Some(_value) = parts.next() {
@@ -179,7 +204,7 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
         platform::environ = platform::OUR_ENVIRON.as_mut_ptr();
     }
 
-    let is_manual = if let Some(img_entry) = get_auxv(&auxv, ::AT_ENTRY) {
+    let is_manual = if let Some(img_entry) = get_auxv(&auxv, crate::AT_ENTRY) {
         img_entry == ld_entry
     } else {
         true
@@ -228,7 +253,7 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
     let base_addr = {
         let mut base = None;
         if !is_manual && cfg!(not(target_os = "redox")) {
-            let phdr = get_auxv(&auxv, ::AT_PHDR).unwrap();
+            let phdr = get_auxv(&auxv, crate::AT_PHDR).unwrap();
             if phdr != 0 {
                 base = Some(phdr - SIZEOF_EHDR);
             }

+ 5 - 5
dlibc/src/unix/ld_so/tcb.rs

@@ -4,10 +4,10 @@ use goblin::error::{Error, Result};
 
 use crate::unix::platform;
 use crate::unix::{ld_so::linker::Linker, sync::mutex::Mutex};
-use MAP_ANONYMOUS;
-use MAP_PRIVATE;
-use PROT_READ;
-use PROT_WRITE;
+use crate::MAP_ANONYMOUS;
+use crate::MAP_PRIVATE;
+use crate::PROT_READ;
+use crate::PROT_WRITE;
 
 use crate::trace;
 
@@ -184,7 +184,7 @@ impl Tcb {
 
     /// Mapping with correct flags for TCB and TLS
     unsafe fn map(size: usize) -> Result<&'static mut [u8]> {
-        let ptr = ::mmap(
+        let ptr = crate::mmap(
             ptr::null_mut(),
             size,
             PROT_READ | PROT_WRITE,

+ 2 - 2
dlibc/src/unix/mod.rs

@@ -1612,11 +1612,11 @@ pub mod macros;
 
 pub mod c_str;
 pub mod c_vec;
-pub mod crt0;
+// pub mod crt0;
 pub mod fs;
 pub mod header;
 pub mod ld_so;
-pub mod start;
+// pub mod start;
 pub mod sync;
 
 mod io;

+ 0 - 0
dlibc/src/unix/crt0/mod.rs → src/crt0/mod.rs


+ 3 - 0
src/lib.rs

@@ -103,6 +103,9 @@ extern crate dlibc;
 pub mod std;
 pub use self::std::*;
 
+mod crt0;
+mod start;
+
 #[cfg(target_os = "dragonos")]
 pub use dlibc::{eprint, eprintln, print, println};
 

+ 23 - 49
dlibc/src/unix/start.rs → src/start.rs

@@ -1,50 +1,21 @@
-use crate::unix::{
-    allocator::ALLOCATOR,
-    header::libgen,
-    ld_so::{self, linker::Linker},
-    platform::{self, get_auxvs},
-    sync::mutex::Mutex,
-};
 use alloc::{boxed::Box, vec::Vec};
 use core::{fmt::Debug, intrinsics, ptr};
-use unix::platform::allocator::new_mspace;
-
-#[repr(C)]
-pub struct Stack {
-    pub argc: isize,
-    pub argv0: *const ::c_char,
-}
-
-impl Stack {
-    pub fn argv(&self) -> *const *const ::c_char {
-        &self.argv0 as *const _
-    }
-
-    pub fn envp(&self) -> *const *const ::c_char {
-        unsafe { self.argv().offset(self.argc + 1) }
-    }
-
-    pub fn auxv(&self) -> *const (usize, usize) {
-        unsafe {
-            let mut envp = self.envp();
-            while !(*envp).is_null() {
-                envp = envp.add(1);
-            }
-            envp.add(1) as *const (usize, usize)
-        }
-    }
-}
-
-impl Debug for Stack {
-    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        f.debug_struct("Stack")
-            .field("argc", &self.argc)
-            .field("argv0", &self.argv0)
-            .finish()
-    }
-}
+use dlibc::unix::platform::allocator::new_mspace;
+use dlibc::{
+    ld_so::start::Stack,
+    unix::{
+        allocator::ALLOCATOR,
+        header::libgen,
+        ld_so::{self, linker::Linker},
+        platform::{self, get_auxvs},
+        sync::mutex::Mutex,
+    },
+};
 
-unsafe fn copy_string_array(array: *const *const ::c_char, len: usize) -> Vec<*mut ::c_char> {
+unsafe fn copy_string_array(
+    array: *const *const dlibc::c_char,
+    len: usize,
+) -> Vec<*mut dlibc::c_char> {
     //println!("copy_string_array: array: {:p}, len: {}", array, len);
 
     let mut vec = Vec::with_capacity(len + 1);
@@ -56,7 +27,7 @@ unsafe fn copy_string_array(array: *const *const ::c_char, len: usize) -> Vec<*m
             len += 1;
         }
 
-        let buf = platform::alloc(len + 1) as *mut ::c_char;
+        let buf = platform::alloc(len + 1) as *mut dlibc::c_char;
         for i in 0..=len {
             *buf.add(i) = *item.add(i);
         }
@@ -82,7 +53,7 @@ static mut init_complete: bool = false;
 
 #[used]
 #[no_mangle]
-static mut __relibc_init_environ: *mut *mut ::c_char = ptr::null_mut();
+static mut __relibc_init_environ: *mut *mut dlibc::c_char = ptr::null_mut();
 
 fn alloc_init() {
     unsafe {
@@ -136,7 +107,7 @@ extern "C" fn init_array() {
     //     init_complete = true
     // }
 }
-use header::stdio;
+use dlibc::header::stdio;
 
 fn io_init() {
     unsafe {
@@ -220,7 +191,10 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
     // println!("to copy args");
     // Set up argc and argv
     let argc = sp.argc;
-    let argv = sp.argv();
+    let argv: *const *const i8 = sp.argv();
+
+    use crate::std::sys;
+    sys::args::init(argc, argv as *const *const u8);
 
     platform::inner_argv = copy_string_array(argv, argc as usize);
 
@@ -249,7 +223,7 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
     // println!("to get auxvs");
     let auxvs = get_auxvs(sp.auxv().cast());
     // println!("to init platform");
-    crate::unix::platform::init(auxvs);
+    dlibc::unix::platform::init(auxvs);
 
     // Setup signal stack, otherwise we cannot handle any signals besides SIG_IGN/SIG_DFL behavior.
     #[cfg(target_os = "redox")]

+ 1 - 1
src/std/mod.rs

@@ -159,7 +159,7 @@ pub mod task {
 //pub use std_detect::is_x86_feature_detected;
 
 // Platform-abstraction modules
-mod sys;
+pub(crate) mod sys;
 mod sys_common;
 
 pub mod alloc;

+ 1 - 1
src/std/sys/unix/process/process_unix.rs

@@ -158,7 +158,7 @@ impl Command {
             let mut bytes = [0; 8];
 
             // TODO: 在DragonOS管道读取数据时拿不到锁
-            return Ok((p, ours));
+            // return Ok((p, ours));
             // loop to handle EINTR
             loop {
                 match input.read(&mut bytes) {