Tighten Type 9 BO validation and fix Type 32a discriminator

Type 9 Constant-YOP:
  Only accept BO=01 and BO=11 as valid constant encodings.
  BO=00 or BO=10 now fall through to unk instead of producing
  plausible-looking but invalid disassembly.

Type 32a:
  - DAG_REG field is 4 bits (was 3), using bits7-4 not bits6-4.
  - Add strict bit checks: bit15=0, bits12-11=11, bit10=0.
    (was: only checking bit11=1, matching too broadly)
  - Prevents overlap with Type 32 (bit11=0) encodings.
This commit is contained in:
Dr. Christian Giessen
2026-04-22 20:08:33 +00:00
parent ae98262bb7
commit ff56cb099f
2 changed files with 30 additions and 16 deletions

View File

@@ -219,24 +219,31 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
} }
/* Constant YOP form: YY=bits12-11, CC=bits7-6, BO=bits5-4. /* Constant YOP form: YY=bits12-11, CC=bits7-6, BO=bits5-4.
Only BO=01 and BO=11 are valid encodings.
Index = (YY<<2)|CC. BO=01: val = 1<<idx (idx<15) Index = (YY<<2)|CC. BO=01: val = 1<<idx (idx<15)
or -32768 (idx=15). BO=11: val = -(1<<idx)-1 or -32768 (idx=15). BO=11: val = -(1<<idx)-1
or +32767 (idx=15). */ or +32767 (idx=15). */
{ {
ut32 yy = (ins >> 11) & 0x3;
ut32 cc = (ins >> 6) & 0x3;
ut32 bo = (ins >> 4) & 0x3; ut32 bo = (ins >> 4) & 0x3;
ut32 idx = (yy << 2) | cc; if (bo == 1 || bo == 3)
int32_t val; {
if (idx == 15) ut32 yy = (ins >> 11) & 0x3;
val = (bo & 0x2) ? 32767 : -32768; ut32 cc_bits = (ins >> 6) & 0x3;
else if (bo & 0x2) ut32 idx = (yy << 2) | cc_bits;
val = -((int32_t)(1 << idx)) - 1; int32_t val;
else if (idx == 15)
val = (int32_t)(1 << idx); val = (bo == 3) ? 32767 : -32768;
op->mnemonic = r_str_newf ("%s%s%s%s = %s(%s, %d)", else if (bo == 3)
cp, cs, sp, dst, f, x, val); val = -((int32_t)(1 << idx)) - 1;
return true; else
val = (int32_t)(1 << idx);
op->mnemonic = r_str_newf (
"%s%s%s%s = %s(%s, %d)",
cp, cs, sp, dst, f, x, val);
return true;
}
/* BO=00 or BO=10 with non-zero lower bits:
not a valid Type 9 encoding, fall through. */
} }
} }
@@ -710,13 +717,20 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
return true; return true;
} }
/* Type 32a: DAG reg store + transfer (bits 23-17=0001010, bit11=1) */ /* Type 32a: DAG reg store + register transfer.
if ((ins >> 17) == 0x0A && ((ins >> 11) & 1)) bits23-17=0001010, bit15=0, bits12-11=11, bit10=0.
U=bit14, G=bit13, RGP=bits9-8, DAG_REG=bits7-4,
I=bits3-2, M=bits1-0.
Syntax: DM(Ireg1 op Mreg1) = DAGreg, DAGreg = Ireg1 */
if ((ins >> 17) == 0x0A
&& !((ins >> 15) & 1)
&& ((ins >> 11) & 0x3) == 0x3
&& !((ins >> 10) & 1))
{ {
ut32 u_bit = (ins >> 14) & 1; ut32 u_bit = (ins >> 14) & 1;
ut32 g = (ins >> 13) & 1; ut32 g = (ins >> 13) & 1;
ut32 rgp = (ins >> 8) & 0x3; ut32 rgp = (ins >> 8) & 0x3;
ut32 dag_reg = (ins >> 4) & 0x7; ut32 dag_reg = (ins >> 4) & 0xF;
ut32 ireg = (ins >> 2) & 0x3; ut32 ireg = (ins >> 2) & 0x3;
ut32 mreg = ins & 0x3; ut32 mreg = ins & 0x3;
int base = g ? 4 : 0; int base = g ? 4 : 0;

Binary file not shown.