You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using objdiff-wasm, parsing the same .o file first as 'base' (for a one-sided diff) and then as 'target' (for a two-sided diff) causes the second comparison to return incorrect results.
Specifically, it reports a perfect match (0 differences) when there are actually significant differences between the two files.
Versions
objdiff-wasm: 3.6.1
Node.js: v22
Reproduction
The fixtures are MIPS big-endian ELF .o files.
The target.o has dual OBJECT+FUNC symbols for the same address.
Pre-parsing target.o as "base" (one-sided diff)...
Done.
Comparing current.o (base) vs target.o (target)...
Matching: 40
Different: 0
⚠ No differences reported — but the .o files contain different code!
What the repro script does
Without --preparse: Parses current.o as 'base' and target.o as 'target', runs a two-sided diff, and counts matching vs. differing instruction rows for symbol func_800B3F64_1E1014. Correctly reports 22 matching / 20 different.
With --preparse: First parses target.o as 'base' and runs a one-sided diff (i.e., runDiff(base, undefined, ...)). Then does the same two-sided comparison as above. This time it incorrectly reports 40 matching / 0 different.
The only difference between the two runs is the extra Object.parse() + runDiff() call on target.o before the real comparison. This suggests that WASM module state from the first parse leaks into the second.
Context
I discovered this while working on Mizuchi, a plugin-based pipeline runner.
One plugin was parsing the target .o to extract assembly (one-sided diff as 'base'), and later another plugin ran the actual two-sided comparison. The prior parse caused the comparison to always report a perfect match, masking real code differences.
I noticed later that it happens on Kappa too, when using the command Compare a symbol from two object files. It runs the pre-parsing to list the symbols before the actual diff.
Summary
When using
objdiff-wasm, parsing the same.ofile first as'base'(for a one-sided diff) and then as'target'(for a two-sided diff) causes the second comparison to return incorrect results.Specifically, it reports a perfect match (0 differences) when there are actually significant differences between the two files.
Versions
objdiff-wasm: 3.6.1Reproduction
The fixtures are MIPS big-endian ELF
.ofiles.The
target.ohas dual OBJECT+FUNC symbols for the same address.Without pre-parse (correct):
With pre-parse (bug):
What the repro script does
Without
--preparse: Parsescurrent.oas'base'andtarget.oas'target', runs a two-sided diff, and counts matching vs. differing instruction rows for symbolfunc_800B3F64_1E1014. Correctly reports 22 matching / 20 different.With
--preparse: First parsestarget.oas'base'and runs a one-sided diff (i.e.,runDiff(base, undefined, ...)). Then does the same two-sided comparison as above. This time it incorrectly reports 40 matching / 0 different.The only difference between the two runs is the extra
Object.parse()+runDiff()call ontarget.obefore the real comparison. This suggests that WASM module state from the first parse leaks into the second.Context
I discovered this while working on Mizuchi, a plugin-based pipeline runner.
One plugin was parsing the target
.oto extract assembly (one-sided diff as'base'), and later another plugin ran the actual two-sided comparison. The prior parse caused the comparison to always report a perfect match, masking real code differences.I noticed later that it happens on Kappa too, when using the command
Compare a symbol from two object files. It runs the pre-parsing to list the symbols before the actual diff.output.mp4