|
@@ -21,16 +21,16 @@ use crate::{
|
|
|
c_str::CString,
|
|
|
fs::File,
|
|
|
header::{fcntl, sys_mman, unistd},
|
|
|
- io::{self, Read},
|
|
|
+ io::Read,
|
|
|
platform::types::c_void,
|
|
|
};
|
|
|
|
|
|
use super::{
|
|
|
+ access::access,
|
|
|
debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug},
|
|
|
tcb::{Master, Tcb},
|
|
|
PAGE_SIZE,
|
|
|
};
|
|
|
-
|
|
|
#[cfg(target_os = "redox")]
|
|
|
const PATH_SEP: char = ';';
|
|
|
|
|
@@ -94,54 +94,41 @@ impl Linker {
|
|
|
}
|
|
|
|
|
|
pub fn load(&mut self, name: &str, path: &str) -> Result<()> {
|
|
|
- self.dep_tree = self.load_recursive(name, path)?
|
|
|
- .ok_or(Error::Malformed(format!(
|
|
|
- "failed to find '{}'",
|
|
|
- path
|
|
|
- )))?;
|
|
|
+ self.dep_tree = self.load_recursive(name, path)?;
|
|
|
if self.verbose {
|
|
|
println!("Dep tree: {:#?}", self.dep_tree);
|
|
|
}
|
|
|
return Ok(());
|
|
|
}
|
|
|
|
|
|
- fn load_recursive(&mut self, name: &str, path: &str) -> Result<Option<DepTree>> {
|
|
|
+ fn load_recursive(&mut self, name: &str, path: &str) -> Result<DepTree> {
|
|
|
if self.verbose {
|
|
|
println!("load {}: {}", name, path);
|
|
|
}
|
|
|
+ if self.cir_dep.contains(name) {
|
|
|
+ return Err(Error::Malformed(format!(
|
|
|
+ "Circular dependency: {} is a dependency of itself",
|
|
|
+ name
|
|
|
+ )));
|
|
|
+ }
|
|
|
|
|
|
+ let mut deps = DepTree::new(name.to_string());
|
|
|
+ let mut data = Vec::new();
|
|
|
+ self.cir_dep.insert(name.to_string());
|
|
|
let path_c = CString::new(path)
|
|
|
.map_err(|err| Error::Malformed(format!("invalid path '{}': {}", path, err)))?;
|
|
|
|
|
|
- let mut data = Vec::new();
|
|
|
{
|
|
|
let flags = fcntl::O_RDONLY | fcntl::O_CLOEXEC;
|
|
|
- let mut file = match File::open(&path_c, flags) {
|
|
|
- Ok(ok) => ok,
|
|
|
- Err(err) => match err.kind() {
|
|
|
- io::ErrorKind::NotFound => return Ok(None),
|
|
|
- _ => return Err(Error::Malformed(format!("failed to open '{}': {}", path, err)))
|
|
|
- }
|
|
|
- };
|
|
|
+ let mut file = File::open(&path_c, flags)
|
|
|
+ .map_err(|err| Error::Malformed(format!("failed to open '{}': {}", path, err)))?;
|
|
|
|
|
|
file.read_to_end(&mut data)
|
|
|
.map_err(|err| Error::Malformed(format!("failed to read '{}': {}", path, err)))?;
|
|
|
}
|
|
|
-
|
|
|
- if self.cir_dep.contains(name) {
|
|
|
- return Err(Error::Malformed(format!(
|
|
|
- "Circular dependency: {} is a dependency of itself",
|
|
|
- name
|
|
|
- )));
|
|
|
- }
|
|
|
- self.cir_dep.insert(name.to_string());
|
|
|
-
|
|
|
- let mut deps = DepTree::new(name.to_string());
|
|
|
deps.deps = self.load_data(name, data.into_boxed_slice())?;
|
|
|
-
|
|
|
self.cir_dep.remove(name);
|
|
|
-
|
|
|
- Ok(Some(deps))
|
|
|
+ Ok(deps)
|
|
|
}
|
|
|
|
|
|
pub fn load_data(&mut self, name: &str, data: Box<[u8]>) -> Result<Vec<DepTree>> {
|
|
@@ -164,12 +151,7 @@ impl Linker {
|
|
|
// It should be previously resolved so we don't need to worry about it
|
|
|
Ok(None)
|
|
|
} else if name.contains('/') {
|
|
|
- Ok(Some(self.load_recursive(name, name)?
|
|
|
- .ok_or(Error::Malformed(format!(
|
|
|
- "failed to find '{}'",
|
|
|
- name
|
|
|
- )))?
|
|
|
- ))
|
|
|
+ Ok(Some(self.load_recursive(name, name)?))
|
|
|
} else {
|
|
|
let library_path = self.library_path.clone();
|
|
|
for part in library_path.split(PATH_SEP) {
|
|
@@ -181,8 +163,19 @@ impl Linker {
|
|
|
if self.verbose {
|
|
|
println!("check {}", path);
|
|
|
}
|
|
|
- if let Some(deps) = self.load_recursive(name, &path)? {
|
|
|
- return Ok(Some(deps));
|
|
|
+ let access = unsafe {
|
|
|
+ let path_c = CString::new(path.as_bytes()).map_err(|err| {
|
|
|
+ Error::Malformed(format!("invalid path '{}': {}", path, err))
|
|
|
+ })?;
|
|
|
+
|
|
|
+ // TODO: Use R_OK | X_OK
|
|
|
+ // 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 {
|
|
|
+ return Ok(Some(self.load_recursive(name, &path)?));
|
|
|
}
|
|
|
}
|
|
|
|