use std::collections::HashMap;
use std::path::Path;
use std::process::Command;
use object::read::elf::ElfFile32;
use object::{Object, ObjectSection};
const GOLDEN_OFF_TEXT_FNV1A: u64 = 0xa68a_a2da_e5af_e4a7;
const GOLDEN_OFF_TEXT_LEN: usize = 576;
fn synth() -> &'static str {
env!("CARGO_BIN_EXE_synth")
}
fn fixture() -> std::path::PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("scripts/repro/const_cse.wat")
}
fn compile(out: &str, cse: bool) -> Vec<u8> {
let mut cmd = Command::new(synth());
if cse {
cmd.env("SYNTH_CONST_CSE", "1");
}
let status = cmd
.args([
"compile",
fixture().to_str().unwrap(),
"-o",
out,
"-b",
"arm",
"--target",
"cortex-m4",
"--all-exports",
])
.status()
.expect("run synth compile");
assert!(status.success(), "synth compile failed (cse={cse})");
std::fs::read(out).expect("read ELF")
}
fn sections(elf: &[u8]) -> HashMap<String, Vec<u8>> {
let obj = ElfFile32::<object::Endianness>::parse(elf).expect("parse ELF");
let mut out = HashMap::new();
for sec in obj.sections() {
if let Ok(name) = sec.name()
&& !name.is_empty()
{
out.insert(name.to_string(), sec.data().unwrap_or(&[]).to_vec());
}
}
out
}
fn func_text_len(elf: &[u8], name: &str) -> usize {
use object::ObjectSymbol;
let obj = ElfFile32::<object::Endianness>::parse(elf).expect("parse ELF");
for sym in obj.symbols() {
if sym.name() == Ok(name) {
return sym.size() as usize;
}
}
panic!("symbol {name} not found");
}
fn fnv1a64(bytes: &[u8]) -> u64 {
let mut h: u64 = 0xcbf2_9ce4_8422_2325;
for &b in bytes {
h ^= b as u64;
h = h.wrapping_mul(0x0000_0100_0000_01b3);
}
h
}
#[test]
fn const_cse_off_matches_frozen_baseline_242() {
let off = compile("/tmp/const_cse_off.elf", false);
let text = sections(&off).remove(".text").expect(".text present");
assert_eq!(
text.len(),
GOLDEN_OFF_TEXT_LEN,
"flag-off .text length drifted from the frozen baseline"
);
assert_eq!(
fnv1a64(&text),
GOLDEN_OFF_TEXT_FNV1A,
"flag-off optimized-path .text drifted from the pre-const-CSE baseline \
— the default-off path is supposed to be byte-identical; re-bless the \
golden ONLY if this was an intentional optimized-path lowering change"
);
}
#[test]
fn const_cse_on_shrinks_headroom_function_242() {
let off = compile("/tmp/const_cse_red_off.elf", false);
let on = compile("/tmp/const_cse_red_on.elf", true);
let off_len = func_text_len(&off, "large3");
let on_len = func_text_len(&on, "large3");
assert!(
on_len < off_len,
"const-CSE must shrink large3 on headroom: off={off_len}B on={on_len}B"
);
assert!(
off_len - on_len >= 8,
"expected ≥8B saved (≥1 movw+movt pair), got {}B",
off_len - on_len
);
}