|
KittyMemoryEx 1.0.0
Dedicated library for runtime code patching, memory scanning, tracing, injection and some more useful memory utilities. works for both Android and Linux
|
Struct representing an ARM32 instruction. More...
#include <KittyAsm.hpp>
Public Member Functions | |
| bool | isValid () const |
| Checks if the instruction is valid. | |
| std::string | ToString () const |
| Renders the instruction as a single line of ARM32 assembly text. | |
Public Attributes | |
| EKittyInsnTypeArm32 | type |
| int | rd = -1 |
| int | rn = -1 |
| int | rt = -1 |
| uint32_t | word |
| The instruction word itself, as decoded. | |
| uint32_t | address |
| Where it lives, for PC-relative targets. | |
| int32_t | immediate |
| uint32_t | target |
| EKittyArmCond | cond = EKittyArmCond::None |
| bool | writeback |
| The instruction updates its base register (Rn) as a side effect. | |
| bool | postIndexed |
| The access happens at [Rn]; immediate is applied afterwards. | |
| bool | registerOffset |
| The offset is a register (held in rt), not immediate. | |
| bool | shiftedOperand |
| The second operand / offset register is a shifted register. | |
| bool | subtractsOffset |
| The register operand is subtracted rather than added. | |
| bool | registerForm |
| The second operand is a register (held in rt), not immediate. | |
| bool | pcRelative |
| Rn is PC, so the address is relative to this instruction. | |
Struct representing an ARM32 instruction.
This struct contains the details of an ARM32 instruction, including its type, registers, immediate value, target address, and condition.
| EKittyArmCond KittyInsnArm32::cond = EKittyArmCond::None |
Branch condition for B_COND, resolved on demand via branchCondName(); EKittyArmCond::None for every other type.
| bool KittyInsnArm32::pcRelative |
Rn is PC, so the address is relative to this instruction.
True for both the literal forms (LDR Rd,[PC,#imm], whose target is computed) and the register-offset form (LDR Rd,[PC,Rm], whose target depends on Rm and so cannot be). A consumer wanting the second form has to add its own PC bias - address + 8 in A32 - which is why this says which instructions need it rather than leaving callers to test Rn by name.
| bool KittyInsnArm32::postIndexed |
The access happens at [Rn]; immediate is applied afterwards.
Post-indexed forms encode their immediate as a write-back amount, not as an access offset, so a consumer must use 0 as the offset for these.
| int KittyInsnArm32::rd = -1 |
Register indices, always filled. -1 means the field is absent. Names are produced on demand via regName() rather than stored here, since nothing else claims the plain field names once no string counterpart exists to compete for them.
| bool KittyInsnArm32::registerForm |
The second operand is a register (held in rt), not immediate.
The data-processing counterpart of registerOffset. A32 selects between the two with one encoding bit, and which one is in play decides whether immediate or rt carries the operand - so a consumer that guesses by testing rt for -1 is relying on a convention rather than on what the instruction says.
| bool KittyInsnArm32::registerOffset |
The offset is a register (held in rt), not immediate.
Register-offset forms cannot be resolved from the instruction alone, so immediate is 0 and a consumer must not treat it as the access offset.
| bool KittyInsnArm32::shiftedOperand |
The second operand / offset register is a shifted register.
A32 encodes LSL/LSR/ASR/ROR as MOV with a non-zero shift field, so MOV Rd,Rm,ROR Rs decodes as type MOV while being a rotate rather than a copy. A consumer that treats this as a plain register move propagates a value the instruction never produced; the shift amount is often a runtime register, so the result is not knowable here at all. Set for the shifted register-offset load/store forms too - LDR Rd,[Rn,Rm,LSL #2] addresses Rn + (Rm << 2), which is not Rn + Rm.
| bool KittyInsnArm32::subtractsOffset |
The register operand is subtracted rather than added.
Two encodings hide this in a bit that is easy to miss, and both mean the result runs the opposite way from the obvious reading: load/store register offsets carry a U bit (LDR Rd,[Rn,-Rm]), and the ADR-shaped data-processing forms may be SUB rather than ADD (SUB Rd,PC,Rm). The immediate forms fold the sign into immediate and target already; this is how the register forms report it, since there is nothing to fold it into.
| bool KittyInsnArm32::writeback |
The instruction updates its base register (Rn) as a side effect.
True for the write-back load/store forms. A consumer that tracks register values must invalidate Rn when it sees this, or it carries on believing a base that the instruction has just moved.