diff --git a/Cargo.lock b/Cargo.lock index 5396b98..309ed6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,6 +367,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "http" version = "0.2.6" @@ -739,6 +745,7 @@ dependencies = [ "ex", "flate2", "goblin", + "hex", "is_executable", "maplit", "reqwest", @@ -750,6 +757,7 @@ dependencies = [ "tempfile", "twoway", "umask", + "version-compare", "zstd", ] @@ -1209,6 +1217,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +[[package]] +name = "version-compare" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 9990760..f853881 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,8 @@ strfmt = "0.1.6" maplit = "1.0.2" flate2 = "1.0.22" zstd = "0.10.0" +version-compare = "0.1.0" +hex = "0.4.3" [dependencies.reqwest] version = "0.11.9" diff --git a/src/elf/build_id.rs b/src/elf/build_id.rs new file mode 100644 index 0000000..dee7934 --- /dev/null +++ b/src/elf/build_id.rs @@ -0,0 +1,22 @@ +use crate::elf; + +use std::path::Path; + +use ex::fs; +use snafu::ResultExt; + +/// Get the build id of the given elf file +pub fn get_build_id(path: &Path) -> elf::parse::Result { + let bytes = fs::read(path).context(elf::parse::ReadSnafu)?; + let elf = elf::parse(path, &bytes)?; + + let mut iter = elf + .iter_note_sections(&bytes, Some(".note.gnu.build-id")) + .unwrap(); + let section = iter + .next() + .unwrap() + .context(elf::parse::GoblinSnafu { path })?; + + Ok(hex::encode(section.desc)) +} diff --git a/src/elf/mod.rs b/src/elf/mod.rs index c37041c..fa23f57 100644 --- a/src/elf/mod.rs +++ b/src/elf/mod.rs @@ -1,6 +1,8 @@ +mod build_id; pub mod detect; mod has_debug_syms; pub mod parse; +pub use build_id::get_build_id; pub use has_debug_syms::has_debug_syms; pub use parse::parse; diff --git a/src/fetch_ld.rs b/src/fetch_ld.rs index 38f6760..07255de 100644 --- a/src/fetch_ld.rs +++ b/src/fetch_ld.rs @@ -1,9 +1,11 @@ +use crate::cpu_arch::CpuArch; use crate::libc_deb; use crate::libc_version::LibcVersion; use colored::Colorize; use snafu::ResultExt; use snafu::Snafu; +use version_compare::Cmp; #[derive(Debug, Snafu)] pub enum Error { @@ -22,7 +24,18 @@ pub fn fetch_ld(ver: &LibcVersion) -> Result { println!("{}", "fetching linker".green().bold()); let deb_file_name = format!("libc6_{}.deb", ver); - let ld_name = format!("ld-{}.so", ver.string_short); - libc_deb::write_ubuntu_pkg_file(&deb_file_name, &ld_name, &ld_name).context(DebSnafu)?; + + let ld_name = if version_compare::compare_to(&ver.string_short, "2.34", Cmp::Lt).unwrap() { + format!("ld-{}.so", ver.string_short) + } else { + match ver.arch { + CpuArch::I386 => "ld-linux.so.2", + CpuArch::Amd64 => "ld-linux-x86-64.so.2", + } + .to_string() + }; + let out_name = format!("ld-{}.so", ver.string_short); + + libc_deb::write_ubuntu_pkg_file(&deb_file_name, &ld_name, &out_name).context(DebSnafu)?; Ok(()) } diff --git a/src/solvepy.rs b/src/solvepy.rs index 1f2ef2e..8417380 100644 --- a/src/solvepy.rs +++ b/src/solvepy.rs @@ -50,7 +50,7 @@ fn make_bindings(opts: &Opts) -> String { &opts.template_bin_name, patch_bin::bin_patched_path(opts) .as_ref() - .or_else(|| opts.bin.as_ref()), + .or(opts.bin.as_ref()), ), bind_line(&opts.template_libc_name, opts.libc.as_ref()), bind_line(&opts.template_ld_name, opts.ld.as_ref()), diff --git a/src/unstrip_libc.rs b/src/unstrip_libc.rs index 9bead3f..486da78 100644 --- a/src/unstrip_libc.rs +++ b/src/unstrip_libc.rs @@ -16,6 +16,7 @@ use ex::io; use snafu::ResultExt; use snafu::Snafu; use tempfile::TempDir; +use version_compare::Cmp; #[derive(Debug, Snafu)] #[allow(clippy::enum_variant_names)] @@ -57,7 +58,12 @@ fn do_unstrip_libc(libc: &Path, ver: &LibcVersion) -> Result { let sym_path = tmp_dir.path().join("libc-syms"); - let name = format!("libc-{}.so", ver.string_short); + let name = if version_compare::compare_to(&ver.string_short, "2.23", Cmp::Lt).unwrap() { + format!("libc-{}.so", ver.string_short) + } else { + let build_id = elf::get_build_id(libc).context(ElfParseSnafu)?; + build_id.chars().skip(2).collect::() + ".debug" + }; libc_deb::write_ubuntu_pkg_file(&deb_file_name, &name, &sym_path).context(DebSnafu)?;