Skip to content

Add ARM BE8 and BE32 fixtures - #202

Open
zardus wants to merge 2 commits into
masterfrom
be8/fixtures
Open

Add ARM BE8 and BE32 fixtures#202
zardus wants to merge 2 commits into
masterfrom
be8/fixtures

Conversation

@zardus

@zardus zardus commented Aug 26, 2026

Copy link
Copy Markdown
Member

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Problem

angr/binaries has no big-endian ARM ELF at all, so nothing exercises either big-endian ARM layout. Searching every ELF under tests/:

searched 735 ELF objects under tests/ for: big-endian (ELFDATA2MSB) EM_ARM object
0 match

BE8 — big-endian data with little-endian instructions, introduced in ARMv6 and marked by EF_ARM_BE8 in e_flags — is the half that cannot be inferred from the header a loader already reads, since a BE8 and a BE32 image differ in that flag and in nothing else about class, machine or data encoding. Without a pair that differs only there, a consumer cannot be shown to read the flag rather than guess.

Root cause

Neither layout falls out of a normal cross build for this repository: it takes a big-endian ARM target, and BE8 additionally takes a linker flag.

Fix

Add tests/armeb/be8_loop and tests/armeb/be32_loop, 1000 bytes each. They come from one compiled object linked twice with the same toolchain, differing only by --be8:

    tests/armeb/be32_loop  --  e_flags=0x05000400, EF_ARM_BE8 clear
    tests/armeb/be8_loop   --  e_flags=0x05800400, EF_ARM_BE8 set

Their .text sections are 64 bytes each and are exact four-byte reversals of one another, so the pair isolates the flag and nothing else. Source and the build recipe are in tests_src/armeb.

Testing

Both headers were read back out of the committed files with pyelftools and cross-checked against readelf -h and readelf -x .text; the reversal was checked word by word. The sha256s are in the validation record. This repository has no suite of its own; the consumer is the archinfo and cle work that reads EF_ARM_BE8, which today loads both as <Arch ARMHF (BE)> with identical map ranges.

Validation: #202 (comment)

session: sharpen

@zardus

zardus commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Validation record for head 082add3484d585d3c4d9fdf8e2bae4daae06ffe7.

  • tests/armeb/be8_loop — 1000 bytes, sha256 01b5be1529f49866e0eb93dd958e18f058f6376767910ca1cee5c2f0fb1c570a; e_flags 0x05800400, so EF_ARM_BE8 (0x00800000) is set
  • tests/armeb/be32_loop — 1000 bytes, sha256 da3cee80dc618f2ae11a22e10a6bd1b10af996af2d8e194916319bf184a43e2b; e_flags 0x05000400, EF_ARM_BE8 clear
  • Both are ELFCLASS32, big-endian (MSB), EM_ARM. Their .text sections are 64 bytes each, and reversing be8_loop's .text four bytes at a time yields be32_loop's .text exactly; checked with pyelftools and cross-checked against readelf -x .text
  • Consumer behaviour today: cle.Loader(path, auto_load_libs=False) on cle b58ea02a446106647cdaae32bdf91b7062404cc1 loads both as <Arch ARMHF (BE)> with identical map ranges — the BE8 flag is not read anywhere, which is what the archinfo and cle halves of this work change

Caveats: this repository has no test suite, so the record is header and section verification of the committed artifacts plus the load above. The build script was not rerun here, so byte reproducibility from tests_src/armeb is not shown.

Re-keyed 2026-08-28. The figures above were measured at 776754f5be7e2ca69ef9af5ebe31f372dbd14f92 on baseline 8646be4eafa4f1fc285d787fb2b73426a5e11d19, which is the head the opening line named until now; the branch is at 082add3484d585d3c4d9fdf8e2bae4daae06ffe7 on de38bc3dbd052f7f9d2442cda0e43eee8e4263a8. git range-diff 8646be4eafa4f1fc285d787fb2b73426a5e11d19..776754f5be7e2ca69ef9af5ebe31f372dbd14f92 de38bc3dbd052f7f9d2442cda0e43eee8e4263a8..082add3484d585d3c4d9fdf8e2bae4daae06ffe7 reports every commit unchanged and git diff 776754f5be7e2ca69ef9af5ebe31f372dbd14f92 082add3484d585d3c4d9fdf8e2bae4daae06ffe7 differs only by master's own advance (4 files changed, 42 insertions(+)). Master touched none of the files this change touches, and both images are the same blobs before and after the move — be8_loop 69067cbc, be32_loop 8d1eeecd — so the header and section readings above are readings of exactly these bytes.

@zardus

