"""Saved O0 completeness pairs, with explicit runnable interface adaptations.""" import json from pathlib import Path import subprocess import tempfile import cle import yaml CASES = Path(__file__).with_name("cases") NAMES = ("faultless-my-putchar-count", "faultless-upper", "faultless-print-page-header") CASE_NAMES = ("my_putchar_count", "upper", "print_page_header") LABELS = ("Faultless: One-byte write", "Faultless: Uppercase loop", "Faultless: Static page counter") def source(name, filename): return (CASES / CASE_NAMES[NAMES.index(name)] / filename).read_text() def metadata(name): info = json.loads(source(name, "metadata.json")) info.update(reference=source(name, "original.c"), expected_verdict="inconclusive" if name == NAMES[0] else "agree") return info def prepare_examples(directory): output = Path(directory).resolve() output.mkdir(parents=True, exist_ok=True) rows = [] with tempfile.TemporaryDirectory(prefix="faultless-completeness-") as temporary: temporary = Path(temporary) for name in NAMES: case = CASES / CASE_NAMES[NAMES.index(name)] info = json.loads((case / "runnable.json").read_text()) original = temporary / "original.c" original.write_text(info["declarations"] + source(name, "original.c")) stubs = temporary / "callees.c" stubs.write_text(info["stubs"]) binary = output / (name + ".elf") flags = ["-O0", "-fno-builtin"] subprocess.run(["gcc", *flags, "-fno-pie", "-no-pie", "-fno-stack-protector", "-nostdlib", "-Wl,--build-id=none", "-Wl,-e," + info["original_symbol"], str(original), str(stubs), "-o", str(binary)], check=True, capture_output=True, text=True, timeout=60) obj = cle.Loader(str(binary), auto_load_libs=False).main_object addresses = {symbol.name: symbol.rebased_addr for symbol in obj.symbols if not symbol.is_import} bindings = {kind: {candidate: addresses[original] for candidate, original in info.get(kind, {}).items()} for kind in ("callees", "globals")} rows.append([str(binary), f"{addresses[info['original_symbol']]:#x}", (case / "candidate.c").read_text(), yaml.safe_dump(bindings, sort_keys=True), info["candidate_symbol"], 100, "0", 1000, "gcc", " ".join(flags), yaml.safe_dump(info["interfaces"], sort_keys=True)]) return rows