Skip to main content

Module arm_encoding

Module arm_encoding 

Source
Expand description

Byte-level rewrites for ARM conditional branches.

Both AArch64 and AArch32 (ARM mode) are fixed 4-byte instruction encodings, so the v0 rewrite strategy mirrors x86 nop_jcc / replace_jcc_with_jmp:

  • Always-false branch → replace the 4-byte conditional instruction with a 4-byte architectural NOP.
  • Always-true branch → assemble an unconditional b <target> over the same 4 bytes.

Mnemonic coverage (planner-side, classified by plan::classify_mnemonic):

  • AArch64: b.<cond> and the compare-and-branch family cbz / cbnz / tbz / tbnz.
  • AArch32 (ARM mode): b<cond> for the standard condition suffixes (eq/ne/cs/hs/cc/lo/mi/pl/vs/vc/ hi/ls/ge/lt/gt/le). Unconditional b, link forms bl/blx, and indirect bx are excluded.

Encoding references:

  • AArch64 NOP: D503201F (ARM ARM Vol. C §C6.2.182). Little- endian byte layout: 1F 20 03 D5.
  • AArch32 NOP (ARMv6T2+): E320F000 (ARM ARM Vol. C §A8.8.119). Little-endian byte layout: 00 F0 20 E3.

Both NOP forms are architectural hint instructions, not the historical mov rN, rN idiom — they are explicitly recognised as NOPs by the CPU’s instruction decoder and have zero side effects on flags or registers.

Thumb-mode AArch32 (2-byte / 4-byte mixed encoding) is out of scope for this rewrite; callers must reject Thumb mnemonics upstream. The slicer / planner currently classifies b<cond> purely on the textual mnemonic and does not yet attempt to detect Thumb vs ARM mode, so any caller invoking the planner against a Thumb function should expect the resulting plan to be byte- incorrect — fixing that is a follow-up gated on Thumb mode detection in the slicer / r2pipe adapter.

Constants§

ARM_INSTRUCTION_BYTES
Length, in bytes, of any AArch64 or AArch32 (ARM-mode) instruction.
THUMB_HALFWORD_BYTES
Length, in bytes, of a Thumb 16-bit instruction half-word.
THUMB_NOP_LE
Thumb NOP encoding (BF00, little-endian). ARMv6T2 introduced this as a proper hint instruction; older Thumb encodings fell back to MOV r8, r8 which still functions as a NOP but is harder to recognise.

Functions§

arm_nop_buffer
Fill len bytes with the architectural NOP encoding for arch.
arm_nop_bytes
Return the architectural NOP encoding for arch.
thumb_nop_buffer
Fill len bytes with the Thumb 16-bit NOP hint.