Releases: loov/ixdiff
Release list
v0.2.0
ixdiff can now compare binaries on nearly every architecture Go targets.
Seven new architectures
This release adds instruction-level diffing for 386, arm (32-bit), riscv64, ppc64/ppc64le, s390x, loong64, and wasm — joining the existing amd64 and arm64 support. Each one gets full operand normalization, so address shifts between builds are masked out and only real code changes show up in the diff. 386, arm, riscv64, and loong64 also get the relocation-only fast path, which classifies most layout-shift noise without disassembling at all.
The one holdout is mips: there is no pure-Go disassembler for it yet (golang/go#19158 tracks adding one to x/arch). Follow #9 if you need it.
Sharper diffs
- The amd64 fast path now verifies rip-relative references against the symbol table, so a
deferor function value retargeted to a different function is reported as a real change instead of being mistaken for relocation noise. --mask-spnow knows each architecture's stack pointer (R1on ppc64,R15on s390x, and friends), and--blockssplits blocks correctly everywhere — including wasm.
Sturdier loaders
The ELF, Mach-O, PE, and wasm loaders now reject malformed and hostile inputs gracefully instead of hanging or panicking, and concurrent disassembly no longer races inside the x/arch decoders. The test suite grew accordingly: every architecture runs through the full pipeline, and a property-based harness cross-checks the fast path against full analysis on real cross-compiled binaries.
Binaries below are for linux, macOS, and windows on amd64/arm64 — or go install github.com/loov/ixdiff@v0.2.0.
v0.1.0
ixdiff compares the assembly of two binaries to show how the generated
code differs: which functions changed, by how much, and what the
instruction-level differences are.
First release.
Highlights
- Summary report: function counts, text size delta, opcode histogram,
per-package rollup, and top-N tables (--top,--sort,--filter). - Per-function assembly diffs (
--fn, repeatable, substring matching
with suggestions), unified or two-column (--side-by-side), with
hunks, address columns, and changed-operand emphasis on terminals. - Relocation-aware: functions whose bytes differ only because code or
data moved are counted separately and excluded from statistics; on
amd64 and arm64 most are classified without disassembly, so large
binaries compare in well under a second per 100MB. - Normalization keeps diffs meaningful: call targets symbolized,
branch labels alignment-derived, address-valued operands masked,
renamed functions re-paired. Real immediates, registers, and stack
offsets still diff (--mask-spto ignore frame-size shifts). --blocksmatches basic blocks first, tolerating block reordering
(e.g. PGO builds).--jsonfor machine-readable reports.
Pure Go (debug/elf, debug/macho, debug/pe, golang.org/x/arch),
no objdump needed. ELF, Mach-O, and PE on amd64 and arm64; Go binaries
get exact function ranges from the pclntab even when stripped.
Install
go install github.com/loov/ixdiff@v0.1.0or use the attached prebuilt binaries for linux, macOS, and Windows.