fix(dso): ensure all (r|run)paths are relative to sysroot
Also make sure we split them on colons.
This commit is contained in:
parent
f2fc705fa0
commit
6d06377154
12
src/args.rs
12
src/args.rs
|
@ -3,7 +3,10 @@
|
|||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{builder::{PathBufValueParser, TypedValueParser}, Parser};
|
||||
use clap::{
|
||||
Parser,
|
||||
builder::{PathBufValueParser, TypedValueParser},
|
||||
};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct AbsolutePathBufValueParser;
|
||||
|
@ -20,10 +23,8 @@ impl TypedValueParser for AbsolutePathBufValueParser {
|
|||
let pathbuf_parser = PathBufValueParser::new();
|
||||
let v = pathbuf_parser.parse_ref(cmd, arg, value)?;
|
||||
|
||||
v.canonicalize().map_err(|e| clap::Error::raw(
|
||||
clap::error::ErrorKind::Io,
|
||||
e,
|
||||
))
|
||||
v.canonicalize()
|
||||
.map_err(|e| clap::Error::raw(clap::error::ErrorKind::Io, e))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,4 +60,3 @@ pub struct Args {
|
|||
/// The location of the sysroot to clean up
|
||||
pub sysroot_location: PathBuf,
|
||||
}
|
||||
|
||||
|
|
|
@ -206,7 +206,12 @@ impl Runner {
|
|||
"regular file"
|
||||
};
|
||||
let size = Self::get_file_size(path)?;
|
||||
log::info!("(dry-run) would remove {} {} ({})", ty, path.display(), size);
|
||||
log::info!(
|
||||
"(dry-run) would remove {} {} ({})",
|
||||
ty,
|
||||
path.display(),
|
||||
size
|
||||
);
|
||||
Ok(size)
|
||||
})
|
||||
} else {
|
||||
|
@ -225,8 +230,8 @@ impl Runner {
|
|||
Err(err) => {
|
||||
log::error!("failed to get metadata from: {}, {}", file.display(), err);
|
||||
FileSize(0)
|
||||
},
|
||||
Ok(lstat) => FileSize(lstat.st_size as u64)
|
||||
}
|
||||
Ok(lstat) => FileSize(lstat.st_size as u64),
|
||||
};
|
||||
Ok(size)
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ impl State {
|
|||
}
|
||||
|
||||
let current_dir = std::env::current_dir()?;
|
||||
let mut dst_path = std::fs::read_link(path)?;
|
||||
let mut dst_path = fs::read_link(path)?;
|
||||
if dst_path.is_absolute() {
|
||||
dst_path = dst_path.strip_prefix("/")?.into();
|
||||
} else {
|
||||
|
@ -197,10 +197,12 @@ impl State {
|
|||
}
|
||||
|
||||
let search_paths = determine_lib_search_paths(path, elf)?;
|
||||
log::trace!("determined search paths {:#?}", search_paths);
|
||||
|
||||
'next_lib: for &library in elf.libraries.iter() {
|
||||
for lib_path in search_paths.iter() {
|
||||
let tentative_path = PathBuf::from(lib_path).strip_prefix("/")?.join(library);
|
||||
assert!(Path::new(&lib_path).is_relative());
|
||||
let tentative_path = PathBuf::from(lib_path).join(library);
|
||||
let dst = match nix::sys::stat::lstat(&tentative_path) {
|
||||
Ok(dst) => dst,
|
||||
Err(Errno::ENOENT) => continue,
|
||||
|
@ -219,7 +221,11 @@ impl State {
|
|||
continue 'next_lib;
|
||||
}
|
||||
|
||||
log::warn!("{}: unable to find library {}, ignoring (this might produce wrong results)!", path.display(), library);
|
||||
log::warn!(
|
||||
"{}: unable to find library {}, ignoring (this might produce wrong results)!",
|
||||
path.display(),
|
||||
library
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -257,7 +263,7 @@ impl State {
|
|||
{:?}
|
||||
}}"
|
||||
},
|
||||
petgraph::dot::Dot::with_attr_getters(
|
||||
dot::Dot::with_attr_getters(
|
||||
&self.graph,
|
||||
&[
|
||||
dot::Config::NodeNoLabel,
|
||||
|
@ -267,8 +273,12 @@ impl State {
|
|||
&|_, _| { String::new() },
|
||||
&|_, n| {
|
||||
let paths = self.paths_map.get(&n.id()).unwrap();
|
||||
let first_path = paths.iter().next().unwrap_or_else(|| panic!("dso: you have a path map with an empty entry for inode {}",
|
||||
n.id()));
|
||||
let first_path = paths.iter().next().unwrap_or_else(|| {
|
||||
panic!(
|
||||
"dso: you have a path map with an empty entry for inode {}",
|
||||
n.id()
|
||||
)
|
||||
});
|
||||
format!(
|
||||
"label = \"({}, {})\"",
|
||||
n.weight(),
|
||||
|
@ -285,10 +295,13 @@ impl State {
|
|||
}
|
||||
|
||||
fn determine_lib_search_paths(path: &Path, elf: &Elf<'_>) -> Result<Vec<String>> {
|
||||
log::trace!("elf.runpaths = {:#?}", elf.runpaths);
|
||||
log::trace!("elf.rpaths = {:#?}", elf.rpaths);
|
||||
|
||||
let mut search_paths = vec![];
|
||||
|
||||
let current_dir = std::env::current_dir()?;
|
||||
let origin = std::fs::canonicalize(path)?
|
||||
let origin = fs::canonicalize(path)?
|
||||
.parent()
|
||||
.unwrap()
|
||||
.strip_prefix(current_dir)?
|
||||
|
@ -297,34 +310,32 @@ fn determine_lib_search_paths(path: &Path, elf: &Elf<'_>) -> Result<Vec<String>>
|
|||
.into_string()
|
||||
.map_err(|s| anyhow::anyhow!("cannot represent {:?} as a UTF-8 string", s))?;
|
||||
|
||||
if elf.rpaths != vec![""] {
|
||||
if elf.runpaths != vec![""] {
|
||||
let mut rpaths = elf
|
||||
.rpaths
|
||||
.iter()
|
||||
.map(|p| p.replace("$ORIGIN", &origin))
|
||||
.collect::<Vec<_>>();
|
||||
search_paths.append(&mut rpaths);
|
||||
}
|
||||
|
||||
search_paths.append(&mut get_env_library_paths());
|
||||
if elf.runpaths.is_empty() {
|
||||
collect_paths(&elf.rpaths, &mut search_paths, &origin);
|
||||
}
|
||||
|
||||
if elf.runpaths != vec![""] {
|
||||
let mut runpaths = elf
|
||||
.runpaths
|
||||
.iter()
|
||||
.map(|p| p.replace("$ORIGIN", &origin))
|
||||
.collect::<Vec<_>>();
|
||||
search_paths.append(&mut runpaths);
|
||||
}
|
||||
search_paths.append(&mut get_env_library_paths());
|
||||
|
||||
search_paths.push("/usr/local/lib".into());
|
||||
search_paths.push("/lib".into());
|
||||
search_paths.push("/usr/lib".into());
|
||||
collect_paths(&elf.runpaths, &mut search_paths, &origin);
|
||||
|
||||
search_paths.push("usr/local/lib".into());
|
||||
search_paths.push("lib".into());
|
||||
search_paths.push("usr/lib".into());
|
||||
Ok(search_paths)
|
||||
}
|
||||
|
||||
fn collect_paths(elf_paths: &Vec<&str>, search_paths: &mut Vec<String>, origin: &str) {
|
||||
if elf_paths.iter().any(|p| !p.is_empty()) {
|
||||
let mut paths = elf_paths
|
||||
.iter()
|
||||
.flat_map(|p| p.split(':'))
|
||||
.map(|p| p.replace("$ORIGIN", origin))
|
||||
.map(|p| p.trim_start_matches('/').to_string())
|
||||
.collect::<Vec<_>>();
|
||||
search_paths.append(&mut paths);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_env_library_paths() -> Vec<String> {
|
||||
let ld_config_path = std::env::var("LD_LIBRARY_PATH");
|
||||
ld_config_path
|
||||
|
|
Loading…
Reference in a new issue