Skip to content

Add a big-endian SuperH fixture for the p-code converter tests - #225

Open
zardus wants to merge 1 commit into
masterfrom
feature/sh2-big-endian-fixture
Open

Add a big-endian SuperH fixture for the p-code converter tests#225
zardus wants to merge 1 commit into
masterfrom
feature/sh2-big-endian-fixture

Conversation

@zardus

@zardus zardus commented Sep 6, 2026

Copy link
Copy Markdown
Member

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Problem

angr's p-code AIL converter reads part of a wide unique varnode, and which end
of the wide value that sub-range names depends on the byte order. Nothing here
can assert that. Scanning every ELF under tests/ at this branch's merge base
for a big-endian file whose e_machine is EM_SH:

003e82a2bfa641530924055695b36cec8af483ab: 762 ELF objects under tests/, 0 big-endian SuperH

The one SuperH object here, tests/sh4/test-instr_sh4, is little-endian.

Root cause

SuperH is the only architecture in reach whose SLEIGH model reads a unique at the
parent's own address with a smaller size: mac.l and dmulu.l both do. Six of
the big-endian objects here -- ppc/libc.so.6, ppc64/libc.so.6,
mips/libc.so.6, mips/busybox, mips64/libc.so.6 and
m68k/mul_add_sub_xor_m68k_be, 1,690,970 instructions between them -- produce no
such read at all.

Fix

tests/sh4/hello_32x_sh2be is the Sega 32X hello-world skeleton from
marsdev, built from examples/32x-skeleton
at 3318d3f.
It is MIT-licensed, and tests/sh4/LICENSE.md carries the license text and the
provenance beside it. angr loads it through pypcode as SuperH4:BE:32:default;
90 of its 313 blocks reach the converter path.

23b72052f61c6d991e426c5033bbc50d77c90d0b: 763 ELF objects under tests/, 1 big-endian SuperH
    tests/sh4/hello_32x_sh2be

Testing

This repository has no suite of its own. The fixture is exercised by the angr
change that needs it, whose tests/ailment/test_converter_pcode.py fails against
angr master on this file and passes with that change applied; the before and
after are in the comment below.

Validation: #225 (comment)

session: sharpen

The Sega 32X hello-world skeleton from marsdev, built from examples/32x-skeleton
at 3318d3f39823154b24ce48bfa5d8fe6e3f6cde3f. It is MIT-licensed;
tests/sh4/LICENSE.md carries the license text and the provenance.

angr's p-code AIL converter reads part of a wide unique varnode, and which half
of the value the varnode's own address holds depends on the byte order. No
big-endian object here can show that: over about 1.69M instructions of ppc,
ppc64, mips, mips64 and m68k code, SLEIGH never reads a unique at the parent's
own address with a smaller size. SuperH's mac.l and dmulu.l both do, and 90
blocks of this object reach it.
@zardus

