Skip to content

Add Thumb IT lookback width fixture - #212

Open
zardus wants to merge 2 commits into
masterfrom
feature/thumb-it-lookback-fixture
Open

Add Thumb IT lookback width fixture#212
zardus wants to merge 2 commits into
masterfrom
feature/thumb-it-lookback-fixture

Conversation

@zardus

@zardus zardus commented Aug 28, 2026

Copy link
Copy Markdown
Member

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Problem

PyVEX's Thumb regressions need a real instruction stream that combines a mixed 16/32/16-bit ITTT group, a false 0xbf08 IT candidate inside LDREX, and the nine-halfword lookback edge. Binaries master has no tests/armel/thumb_it_lookback_widths.bin.

Root cause

The lookback decision depends on actual Thumb instruction widths and alignment. Synthetic bytes in the consumer test would bypass the workspace's real-fixture policy and would not prove a toolchain emits the sequence.

Fix

Add the 64-byte Cortex-M3 Thumb .text image, its complete MIT-licensed assembly source, and the Clang/LLD/LLVM objcopy 21.1.8 build recipe.

Testing

Exact-head readback confirms 64 bytes beginning f0b50028013000bf02bf401c15f4c03f and SHA-256 a49c1a151765f87446da09b98d6b11991f054a0a4ccb1d4ed2ea92694ad1f628. Two builds in separate fresh directories reproduced the source, object, ELF, and raw image byte-for-byte. Validation: #212 (comment)

session: sharpen

@zardus

zardus commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Validation record for head b16b950949fb7981634b0ff76372422c21b36456 against baseline a87538bc248531d2a1d22434143e8b9752459bac.

  • Exact PR shape: the own-merge-base/head scan verifies the added compiler-produced fixture and its load-bearing format/address shape: 64-byte raw Thumb fixture containing all four mixed-width IT lookback cases.
  • Provenance/reproduction: two fresh Clang 21.1.8 / LLD 21.1.8 / LLVM objcopy builds was rerun twice in separate fresh directories; both outputs byte-compare with each other and with the committed bytes.
  • Input/native identity: committed SHA-256 a49c1a151765f87446da09b98d6b11991f054a0a4ccb1d4ed2ea92694ad1f628; /proc/self/maps resolved pyvex/lib/libpyvex.so inside each isolated runtime on every arm: base SHA-256 4357c840876b955d15c2967a6bd8566bb03a19f07c1347cb3d157eed0f1156c6, head SHA-256 8950f2d7f75d84046913937d4f2458a269019b13ef6b8e55f643a42b083f574e.
  • Real consumer: Lifting: Handle mixed-width Thumb IT lookback pyvex#568 at baseline ab18a834ba4a5320c3415eff971092ef2b940779 / VEX 875f7c9a5f6be621b4f000c29c016e15ddf32207 and head 86716e788dc944bda3c0f7000096a15c1d7783ef / VEX 881703eda064a67a803cf51974c992286a8bdf4f loaded the committed fixture and produced the complete output linked in this PR's output record.
  • Repeat/order control: A/B/B/A, a static structural/native capture whose determinism is established by separate same-arm processes; same-arm output is byte-identical and the cross-arm delta is nonempty.
  • Local scope: this recapture validates fixture bytes, fixture shape, and the actual consumer path only. It does not claim a fresh full-workspace gate.
  • Hosted status: fresh hosted dependency validation for this exact binaries head has not been observed in this recapture; it remains pending and no hosted success is claimed here.

@zardus

