diff --git a/Handle/BNBasicBlock.cs b/Handle/BNBasicBlock.cs index 97a8ce4..2c27eb3 100644 --- a/Handle/BNBasicBlock.cs +++ b/Handle/BNBasicBlock.cs @@ -802,9 +802,10 @@ ref length break; } - // Carry the instruction's start address on the line, mirroring Python's - // Function.instructions / BinaryView.instructions which yield (tokens, addr). - yield return new InstructionTextLine(tokens, address); + // Carry the instruction's start address and decoded byte length on the line, + // mirroring Python's Function.instructions / BinaryView.instructions (yield + // (tokens, addr)) and BasicBlock.__getitem__ (yield (tokens, size)). + yield return new InstructionTextLine(tokens, address, length); address += length; } diff --git a/Struct/BNInstructionTextLine.cs b/Struct/BNInstructionTextLine.cs index f959e6f..2585247 100644 --- a/Struct/BNInstructionTextLine.cs +++ b/Struct/BNInstructionTextLine.cs @@ -30,6 +30,14 @@ public sealed class InstructionTextLine // line was not produced by an address-walking generator (e.g. synthesized token lists). public ulong Address { get; } = 0; + // The byte length of the instruction this line disassembles. Python's + // BasicBlock.__getitem__ (basicblock.py:210) yields (tokens, size) per instruction, so the + // size is as much a part of an instruction's identity as its address. It is 0 when the line + // was not produced by an address-walking generator (e.g. synthesized token lists); a block's + // last instruction has no successor, so its size cannot otherwise be recovered from + // consecutive addresses. + public ulong ByteSize { get; } = 0; + public InstructionTextLine() { @@ -46,6 +54,13 @@ public InstructionTextLine(InstructionTextToken[] tokens, ulong address) this.Address = address; } + public InstructionTextLine(InstructionTextToken[] tokens, ulong address, ulong byteSize) + { + this.Tokens = tokens; + this.Address = address; + this.ByteSize = byteSize; + } + public override string ToString() { StringBuilder builder = new StringBuilder();