Prechádzať zdrojové kódy

Remove dependency on errno in ld.so

During early parts of ld.so, errno and other thread local variables are
not yet initialized so we cannot use function (such as unistd::access)
that depends on such thread local variables (errno). For this reason
this patch creates small wrapper around the syscall that doesn't not
touch the errno
oddcoder 4 rokov pred
rodič
commit
3aacc160a1
2 zmenil súbory, kde vykonal 15 pridanie a 3 odobranie
  1. 4 1
      src/ld_so/linker.rs
  2. 11 2
      src/ld_so/mod.rs

+ 4 - 1
src/ld_so/linker.rs

@@ -29,6 +29,7 @@ use super::{
     debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug},
     debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug},
     tcb::{Master, Tcb},
     tcb::{Master, Tcb},
     PAGE_SIZE,
     PAGE_SIZE,
+    access,
 };
 };
 
 
 #[cfg(target_os = "redox")]
 #[cfg(target_os = "redox")]
@@ -169,7 +170,9 @@ impl Linker {
                     })?;
                     })?;
 
 
                     // TODO: Use R_OK | X_OK
                     // TODO: Use R_OK | X_OK
-                    unistd::access(path_c.as_ptr(), unistd::F_OK) == 0
+                    // We cannot use unix stdlib because errno is thead local variable
+                    // and fs:[0] is not set yet.
+                    access(path_c.as_ptr(), unistd::F_OK) == 0
                 };
                 };
 
 
                 if access {
                 if access {

+ 11 - 2
src/ld_so/mod.rs

@@ -1,8 +1,11 @@
 use goblin::elf::program_header::{self, program_header32, program_header64, ProgramHeader};
 use goblin::elf::program_header::{self, program_header32, program_header64, ProgramHeader};
 
 
 use self::tcb::{Master, Tcb};
 use self::tcb::{Master, Tcb};
-use crate::start::Stack;
-
+use crate::{
+start::Stack,
+c_str::CStr,
+platform::types::*
+};
 pub const PAGE_SIZE: usize = 4096;
 pub const PAGE_SIZE: usize = 4096;
 
 
 pub mod debug;
 pub mod debug;
@@ -80,6 +83,12 @@ pub fn static_init(sp: &'static Stack) {
     }
     }
 }
 }
 
 
+// Wrapper over the systemcall, Do not use outside of ld_so
+pub unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
+        let path = CStr::from_ptr(path);
+        syscall!(ACCESS, (path).as_ptr(), mode) as c_int
+}
+
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "linux")]
 pub unsafe fn init(sp: &'static Stack) {
 pub unsafe fn init(sp: &'static Stack) {
     let mut tp = 0usize;
     let mut tp = 0usize;