zardus commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Exact fixture-shape and consumer-output record for #212.

  • Fixture comparison: own merge base a87538bc248531d2a1d22434143e8b9752459bac versus exact head b16b950949fb7981634b0ff76372422c21b36456. The target path/shape is absent on the merge base and present on the head. 64-byte raw Thumb fixture containing all four mixed-width IT lookback cases.
  • Fixture identity: SHA-256 a49c1a151765f87446da09b98d6b11991f054a0a4ccb1d4ed2ea92694ad1f628; source provenance: the adjacent complete assembly source at this exact binaries head. The complete readelf/objdump scan is retained with the exact script. The recorded recipe (two fresh Clang 21.1.8 / LLD 21.1.8 / LLVM objcopy builds) was rerun twice in fresh directories; both runs are byte-identical to the committed fixture.
  • Actual consumer: Lifting: Handle mixed-width Thumb IT lookback pyvex#568, exact baseline ab18a834ba4a5320c3415eff971092ef2b940779 / VEX 875f7c9a5f6be621b4f000c29c016e15ddf32207 versus exact head 86716e788dc944bda3c0f7000096a15c1d7783ef / VEX 881703eda064a67a803cf51974c992286a8bdf4f; target four exact IRSB lifts; configuration PyVEX opt-level 1 (plus recorded case controls).
  • Native identity: /proc/self/maps resolved pyvex/lib/libpyvex.so inside each isolated runtime on every arm: base SHA-256 4357c840876b955d15c2967a6bd8566bb03a19f07c1347cb3d157eed0f1156c6, head SHA-256 8950f2d7f75d84046913937d4f2458a269019b13ef6b8e55f643a42b083f574e.
  • Determinism: fresh A/B/B/A order, a static structural/native capture whose determinism is established by separate same-arm processes; each same-arm pair is byte-identical and every base/head comparison below is nonempty. Absolute checkout prefixes in tracebacks are normalized to <workspace> for publication; raw output is retained unchanged.

Before — four exact IRSB lifts

Exact consumer baseline
case=0x0,0x14,0x110c7,0x13,1
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I32 t7:Ity_I32 t8:Ity_I32 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I32 t13:Ity_I32 t14:Ity_I32 t15:Ity_I32 t16:Ity_I32 t17:Ity_I32 t18:Ity_I32 t19:Ity_I1 t20:Ity_I32 t21:Ity_I32 t22:Ity_I32 t23:Ity_I1 t24:Ity_I1 t25:Ity_I32 t26:Ity_I32 t27:Ity_I32 t28:Ity_I32 t29:Ity_I32 t30:Ity_I32 t31:Ity_I32 t32:Ity_I32 t33:Ity_I32 t34:Ity_I32 t35:Ity_I32

   00 | ------ IMark(0x110c6, 2, 1) ------
   01 | t0 = GET:I32(itstate)
   02 | t1 = Shr32(t0,0x08)
   03 | PUT(itstate) = t1
   04 | t12 = And32(t0,0x000000f0)
   05 | t11 = Xor32(t12,0x000000e0)
   06 | t13 = GET:I32(cc_op)
   07 | t10 = Or32(t13,t11)
   08 | t14 = GET:I32(cc_dep1)
   09 | t15 = GET:I32(cc_dep2)
   10 | t16 = GET:I32(cc_ndep)
   11 | t17 = armg_calculate_condition(t10,t14,t15,t16):Ity_I32
   12 | t19 = CmpNE32(t12,0x00000000)
   13 | t18 = ITE(t19,t17,0x00000001)
   14 | t24 = 32to1(t18)
   15 | t23 = Not1(t24)
   16 | if (t23) { PUT(r15t) = 0x110c9; Ijk_Boring }
   17 | t6 = GET:I32(r13)
   18 | t7 = And32(t6,0xfffffffc)
   19 | t8 = Add32(t6,0x00000014)
   20 | t25 = LDle:I32(t7)
   21 | PUT(r4) = t25
   22 | t28 = Add32(t7,0x00000004)
   23 | t27 = LDle:I32(t28)
   24 | PUT(r5) = t27
   25 | t30 = Add32(t7,0x00000008)
   26 | t29 = LDle:I32(t30)
   27 | PUT(r6) = t29
   28 | t32 = Add32(t7,0x0000000c)
   29 | t31 = LDle:I32(t32)
   30 | PUT(r7) = t31
   31 | t34 = Add32(t7,0x00000010)
   32 | t33 = LDle:I32(t34)
   33 | PUT(r13) = t8
   34 | PUT(itstate) = t1
   NEXT: PUT(r15t) = t33; Ijk_Ret
}
exit_count=1

