Skip to content

feat: HLIL DetailedOperands/Operands/Traverse navigation (#13,#15)#41

Merged
tinysec merged 1 commit into
masterfrom
feat/hlil-navigation
Jul 9, 2026
Merged

feat: HLIL DetailedOperands/Operands/Traverse navigation (#13,#15)#41
tinysec merged 1 commit into
masterfrom
feat/hlil-navigation

Conversation

@tinysec

@tinysec tinysec commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Mirrors Python HighLevelILInstruction.detailed_operands / operands / traverse (highlevelil.py:795/786/802).

A static descriptor table (operation → named, typed operands) drives a kind-dispatched reader; Operands and Traverse<T> derive from it — the same foundation-first design as Python, where operands and traverse both build on detailed_operands.

Changes

  • HighLevelILOperand.cs: HighLevelILOperandKind enum + readonly HighLevelILOperand/HighLevelILOperandDescriptor structs.
  • HighLevelILDetailedOperandsTable.cs: 114-op descriptor table generated from the Python detailed_operands overrides, abstract bases expanded to every concrete op.
  • BNHighLevelILInstruction.cs: GetOperandAsInteger, virtual DetailedOperands, private ReadDetailedOperandByKind (SSA variable + constant data occupy two raw slots), Operands, generic Traverse<T> (DFS over operand tree; shallow blacklist {true,false,body,cases,default} matches Python).
  • HLILVariableDeclare.cs: expose the .Variable accessor (the one missing accessor).

Intentional divergence from Python — HLIL_ROR. Python HighLevelILRor inherits HighLevelILCarryBase, so its detailed_operands lists a third carry operand — but the core (highlevelilinstruction.cpp:189) defines HLIL_ROR with only {left, right}, so Python's Ror.carry reads a non-existent slot (garbage). This binding follows the core (OperationOperands[HLIL_ROR]=2, consistent with PR #26's removal of the bogus Carry accessor), so ROR has just {left, right}. RLC/RRC/ADC/SBB genuinely have a carry slot in the core and keep it.

Verification (harness repo, not this one) — 76/76 pass:

Closes parity gaps #13 (Operands) + #15 (Traverse) + the DetailedOperands foundation. #14 (Vars/VarsWritten/VarsRead/VarsAddressTaken) needs a focused follow-up: HighLevelILSSAVariable and HighLevelILVariable are separate sealed types with no common base, so the collection return type needs design.

Mirror Python HighLevelILInstruction.detailed_operands / operands / traverse
(highlevelil.py:795/786/802). A static descriptor table (operation -> named,
typed operands) drives a kind-dispatched reader; Operands and Traverse derive
from it, exactly as in Python.

- HighLevelILOperand: enum Kind + readonly Operand/Descriptor structs.
- HighLevelILDetailedOperandsTable: 114-op descriptor table generated from the
  Python detailed_operands overrides, abstract bases expanded to concrete ops.
- HighLevelILInstruction: GetOperandAsInteger, virtual DetailedOperands,
  ReadDetailedOperandByKind (SSA var + constant data occupy two raw slots),
  Operands, generic Traverse<T> (DFS, shallow blacklist matches Python).
- HLILVariableDeclare: expose the .Variable accessor (the one missing accessor).

Divergence from Python (intentional, documented in the table header): HLIL_ROR
omits the "carry" operand -- Python's HighLevelILRor inherits CarryBase but the
core (highlevelilinstruction.cpp:189) defines ROR with only {left,right}, so
Python's Ror.carry reads a non-existent slot. C# follows the core (OperationOperands
= 2, matching PR #26's removal of the bogus Carry accessor).

E2E (harness, not in this repo): DetailedOperands parity vs the Python spec for
ADD/STRUCT_FIELD/CONST(+PTR/FLOAT); Operands + Traverse; full cat.bndb sweep
no-throw; static consistency test reflecting over the table + OperationOperands
catches out-of-bounds indices (the ROR bug above was found + fixed by it).
76/76 pass.
@tinysec tinysec merged commit 72d9554 into master Jul 9, 2026
1 check passed
@tinysec tinysec deleted the feat/hlil-navigation branch July 9, 2026 04:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant