Repository navigation
Conversation
The operand tables behind GetOperands(), the IL operand classes and the untyped instruction accessors read several ops' operands from the wrong slots, or reported them under the wrong usage. MLIL's CopyTo also didn't handle phis, and HLIL's expression ordering threw on WHILE_SSA and ignored the operands of a few ops. Now each op's operands are read from the right slots, CopyTo copies phis, and expression ordering compares every operand.
… slice Rust architectures were never asked for the flags of comparisons, float operations or intrinsics. `LowLevelILFlagWriteOp` had no variants for them, so the callback logged a warning and used core's default flag IL instead. Each now has a variant. `Intrinsic` carries a parameter list, so the enum is no longer `Copy`. The callback also built its operand slice with `std::slice::from_raw_parts`, which is undefined behavior if it is ever passed null. It now uses `ffi::slice_from_raw_parts`, which returns an empty slice instead.
Rust's IL bindings read several ops' operands from the wrong slots, and decoded ASSERT and FORCE_VER as Undef. The LLIL visitor also missed some operands of intrinsics and the SSA calls. LLIL comparisons reported a size of 0, unlike the C++ and Python bindings. The rlc and rrc lifters took no carry, and the float conversion lifters lifted their source at the wrong width. Now each op decodes correctly, and ASSERT and FORCE_VER have their own variants. MLIL's unused NotYetImplemented and CallOutput variants are gone. Comparisons report their size like any other operation. rlc and rrc take a carry, so msp430 now passes its carry flag.
Python's IL bindings reported no operands for ASSERT and FORCE_VER, and the wrong variables as read or written for a handful of MLIL ops. ILOperations named some operands after their slots rather than their properties. LLIL also turned negative register-stack adjustments into -1, HLIL's ROR read a carry it doesn't have, and a few HLIL builders stored their operands in the wrong slots. Now each op reports its operands and variables correctly, and the builders store their operands in the right slots.
bdash
force-pushed
the
test_il_operand_fixes
branch
from
October 20, 2026 22:57
26b4495 to
bcdadc1
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Each binding had its own mistakes in how it reads IL operands. Some instruction operands were read from the wrong slots, a few ops reported missing or wrong operands and variables, and Rust decoded ASSERT and FORCE_VER as
Undef.The Rust changes break source compatibility in a few places.
rlcandrrcnow take a carry.RegStackFreeRegis now an instruction rather than an expression. MLIL'sCallOutputandNotYetImplementedvariants are gone, andLowLevelILFlagWriteOpis no longerCopy.See the individual commits for more details about the specific fixes.