case=0x12,0x2,0x110c7,0x1,1
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I32 t7:Ity_I32 t8:Ity_I32 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I32 t13:Ity_I32 t14:Ity_I32 t15:Ity_I32 t16:Ity_I32 t17:Ity_I32 t18:Ity_I32 t19:Ity_I1 t20:Ity_I32 t21:Ity_I32 t22:Ity_I32 t23:Ity_I1 t24:Ity_I1 t25:Ity_I32 t26:Ity_I32 t27:Ity_I32 t28:Ity_I32 t29:Ity_I32 t30:Ity_I32 t31:Ity_I32 t32:Ity_I32 t33:Ity_I32 t34:Ity_I32 t35:Ity_I32

   00 | ------ IMark(0x110c6, 2, 1) ------
   01 | t0 = GET:I32(itstate)
   02 | t1 = Shr32(t0,0x08)
   03 | PUT(itstate) = t1
   04 | t12 = And32(t0,0x000000f0)
   05 | t11 = Xor32(t12,0x000000e0)
   06 | t13 = GET:I32(cc_op)
   07 | t10 = Or32(t13,t11)
   08 | t14 = GET:I32(cc_dep1)
   09 | t15 = GET:I32(cc_dep2)
   10 | t16 = GET:I32(cc_ndep)
   11 | t17 = armg_calculate_condition(t10,t14,t15,t16):Ity_I32
   12 | t19 = CmpNE32(t12,0x00000000)
   13 | t18 = ITE(t19,t17,0x00000001)
   14 | t24 = 32to1(t18)
   15 | t23 = Not1(t24)
   16 | if (t23) { PUT(r15t) = 0x110c9; Ijk_Boring }
   17 | t6 = GET:I32(r13)
   18 | t7 = And32(t6,0xfffffffc)
   19 | t8 = Add32(t6,0x00000014)
   20 | t25 = LDle:I32(t7)
   21 | PUT(r4) = t25
   22 | t28 = Add32(t7,0x00000004)
   23 | t27 = LDle:I32(t28)
   24 | PUT(r5) = t27
   25 | t30 = Add32(t7,0x00000008)
   26 | t29 = LDle:I32(t30)
   27 | PUT(r6) = t29
   28 | t32 = Add32(t7,0x0000000c)
   29 | t31 = LDle:I32(t32)
   30 | PUT(r7) = t31
   31 | t34 = Add32(t7,0x00000010)
   32 | t33 = LDle:I32(t34)
   33 | PUT(r13) = t8
   34 | PUT(itstate) = t1
   NEXT: PUT(r15t) = t33; Ijk_Ret
}
exit_count=1

case=0x14,0x18,0x110db,0x13,1
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I32 t7:Ity_I32 t8:Ity_I32 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I32 t13:Ity_I32 t14:Ity_I32 t15:Ity_I32 t16:Ity_I32 t17:Ity_I32 t18:Ity_I32 t19:Ity_I1 t20:Ity_I32 t21:Ity_I32 t22:Ity_I32 t23:Ity_I1 t24:Ity_I1 t25:Ity_I32 t26:Ity_I32 t27:Ity_I32 t28:Ity_I32 t29:Ity_I32

   00 | ------ IMark(0x110da, 2, 1) ------
   01 | t0 = GET:I32(itstate)
   02 | t1 = Shr32(t0,0x08)
   03 | PUT(itstate) = t1
   04 | t12 = And32(t0,0x000000f0)
   05 | t11 = Xor32(t12,0x000000e0)
   06 | t13 = GET:I32(cc_op)
   07 | t10 = Or32(t13,t11)
   08 | t14 = GET:I32(cc_dep1)
   09 | t15 = GET:I32(cc_dep2)
   10 | t16 = GET:I32(cc_ndep)
   11 | t17 = armg_calculate_condition(t10,t14,t15,t16):Ity_I32
   12 | t19 = CmpNE32(t12,0x00000000)
   13 | t18 = ITE(t19,t17,0x00000001)
   14 | t24 = 32to1(t18)
   15 | t23 = Not1(t24)
   16 | if (t23) { PUT(r15t) = 0x110dd; Ijk_Boring }
   17 | t6 = GET:I32(r13)
   18 | t7 = And32(t6,0xfffffffc)
   19 | t8 = Add32(t6,0x00000008)
   20 | t25 = LDle:I32(t7)
   21 | PUT(r4) = t25
   22 | t28 = Add32(t7,0x00000004)
   23 | t27 = LDle:I32(t28)
   24 | PUT(r13) = t8
   25 | PUT(itstate) = t1
   NEXT: PUT(r15t) = t27; Ijk_Ret
}
exit_count=1

