Source-linked AI summary
Recompilation Is Not Enough: Test-Guided Decompiled-C Repair
Yuhan Huang, Puzhuo Liu, Jianlei Chi
TL;DR
Recompiled decompiled C can still diverge from a utility’s command-line behavior, so recompilation alone is insufficient evidence of recovery. The paper uses compiler feedback for build repair and test-gate feedback for semantic repair; 91 of 104 evaluated Coreutils 9.5 binaries recompile and pass the gate. The evaluation is limited to one utility family, related official tests, and a primary static-enriched track.
Problem
A recompiled command-line binary may still parse options differently, print different bytes, or return different exit statuses, leaving behavioral recovery beyond recompilation as the gap.
Source: §1 · p. 1Method
Results
91 of 104 Coreutils 9.5 binaries (87.5%) in the static-enriched evaluation recompile and pass the test gate.
Source: §1 · p. 1Takeaways & Limitations
The preliminary result supports a bounded repair discipline in which binaries that fail recompilation or the test gate are not accepted on smoke checks alone.
Source: §5 · p. 4The evaluation covers one utility family, related official tests rather than full equivalence, and one primary static-enriched track.
Source: §5 · p. 4
Abstract
from arXiv · showhide
Decompiled C often becomes recompilable only after repair, but recompilation alone does not establish test-observed behavior. A recompiled command-line binary can still parse options incorrectly, print different bytes, or return a different exit status. We present a few-step workflow for repairing decompiled C using compiler feedback and related official tests. Compiler and linker diagnostics first guide build repair. Once the repaired C recompiles into a binary, smoke checks and related official tests expose behavioral discrepancies for semantic repair. In a preliminary static-enriched evaluation on 104 Coreutils 9.5 binaries with available decompiler exports and deterministic exact-output smoke comparisons, 91 binaries (87.5%) recompile and pass the test gate; 9 do not recompile within the repair budget, and 4 recompile but still fail the test gate. The result suggests that test-gate feedback can make LLM-assisted repair of decompiled C more auditable than compile-only recovery.
1 Introduction
Recompilation does not ensure that a complete command-line binary reproduces the original utility’s behavior. The paper proposes a bounded, test-guided repair workflow and reports preliminary results on Coreutils 9.5 binaries.
1 Introduction
- A complete binary can recompile yet still parse options differently, print different bytes, or return different exit statuses.The repair target includes more than individual functions: option tables, static data, global state, helper-library behavior, output formatting, and exit-status conventions.Source: §1 · p. 1
- The workflow treats recompilation as an intermediate step and uses compiler/linker diagnostics for build repair, then related official tests and smoke checks for semantic repair.Related official tests are assigned before repair and exercise expected command-line behavior; Coreutils source code is not used as repair input.Source: §1 · p. 1
- The paper contributes a few-step, binary-granularity workflow and a test-gate feedback loop that guides semantic repair beyond recompilation.The workflow accepts a binary only when the repaired C recompiles and the resulting binary passes related official tests and smoke checks.Source: §1 · p. 1
- 91 of 104 binaries (87.5%) recompile and pass the test gate in the preliminary static-enriched evaluation.The evaluation covers Coreutils 9.5 binaries with available decompiler exports and deterministic exact-output smoke comparisons; 9 fail to recompile within the repair budget, and 4 recompile but fail the gate.Source: §1 · p. 1
2 Motivation
Compiler and linker feedback can establish that repaired C produces a binary, but not that its command-line behavior matches the original. Related official tests provide behavioral evidence beyond shallow smoke checks.
2 Motivation
- Compiler diagnostics identify build faults but rarely explain why an option combination should produce a particular byte sequence or exit status.Smoke checks are useful sanity checks, while related official tests can expose boundary cases and option interactions.Source: §2 · p. 1
- Compiler errors often point to local syntactic defects, whereas behavioral failures can reflect cross-function invariants such as malformed option tables, incorrect helpers, or mislaid static data.Treating failures as staged evidence helps distinguish recurring decompiler artifacts from cases needing semantic edits.Source: §2 · pp. 1–2
- Related official tests can exercise long-option aliases, diagnostic formatting, ordering rules, and error exits that a single hand-written smoke command may miss.They are not proof of equivalence, but offer a stronger behavioral check than recompilation and a more reusable target than utility-specific manual scripts.Source: §2 · p. 2
- A recompiled binary passed smoke checks but only 2 of 5 related official tests in the cut case, exposing output, exit-status, and help/version discrepancies.The case illustrates behavioral evidence that compile/link diagnostics and smoke checks did not capture.Source: §2 · p. 2, Figure 1 · p. 2
3 Approach
The approach separates build repair from semantic repair, using diagnostics for compilation failures and behavioral discrepancies after recompilation. Its bounded test-feedback loop uses compact discrepancy summaries and records explicit outcomes.
3 Approach
- The workflow accepts either a passing recompiled binary or an explicit failure label, with optional sanitized static metadata rather than Coreutils source snippets or complete expected-output files.Metadata may include recovered symbols, constants, and data-layout hints.Source: §3 · p. 2
- Two feedback loops separate compiler/linker diagnostics for build repair from smoke-test and related-official-test behavior differences for semantic repair.Semantic edits are rebuilt; any resulting compile or link errors join the feedback for that semantic attempt, and failures retain a stage label.Source: §3 · p. 2
- Deterministic preprocessing handles recurring source-independent artifacts, then LLM build repair uses compiler and linker diagnostics if the C still does not compile or link.The narrow rules cover declarations and headers, intrinsic helpers, ABI and prototype cleanup, recovered global data, and minimal C/POSIX shims; diagnostic extensions are recorded as repair effort.Source: §3 · p. 2
- Preprocessing rules are limited to recurring decompiler artifacts and must be justified independently of a particular test outcome.This keeps the repair layer reusable and reduces the risk of hidden benchmark-specific solutions.Source: §3 · p. 2
- The test gate requires recompilation plus both smoke checks and related official tests, which can expose boundary ranges, option interactions, formatting, and error-path behavior.Generated repairs are also audited against known test-specific branch patterns and hard-coded answer patterns.Source: §3 · p. 2
- Semantic repair summarizes failing tests, output or exit-status mismatches, timeouts, and smoke results; deterministic fixes address recurring defect classes before remaining cases reach LLM repair.After three semantic iterations, binaries that still fail the gate count as failures. Compact summaries omit complete logs and expected outputs, retaining short discrepancy fragments while aiming to preserve already passing behavior.Source: §3 · pp. 2–3
4 Evaluation
The evaluation repairs and accounts for whole Coreutils binaries under a bounded budget, accepting only recompiled binaries that pass the test gate. It reports success and failure stages, a cut-case repair trace, and aggregate token use.
4.1 Setup
- The evaluation used the whole binary as its unit and accepted it only after recompilation, linking, and passing related official tests plus smoke checks.Repair used static-enriched sidecars, with a primary three-iteration build target and a three-iteration semantic cap.Source: §4.1 · p. 3
4.2 Effectiveness
- 91 of 104 binaries (87.5%) recompiled and passed the test gate; 9 failed to recompile and 4 recompiled but failed the gate.Table 1 presents the final outcome taxonomy under bounded repair.Source: Table 1 · p. 3, §4.2 · p. 3
- The outcome taxonomy separates build failures from recompiled binaries whose observable behavior still diverges under the test gate.The 9 build failures include unresolved integration problems such as declarations, recovered data, linkage, or helper behavior.Source: §4.2 · p. 3
- In the cut case, smoke checks passed, but related official tests exposed a behavior gap that two semantic-repair iterations then closed without smoke regression.The discrepancy summary captured observable mismatches, and repair checks audited against known test-specific shortcuts.Source: §4.2 · p. 3
- The cut-case tests covered range parsing, read/write error paths, and help/version handling—behavioral categories compiler diagnostics could not explain.The recompiled binary had enough structure to run, while the discrepancy summary exposed behavioral categories.Source: §4.2 · pp. 3–4
4.3 Efficiency
- Across 104 binaries, repair traces recorded 6.87M tokens across successes, build failures, diagnostic extensions, and test-gate failures.The token total profiles prototype repair effort, not model-independent runtime efficiency.Source: §4.3 · p. 4
5 Discussion
The preliminary results support a bounded repair discipline, not a final decompilation benchmark. The evaluation remains limited in scope and does not establish full behavioral equivalence or portability beyond Coreutils-style binaries.
5 Discussion
- The bounded accounting keeps build failures and test-gate failures explicit rather than accepting binaries on recompilation or smoke checks alone.It limits how far unbounded retry or manual steering can obscure the source of progress.Source: §5 · p. 4
- The evaluation covers one utility family, related official tests rather than full equivalence, and one primary static-enriched track.Exact-output smoke checks favor deterministic command-line behavior, and portability beyond Coreutils-style binaries remains open.Source: §5 · p. 4
- Related official tests remain a subset of full behavioral equivalence, and static metadata may make repair easier than a pseudo-only setting.Transfer to libraries, servers, or interactive programs would require different behavioral tests and externally observable contracts.Source: §5 · p. 4
6 Related Work
Related work advances decompilation generation, refinement, and evaluation, but does not by itself define acceptance of a repaired whole binary. This paper applies test feedback to that binary-level setting.
6 Related Work
- Recent decompilation systems improve recovered function quality through assembly-language modeling, larger benchmarks, separated structure and identifier recovery, pseudocode repair, and symbol recovery.Examples include Nova and Decompile-Bench [17], SK2Decompile [15], PseudoFix, LLM4Decompile and SLaDe [1] [16], and ReSym, SymGen, and GenNm.Source: §6 · p. 4
- Decompiler-output refinement uses recompilation, correction, retrieval-augmented repair, or readability optimization, but these systems do not evaluate whole-binary repair driven by related official tests plus smoke checks.The binary-level setting must reconstruct cross-function and global behavior rather than assume function-level context.Source: §6 · p. 4
- Prior work separates readability, recompilability, and functionality [10], while repair research uses test and runtime evidence to guide edits [2] [13] [22].This paper applies that feedback principle to decompiled C at binary granularity, using related official tests as both repair evidence and an endpoint.Source: §6 · p. 4
7 Conclusion
The paper concludes that recompilation alone is insufficient for repairing decompiled C: compiler/linker diagnostics guide build repair, while test-gate feedback guides semantic repair. Its preliminary bounded evaluation reports 91 passing binaries among 104 Coreutils 9.5 binaries, with repair traces and explicit failure reasons.
7 Conclusion
- 91 of 104 Coreutils 9.5 binaries recompiled and passed the test gate in the static-enriched track.The result is bounded repair evidence rather than a proof of equivalence; accepted binaries have recorded traces, and failures retain stopping reasons.Source: §7 · p. 4