zardus commented Sep 6, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Validation record for head 23b72052f61c6d991e426c5033bbc50d77c90d0b against baseline 003e82a2bfa641530924055695b36cec8af483ab.

  • Shape scan: git ls-tree -r <rev> tests/, reading the first 20 bytes of every blob — baseline 762 ELF objects under tests/, 0 with EI_DATA == ELFDATA2MSB and e_machine == EM_SH; head 763 and 1
  • Survey behind the Root cause figure: each object's executable sections translated one instruction at a time under its own SLEIGH language, looking for a read of a unique at an offset a previous op wrote, at a smaller size — ppc/libc.so.6 302,766 instructions, ppc64/libc.so.6 302,532, mips/libc.so.6 310,933, mips/busybox 350,856, mips64/libc.so.6 305,896, m68k/mul_add_sub_xor_m68k_be 117,987 under 68000:BE:32:default; 1,690,970 in total, 0 such reads
  • Committed artifact, read back: ELF32, 2's complement, big endian, Type: EXEC, Machine: Renesas / SuperH SH, Flags: 0x2, sh2, entry 0x2000000, 10,416 bytes, sha256 7758d275028974aedc5c11e2aab280fac7d4ebffc19b5ca2644f2fffd6dadec5
  • Provenance: built from examples/32x-skeleton of https://github.com/andwn/marsdev at 3318d3f39823154b24ce48bfa5d8fe6e3f6cde3f, MIT. Checked anonymously on 2026-09-06: GET /repos/andwn/marsdev returns 200 with private: false and license.spdx_id: MIT, the response carries x-ratelimit-limit: 60 so the call was unauthenticated, the commit resolves, and examples/32x-skeleton is in its tree at that revision. The binary carries SEGA 32X, HELLO WORLD and GCC: (GNU) 13.1.0 and no build path, user name or host name.
  • Build recipe: not rerun; no SuperH cross toolchain was available here. This is the recorded origin of these bytes, not a claim that a command reproduces them.
  • Consumer: angr loads it as SuperH4:BE:32:default; CFGFast recovers 313 blocks, of which 90 reach the p-code converter's partial-unique-read path
  • Lint/type: not applicable, no source added

Caveats: this repository has no test suite, so the fixture's evidence is the shape scan and the consumer load rather than a suite result.

@zardus

zardus commented Sep 6, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

The whole AIL block converted from mac.l @r0+, @r0+ at 0x200079a in
tests/sh4/hello_32x_sh2be, before and after the angr change this fixture
exists for. reg2048 is MACH and reg2052 is MACL.

Before — angr master reads MACL from a tmp no statement defines, and gives MACH the product's low half unshifted. Two stacked changes separate the two blocks: angr/angr#6934 repairs the first line, the change on top of it repairs the second.

angr master 87411a719c96ddc3f3954590b1833b1789e19697
200079a  mac.l   @r0+, @r0+
    t0 = Load(addr=reg0<32>, size=4, endness=Iend_BE)
    t1 = Conv(32->64, t0)
    t2 = Load(addr=reg0<32>, size=4, endness=Iend_BE)
    t3 = Conv(32->64, t2)
    t4 = Conv(32->64, reg2052<32>)
    t5 = Conv(32->64, reg2048<32>)
    t6 = (t5 Shl 32<32>)
    t7 = (t4 Add t6)
    t8 = (t1 Mul t3)
    t9 = Conv(1->8, (reg1543<8> CmpEQ 0<8>))
    if ((t9 CmpNE 0<8>)) { Goto 3<32> } else { Goto 2<32> }
    t10 = (t7 Add t8)
    reg2052<32> = Conv(64->32, t123392)
    reg2048<32> = t10
    reg0<32> = (reg0<32> Add 4<32>)
    reg0<32> = (reg0<32> Add 4<32>)

After — MACL is the low half and MACH is the high half:

with the angr change applied
200079a  mac.l   @r0+, @r0+
    t0 = Load(addr=reg0<32>, size=4, endness=Iend_BE)
    t1 = Conv(32->64, t0)
    t2 = Load(addr=reg0<32>, size=4, endness=Iend_BE)
    t3 = Conv(32->64, t2)
    t4 = Conv(32->64, reg2052<32>)
    t5 = Conv(32->64, reg2048<32>)
    t6 = (t5 Shl 32<32>)
    t7 = (t4 Add t6)
    t8 = (t1 Mul t3)
    t9 = Conv(1->8, (reg1543<8> CmpEQ 0<8>))
    if ((t9 CmpNE 0<8>)) { Goto 3<32> } else { Goto 2<32> }
    t10 = (t7 Add t8)
    reg2052<32> = Conv(64->32, t10)
    reg2048<32> = Conv(64->32, (t10 Shr 32<8>))
    reg0<32> = (reg0<32> Add 4<32>)
    reg0<32> = (reg0<32> Add 4<32>)

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