case=0x2c,0x14,0x110f3,0x13,1
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I1 t5:Ity_I1 t6:Ity_I1 t7:Ity_I32

   00 | ------ IMark(0x110f2, 2, 1) ------
   01 | PUT(itstate) = 0x00000000
   02 | t2 = GET:I32(r14)
   NEXT: PUT(r15t) = t2; Ijk_Ret
}
exit_count=0

After — four exact IRSB lifts

Exact consumer head
case=0x0,0x14,0x110c7,0x13,1
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I1 t7:Ity_I1 t8:Ity_I32 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I32 t13:Ity_I32 t14:Ity_I32 t15:Ity_I32 t16:Ity_I32 t17:Ity_I32 t18:Ity_I32

   00 | ------ IMark(0x110c6, 2, 1) ------
   01 | t2 = GET:I32(r13)
   02 | t3 = And32(t2,0xfffffffc)
   03 | t4 = Add32(t2,0x00000014)
   04 | t8 = LDle:I32(t3)
   05 | PUT(r4) = t8
   06 | t11 = Add32(t3,0x00000004)
   07 | t10 = LDle:I32(t11)
   08 | PUT(r5) = t10
   09 | t13 = Add32(t3,0x00000008)
   10 | t12 = LDle:I32(t13)
   11 | PUT(r6) = t12
   12 | t15 = Add32(t3,0x0000000c)
   13 | t14 = LDle:I32(t15)
   14 | PUT(r7) = t14
   15 | t17 = Add32(t3,0x00000010)
   16 | t16 = LDle:I32(t17)
   17 | PUT(r13) = t4
   18 | PUT(itstate) = 0x00000000
   NEXT: PUT(r15t) = t16; Ijk_Ret
}
exit_count=0

