/// Cross-check the in-house ELF read against binutils on whatever binaries this /// machine happens to have. Not a unit test of the parser (those live beside it); /// a differential against the tool everyone else would have used. #[test] fn compare_against_readelf() { // Skip where binutils is not installed rather than failing: this is a // differential, and with nothing to differ against there is nothing to say. if std::process::Command::new("readelf") .arg("--version") .output() .is_err() { eprintln!("no readelf on this machine; skipping the differential"); return; } let mut checked = 0; let candidates: Vec = std::fs::read_dir("/usr/bin") .into_iter() .flatten() .flatten() .map(|e| e.path().to_string_lossy().into_owned()) .take(400) .collect(); for p in candidates { let Ok(bytes) = std::fs::read(&p) else { continue; }; if bytes.len() < 64 || &bytes[..4] != b"\x7fELF" { continue; } let mine = sando_daemon::elf::glibc_floor(&bytes).map(|v| v.to_string()); let Ok(out) = std::process::Command::new("readelf") .args(["-V", &p]) .output() else { continue; }; if !out.status.success() { continue; } let s = String::from_utf8_lossy(&out.stdout); // Only the version-requirement section; readelf -V also prints defined // versions, which are not what a floor is made of. let req = match s.split_once("Version needs section") { Some((_, rest)) => rest, None => "", }; let mut best: Option<(u32, u32)> = None; for tok in req.split(|c: char| !(c.is_alphanumeric() || c == '.' || c == '_')) { if let Some(v) = tok.strip_prefix("GLIBC_") && let Some((a, b)) = v.split_once('.') && let (Ok(a), Ok(b)) = (a.parse::(), b.parse::()) { best = Some(best.map_or((a, b), |x| x.max((a, b)))); } } let theirs = best.map(|(a, b)| format!("{a}.{b}")); assert_eq!(mine, theirs, "disagreed on {p}"); checked += 1; } println!("agreed with readelf on {checked} binaries"); assert!( checked > 20, "only {checked} binaries compared; too few to mean anything" ); }