use std::path::PathBuf;
use std::process::Command;
use object::{Object, ObjectSection};
fn synth() -> &'static str {
env!("CARGO_BIN_EXE_synth")
}
fn bss_size(path: &str) -> u64 {
let data = std::fs::read(path).expect("read .o");
let obj = object::File::parse(&*data).expect("parse ELF");
obj.sections()
.find(|s| s.name() == Ok(".bss"))
.expect(".bss section present")
.size()
}
fn fixture() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("scripts/repro/gust_kernel.wasm")
}
fn compile(extra: &[&str], out: &str) -> std::process::Output {
let fx = fixture();
let mut args = vec![
"compile",
fx.to_str().unwrap(),
"--target",
"cortex-m3",
"--native-pointer-abi",
"--all-exports",
"--relocatable",
"-o",
out,
];
args.extend_from_slice(extra);
Command::new(synth())
.args(&args)
.output()
.expect("run synth")
}
#[test]
fn shadow_stack_size_shrinks_gust_reservation_383() {
let out = compile(&["--shadow-stack-size", "4096"], "/tmp/gust_shrink_383.o");
assert!(
out.status.success(),
"compile failed: {}",
String::from_utf8_lossy(&out.stderr)
);
assert_eq!(
bss_size("/tmp/gust_shrink_383.o"),
4240,
"reservation should shrink to B + static-tail"
);
}
#[test]
fn no_flag_leaves_reservation_full_383() {
let out = compile(&[], "/tmp/gust_noshrink_383.o");
assert!(out.status.success());
assert_eq!(
bss_size("/tmp/gust_noshrink_383.o"),
1048720,
"no flag must leave the full reservation"
);
}
#[test]
fn budget_above_sp_init_refused_383() {
let out = compile(&["--shadow-stack-size", "2000000"], "/tmp/gust_bad_383.o");
assert!(
!out.status.success(),
"budget > sp_init must be refused, not accepted"
);
let log = String::from_utf8_lossy(&out.stderr);
assert!(
log.contains("exceeds the declared shadow-stack top"),
"expected honest refuse message; got:\n{log}"
);
}