Getting the address of a varnode (aka instruction operand)
See original GitHub issue(rephrased to better match sleigh terminology)
I’m working on a processor description for VAX and would need to get the address of an instruction operand.
VAX has one-byte opcodes followed by operands with variable (1 to 5 bytes) length.
Examples (not exact mnemonics)
- one-byte opcode, two one-byte operands
00000000: 90 01 50 - MOVE.B S^1, R0
- one-byte opcode, one two-byte operand, one four-byte operand
00000000: 90 CF 34 12 E0 78 56 34 12 - MOVE.B (PC+0x1234), (R0 + 0x12345678)
Example 2 is the problem. The first operand (“CF 34 12”) is PC-relative, it computes PC+0x1234, where PC is right after the final “12” value. In the example above, that would result in 0x1238.
Problem
To compute PC-relative offsets correctly, I need to know the operands memory address. However, neither inst_start
, nor inst_next
are usable here:
-
I can’t use
inst_start
because the operand might be second and I don’t know the size of the first operand. -
I can’t use
inst_next
because the operand might be first and I don’t know the size of the second operand.
Are there any other options ?
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:11 (1 by maintainers)
Solved this with a non-visible operand
Works nicely, as the
op_addr
value gets reset when I add..; op_code; ..
to the bit pattern section.However, when computing operands, every operand gets the final
op_addr
value (after all operands are parsed) instead of the value at the respective operand position.I’ve solved it now by introducing an
operand_offset
variable.(Adding _printf_s to Ghidra pointed me to the right places, esp. showing that ParserWalker’s value retrieval functions where called twice - once reading 4-byte-value to match against the disassembler spec and once reading correctly-sized values to compute the correct disassembly values)
See https://github.com/NationalSecurityAgency/ghidra/commit/f9a87889c24cfb6f677493cfdbe2685e302fe2f5 for the
C++
part and https://github.com/NationalSecurityAgency/ghidra/commit/ecc24c7c9e73ee4f448b277bdbe15898cfab5de4 for theJava
part.operand_offset
is modeled likeinst_start
but with a differentgetValue()
implementation:inst_start has
operand_offset has
This works nicely and fixes the issue at hand.