zardus commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Searching every ELF object under tests/ for a big-endian EM_ARM object, before and after this change.

Before — this repository has no big-endian ARM ELF at all, so nothing exercises BE8 or BE32:

angr/binaries at the merge base
angr/binaries at baseline de38bc3
searched 735 ELF objects under tests/ for: big-endian (ELFDATA2MSB) EM_ARM object
0 match

After — one BE8 and one BE32 object, built from the same object file and differing only in EF_ARM_BE8:

with this change
angr/binaries at head 082add3
searched 737 ELF objects under tests/ for: big-endian (ELFDATA2MSB) EM_ARM object
2 match
    tests/armeb/be32_loop  --  e_flags=0x05000400, EF_ARM_BE8 clear
    tests/armeb/be8_loop  --  e_flags=0x05800400, EF_ARM_BE8 set

zardus added a commit to angr/cle that referenced this pull request Aug 29, 2026
The first version of this branch passed instruction_endness= to ArchARMEL,
ArchARMHF and ArchARM on every ARM path, and pinned archinfo to the branch that
added the keyword. archinfo#374 is closed, so against archinfo master that call
is a TypeError, and it fires on every ARM ELF carrying either float-ABI bit
rather than only on BE8 images: 44 of the 70 ARM objects in angr/binaries raise
it, which is what turned every ARM test in angr and angrop red.

Ghidra already ships ARM:LEBE:32:v7LEInstruction, declared endian="big"
instructionEndian="little", and its own ARM ELF opinion selects it on
EF_ARM_BE8, so the split needs no archinfo change: EF_ARM_BE8 returns an
ArchPcode for that language and every other ARM path is restored to master.
Over the 70 ARM ELF objects in angr/binaries plus the two fixtures in
angr/binaries#202, the architecture cle picks now changes for exactly one file,
be8_loop, where 0x2010c decodes as cmp r0,#0x1; movlt r0,#0x0 against master's
smlatteq r0, r3, r0, r5.

Two consequences are worth naming. ALL_RELOCATIONS is keyed on arch.name, so the
language id joins it beside the sparc entry that set the precedent; without that
a BE8 shared object would lose every relocation. And angr's CFG recovery over a
p-code ARM language needs archinfo#376: is_arm_arch is a prefix test on the
name, so it answers True for ARM:LEBE and CFGFast then reads an ARM-only option
that a p-code architecture does not carry. With that predicate fixed, CFGFast
recovers _start and compute from be8_loop.

pypcode is optional in cle, so an installation without it keeps master's
big-endian ARM answer and logs that it did.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The repository has no big-endian ARM ELF at all. These are a matched pair built
from one object file, differing only in whether the linker was given --be8, so a
test can tell the two layouts apart: their .text sections are byte-for-byte
reversals of each other, and e_flags differs only in EF_ARM_BE8. Freestanding,
1000 bytes each; the source, the build line and the digests are in
tests_src/armeb.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
zardus added a commit to angr/cle that referenced this pull request Aug 30, 2026
The first version of this branch passed instruction_endness= to ArchARMEL,
ArchARMHF and ArchARM on every ARM path, and pinned archinfo to the branch that
added the keyword. archinfo#374 is closed, so against archinfo master that call
is a TypeError, and it fires on every ARM ELF carrying either float-ABI bit
rather than only on BE8 images: 44 of the 70 ARM objects in angr/binaries raise
it, which is what turned every ARM test in angr and angrop red.

Ghidra already ships ARM:LEBE:32:v7LEInstruction, declared endian="big"
instructionEndian="little", and its own ARM ELF opinion selects it on
EF_ARM_BE8, so the split needs no archinfo change: EF_ARM_BE8 returns an
ArchPcode for that language and every other ARM path is restored to master.
Over the 70 ARM ELF objects in angr/binaries plus the two fixtures in
angr/binaries#202, the architecture cle picks now changes for exactly one file,
be8_loop, where 0x2010c decodes as cmp r0,#0x1; movlt r0,#0x0 against master's
smlatteq r0, r3, r0, r5.

Two consequences are worth naming. ALL_RELOCATIONS is keyed on arch.name, so the
language id joins it beside the sparc entry that set the precedent; without that
a BE8 shared object would lose every relocation. And angr's CFG recovery over a
p-code ARM language needs archinfo#376: is_arm_arch is a prefix test on the
name, so it answers True for ARM:LEBE and CFGFast then reads an ARM-only option
that a p-code architecture does not carry. With that predicate fixed, CFGFast
recovers _start and compute from be8_loop.

pypcode is optional in cle, so an installation without it keeps master's
big-endian ARM answer and logs that it did.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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