Skip to content

arm: check SMLAD overflow on final result - #87

Open
DORA-B wants to merge 1 commit into
angr:masterfrom
DORA-B:fix/arm_smlad_qflag
Open

arm: check SMLAD overflow on final result#87
DORA-B wants to merge 1 commit into
angr:masterfrom
DORA-B:fix/arm_smlad_qflag

Conversation

@DORA-B

@DORA-B DORA-B commented Jul 28, 2026

Copy link
Copy Markdown

Summary

ARM SMLAD and SMLADX set the sticky Q flag when the complete signed sum of both halfword products and Ra does not fit in 32 bits. The current lifter checks overflow once after adding the products and again after adding Ra. This incorrectly sets Q when Ra cancels an intermediate overflow.

  full_result = signed_product_low + signed_product_high + signed(Ra)
  Rd = low32(full_result)
  if full_result != sign_extend_32(Rd):
  Therefore, overflow is tested once on the complete mathematical result.
VEX instead:
  1. Sets sticky Q if that intermediate value overflows.
  2. Adds Ra and checks overflow again.

Reproducer

With angr/pyvex 9.3.0:

import angr

for name, code in [("smlad", bytes.fromhex("113200e7")),
                   ("smladx", bytes.fromhex("313200e7"))]:
    project = angr.load_shellcode(code, arch="ARMEL", load_address=0x1000)
    state = project.factory.blank_state(addr=0x1000)
    state.regs.r1 = 0x80008000
    state.regs.r2 = 0x80008000
    state.regs.r3 = 0xffffffff
    state.regs.qflag32 = 0
    out = project.factory.successors(state, num_inst=1).flat_successors[0]
    print(name, hex(out.solver.eval(out.regs.r0)),
          out.solver.eval(out.regs.qflag32) & 1)

Current output:

smlad  0x7fffffff 1
smladx 0x7fffffff 1

Expected output:

smlad  0x7fffffff 0
smladx 0x7fffffff 0

Each signed halfword product is 0x40000000. Their intermediate sum is 0x80000000, but adding Ra = -1 produces the representable final result 0x7fffffff. ARM defines the overflow test over this complete three-term result.

Fix

Compute the complete signed sum in I64 and compare it with the sign extension of its low 32-bit result. Q is ORed only with that final representability check. The SMLSD/SMLSDX path retains its existing final addition check.

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