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