case=0x12,0x2,0x110c7,0x1,1
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I32 t7:Ity_I32 t8:Ity_I32 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I32 t13:Ity_I32 t14:Ity_I32 t15:Ity_I32 t16:Ity_I32 t17:Ity_I32 t18:Ity_I32 t19:Ity_I1 t20:Ity_I32 t21:Ity_I32 t22:Ity_I32 t23:Ity_I1 t24:Ity_I1 t25:Ity_I32 t26:Ity_I32 t27:Ity_I32 t28:Ity_I32 t29:Ity_I32 t30:Ity_I32 t31:Ity_I32 t32:Ity_I32 t33:Ity_I32 t34:Ity_I32 t35:Ity_I32

   00 | ------ IMark(0x110c6, 2, 1) ------
   01 | t0 = GET:I32(itstate)
   02 | t1 = Shr32(t0,0x08)
   03 | PUT(itstate) = t1
   04 | t12 = And32(t0,0x000000f0)
   05 | t11 = Xor32(t12,0x000000e0)
   06 | t13 = GET:I32(cc_op)
   07 | t10 = Or32(t13,t11)
   08 | t14 = GET:I32(cc_dep1)
   09 | t15 = GET:I32(cc_dep2)
   10 | t16 = GET:I32(cc_ndep)
   11 | t17 = armg_calculate_condition(t10,t14,t15,t16):Ity_I32
   12 | t19 = CmpNE32(t12,0x00000000)
   13 | t18 = ITE(t19,t17,0x00000001)
   14 | t24 = 32to1(t18)
   15 | t23 = Not1(t24)
   16 | if (t23) { PUT(r15t) = 0x110c9; Ijk_Boring }
   17 | t6 = GET:I32(r13)
   18 | t7 = And32(t6,0xfffffffc)
   19 | t8 = Add32(t6,0x00000014)
   20 | t25 = LDle:I32(t7)
   21 | PUT(r4) = t25
   22 | t28 = Add32(t7,0x00000004)
   23 | t27 = LDle:I32(t28)
   24 | PUT(r5) = t27
   25 | t30 = Add32(t7,0x00000008)
   26 | t29 = LDle:I32(t30)
   27 | PUT(r6) = t29
   28 | t32 = Add32(t7,0x0000000c)
   29 | t31 = LDle:I32(t32)
   30 | PUT(r7) = t31
   31 | t34 = Add32(t7,0x00000010)
   32 | t33 = LDle:I32(t34)
   33 | PUT(r13) = t8
   34 | PUT(itstate) = t1
   NEXT: PUT(r15t) = t33; Ijk_Ret
}
exit_count=1

case=0x14,0x18,0x110db,0x13,1
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I32 t7:Ity_I32 t8:Ity_I32 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I32 t13:Ity_I32 t14:Ity_I32 t15:Ity_I32 t16:Ity_I32 t17:Ity_I32 t18:Ity_I32 t19:Ity_I1 t20:Ity_I32 t21:Ity_I32 t22:Ity_I32 t23:Ity_I1 t24:Ity_I1 t25:Ity_I32 t26:Ity_I32 t27:Ity_I32 t28:Ity_I32 t29:Ity_I32

   00 | ------ IMark(0x110da, 2, 1) ------
   01 | t0 = GET:I32(itstate)
   02 | t1 = Shr32(t0,0x08)
   03 | PUT(itstate) = t1
   04 | t12 = And32(t0,0x000000f0)
   05 | t11 = Xor32(t12,0x000000e0)
   06 | t13 = GET:I32(cc_op)
   07 | t10 = Or32(t13,t11)
   08 | t14 = GET:I32(cc_dep1)
   09 | t15 = GET:I32(cc_dep2)
   10 | t16 = GET:I32(cc_ndep)
   11 | t17 = armg_calculate_condition(t10,t14,t15,t16):Ity_I32
   12 | t19 = CmpNE32(t12,0x00000000)
   13 | t18 = ITE(t19,t17,0x00000001)
   14 | t24 = 32to1(t18)
   15 | t23 = Not1(t24)
   16 | if (t23) { PUT(r15t) = 0x110dd; Ijk_Boring }
   17 | t6 = GET:I32(r13)
   18 | t7 = And32(t6,0xfffffffc)
   19 | t8 = Add32(t6,0x00000008)
   20 | t25 = LDle:I32(t7)
   21 | PUT(r4) = t25
   22 | t28 = Add32(t7,0x00000004)
   23 | t27 = LDle:I32(t28)
   24 | PUT(r13) = t8
   25 | PUT(itstate) = t1
   NEXT: PUT(r15t) = t27; Ijk_Ret
}
exit_count=1

case=0x2c,0x14,0x110f3,0x13,1
IRSB {
   t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I1 t5:Ity_I1 t6:Ity_I1 t7:Ity_I32

   00 | ------ IMark(0x110f2, 2, 1) ------
   01 | PUT(itstate) = 0x00000000
   02 | t2 = GET:I32(r14)
   NEXT: PUT(r15t) = t2; Ijk_Ret
}
exit_count=0

@zardus
zardus force-pushed the feature/thumb-it-lookback-fixture branch from b68d18e to b16b950 Compare August 28, 2026 16:49
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